From nnorwitz at gmail.com Tue Dec 1 00:42:51 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 30 Nov 2009 18:42:51 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (2) Message-ID: <20091130234251.GA10285@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_distutils leaked [0, 0, 25] references, sum=25 test_zipimport_support leaked [0, 0, -25] references, sum=-25 Less important issues: ---------------------- test_cmd_line leaked [-25, 0, 0] references, sum=-25 test_popen2 leaked [4, -29, 25] references, sum=0 From solipsis at pitrou.net Tue Dec 1 00:48:45 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 1 Dec 2009 00:48:45 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76609): sum=45 Message-ID: <20091130234845.7300F17720@ns6635.ovh.net> py3k results for svn r76609 (hg cset 66849d804d3c) -------------------------------------------------- test_urllib leaked [10, 2, 4] references, sum=16 test_zipimport_support leaked [29, 0, 0] references, sum=29 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogtJ_ZG2', '-x', 'test_httpservers'] From python-checkins at python.org Tue Dec 1 06:57:26 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 05:57:26 -0000 Subject: [Python-checkins] r76611 - tracker/instances/meta/schema.py Message-ID: Author: martin.v.loewis Date: Tue Dec 1 06:57:26 2009 New Revision: 76611 Log: r4238: Add Register permission. Modified: tracker/instances/meta/schema.py Modified: tracker/instances/meta/schema.py ============================================================================== --- tracker/instances/meta/schema.py (original) +++ tracker/instances/meta/schema.py Tue Dec 1 06:57:26 2009 @@ -47,6 +47,8 @@ roles=String(), # comma-separated string of Role names timezone=String()) user.setkey("username") +db.security.addPermission(name='Register', klass='user', + description='User is allowed to register new user') # FileClass automatically gets this property in addition to the Class ones: # content = String() [saved to disk in /db/files/] @@ -162,7 +164,7 @@ # Assign the appropriate permissions to the anonymous user's Anonymous # Role. Choices here are: # - Allow anonymous users to register -db.security.addPermissionToRole('Anonymous', 'Create', 'user') +db.security.addPermissionToRole('Anonymous', 'Register', 'user') # Allow anonymous users access to view issues (and the related, linked # information) From python-checkins at python.org Tue Dec 1 07:02:46 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:02:46 -0000 Subject: [Python-checkins] r76612 - tracker/instances/python-dev/schema.py Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:02:46 2009 New Revision: 76612 Log: r4238: Add Register permission. Modified: tracker/instances/python-dev/schema.py Modified: tracker/instances/python-dev/schema.py ============================================================================== --- tracker/instances/python-dev/schema.py (original) +++ tracker/instances/python-dev/schema.py Tue Dec 1 07:02:46 2009 @@ -97,6 +97,8 @@ contrib_form=Boolean(), contrib_form_date=Date()) user.setkey("username") +db.security.addPermission(name='Register', klass='user', + description='User is allowed to register new user') # FileClass automatically gets this property in addition to the Class ones: # content = String() [saved to disk in /db/files/] @@ -349,7 +351,7 @@ # Assign the appropriate permissions to the anonymous user's Anonymous # Role. Choices here are: # - Allow anonymous users to register -db.security.addPermissionToRole('Anonymous', 'Create', 'user') +db.security.addPermissionToRole('Anonymous', 'Register', 'user') # Allow anonymous users access to view issues (and the related, linked # information). From python-checkins at python.org Tue Dec 1 07:03:11 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:03:11 -0000 Subject: [Python-checkins] r76613 - tracker/instances/jython/schema.py Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:03:11 2009 New Revision: 76613 Log: r4238: Add Register permission. Modified: tracker/instances/jython/schema.py Modified: tracker/instances/jython/schema.py ============================================================================== --- tracker/instances/jython/schema.py (original) +++ tracker/instances/jython/schema.py Tue Dec 1 07:03:11 2009 @@ -86,6 +86,8 @@ roles=String(), # comma-separated string of Role names timezone=String()) user.setkey("username") +db.security.addPermission(name='Register', klass='user', + description='User is allowed to register new user') # FileClass automatically gets this property in addition to the Class ones: # content = String() [saved to disk in /db/files/] @@ -322,7 +324,7 @@ # Assign the appropriate permissions to the anonymous user's Anonymous # Role. Choices here are: # - Allow anonymous users to register -db.security.addPermissionToRole('Anonymous', 'Create', 'user') +db.security.addPermissionToRole('Anonymous', 'Register', 'user') # Allow anonymous users access to view issues (and the related, linked # information). From python-checkins at python.org Tue Dec 1 07:04:04 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:04:04 -0000 Subject: [Python-checkins] r76614 - tracker/instances/jobs/schema.py Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:04:04 2009 New Revision: 76614 Log: r4238: Add Register permission. Modified: tracker/instances/jobs/schema.py Modified: tracker/instances/jobs/schema.py ============================================================================== --- tracker/instances/jobs/schema.py (original) +++ tracker/instances/jobs/schema.py Tue Dec 1 07:04:04 2009 @@ -37,6 +37,8 @@ roles=String(), # comma-separated string of Role names timezone=String()) user.setkey("username") +db.security.addPermission(name='Register', klass='user', + description='User is allowed to register new user') # FileClass automatically gets this property in addition to the Class ones: # content = String() [saved to disk in /db/files/] @@ -292,7 +294,7 @@ # Assign the appropriate permissions to the anonymous user's Anonymous # Role. Choices here are: # - Allow anonymous users to register -db.security.addPermissionToRole('Anonymous', 'Create', 'user') +db.security.addPermissionToRole('Anonymous', 'Register', 'user') # Allow anonymous users access to view offers (and the related, linked # information). From python-checkins at python.org Tue Dec 1 07:05:05 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:05:05 -0000 Subject: [Python-checkins] r76615 - tracker/instances/setuptools/schema.py Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:05:04 2009 New Revision: 76615 Log: r4238: Add Register permission. Modified: tracker/instances/setuptools/schema.py Modified: tracker/instances/setuptools/schema.py ============================================================================== --- tracker/instances/setuptools/schema.py (original) +++ tracker/instances/setuptools/schema.py Tue Dec 1 07:05:04 2009 @@ -47,6 +47,8 @@ roles=String(), # comma-separated string of Role names timezone=String()) user.setkey("username") +db.security.addPermission(name='Register', klass='user', + description='User is allowed to register new user') # FileClass automatically gets this property in addition to the Class ones: # content = String() [saved to disk in /db/files/] @@ -151,7 +153,7 @@ # Assign the appropriate permissions to the anonymous user's Anonymous # Role. Choices here are: # - Allow anonymous users to register -db.security.addPermissionToRole('Anonymous', 'Create', 'user') +db.security.addPermissionToRole('Anonymous', 'Register', 'user') # Allow anonymous users access to view issues (and the related, linked # information) From python-checkins at python.org Tue Dec 1 07:16:23 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:16:23 -0000 Subject: [Python-checkins] r76616 - tracker/instances/python-dev/html/page.html Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:16:22 2009 New Revision: 76616 Log: More changes from r4238: Consider Register permission in template. 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 Tue Dec 1 07:16:22 2009 @@ -145,7 +145,7 @@
  • Register
  • Lost your login? From python-checkins at python.org Tue Dec 1 07:17:05 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:17:05 -0000 Subject: [Python-checkins] r76617 - tracker/instances/meta/html/page.html Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:17:05 2009 New Revision: 76617 Log: More changes from r4238: Consider Register permission in template. Modified: tracker/instances/meta/html/page.html Modified: tracker/instances/meta/html/page.html ============================================================================== --- tracker/instances/meta/html/page.html (original) +++ tracker/instances/meta/html/page.html Tue Dec 1 07:17:05 2009 @@ -134,7 +134,7 @@ Register
    Lost your login?

    From python-checkins at python.org Tue Dec 1 07:17:30 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:17:30 -0000 Subject: [Python-checkins] r76618 - tracker/instances/jython/html/page.html Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:17:30 2009 New Revision: 76618 Log: More changes from r4238: Consider Register permission in template. Modified: tracker/instances/jython/html/page.html Modified: tracker/instances/jython/html/page.html ============================================================================== --- tracker/instances/jython/html/page.html (original) +++ tracker/instances/jython/html/page.html Tue Dec 1 07:17:30 2009 @@ -163,7 +163,7 @@ Register From python-checkins at python.org Tue Dec 1 07:18:05 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:18:05 -0000 Subject: [Python-checkins] r76619 - tracker/instances/setuptools/html/page.html Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:18:04 2009 New Revision: 76619 Log: More changes from r4238: Consider Register permission in template. Modified: tracker/instances/setuptools/html/page.html Modified: tracker/instances/setuptools/html/page.html ============================================================================== --- tracker/instances/setuptools/html/page.html (original) +++ tracker/instances/setuptools/html/page.html Tue Dec 1 07:18:04 2009 @@ -136,7 +136,7 @@ Register
    Lost your login?

    From python-checkins at python.org Tue Dec 1 07:18:55 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:18:55 -0000 Subject: [Python-checkins] r76620 - tracker/instances/jobs/html/page.html Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:18:55 2009 New Revision: 76620 Log: More changes from r4238: Consider Register permission in template. Modified: tracker/instances/jobs/html/page.html Modified: tracker/instances/jobs/html/page.html ============================================================================== --- tracker/instances/jobs/html/page.html (original) +++ tracker/instances/jobs/html/page.html Tue Dec 1 07:18:55 2009 @@ -117,7 +117,7 @@
  • Register
  • Lost your login? From python-checkins at python.org Tue Dec 1 07:20:15 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 01 Dec 2009 06:20:15 -0000 Subject: [Python-checkins] r76621 - tracker/instances/jython/html/page.html Message-ID: Author: martin.v.loewis Date: Tue Dec 1 07:20:15 2009 New Revision: 76621 Log: Remove demo marker from template. Modified: tracker/instances/jython/html/page.html Modified: tracker/instances/jython/html/page.html ============================================================================== --- tracker/instances/jython/html/page.html (original) +++ tracker/instances/jython/html/page.html Tue Dec 1 07:20:15 2009 @@ -38,7 +38,6 @@ title="Jython" /> -This is a demo installation. Do not use it to report real bugs.
  • Register
  • Lost your login? From python-checkins at python.org Tue Dec 1 16:54:02 2009 From: python-checkins at python.org (ronald.oussoren) Date: Tue, 01 Dec 2009 15:54:02 -0000 Subject: [Python-checkins] r76623 - python/trunk/Include/pymacconfig.h Message-ID: Author: ronald.oussoren Date: Tue Dec 1 16:54:01 2009 New Revision: 76623 Log: Fix for issue #7416: SIZEOF_UINTPTR_T can be invalid when configuring a multi-architecture build (in particular when the architectures don't share a common pointer size). Fixed the same issue for SIZEOF_PTHREAD_T. (No update to the NEWS file because this is a bugfix for an as yet unreleased feature) Modified: python/trunk/Include/pymacconfig.h Modified: python/trunk/Include/pymacconfig.h ============================================================================== --- python/trunk/Include/pymacconfig.h (original) +++ python/trunk/Include/pymacconfig.h Tue Dec 1 16:54:01 2009 @@ -16,6 +16,8 @@ # undef SIZEOF_TIME_T # undef SIZEOF_VOID_P # undef SIZEOF__BOOL +# undef SIZEOF_UINTPTR_T +# undef SIZEOF_PTHREAD_T # undef WORDS_BIGENDIAN # undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 # undef DOUBLE_IS_BIG_ENDIAN_IEEE754 @@ -40,6 +42,8 @@ # define SIZEOF_SIZE_T 8 # define SIZEOF_TIME_T 8 # define SIZEOF_VOID_P 8 +# define SIZEOF_UINTPTR_T 8 +# define SIZEOF_PTHREAD_T 8 # else # ifdef __ppc__ # define SIZEOF__BOOL 4 @@ -51,6 +55,8 @@ # define SIZEOF_SIZE_T 4 # define SIZEOF_TIME_T 4 # define SIZEOF_VOID_P 4 +# define SIZEOF_UINTPTR_T 4 +# define SIZEOF_PTHREAD_T 4 # endif # if defined(__LP64__) From python-checkins at python.org Tue Dec 1 16:55:14 2009 From: python-checkins at python.org (ronald.oussoren) Date: Tue, 01 Dec 2009 15:55:14 -0000 Subject: [Python-checkins] r76624 - in python/branches/py3k: Include/pymacconfig.h Message-ID: Author: ronald.oussoren Date: Tue Dec 1 16:55:14 2009 New Revision: 76624 Log: Merged revisions 76623 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76623 | ronald.oussoren | 2009-12-01 16:54:01 +0100 (Tue, 01 Dec 2009) | 9 lines Fix for issue #7416: SIZEOF_UINTPTR_T can be invalid when configuring a multi-architecture build (in particular when the architectures don't share a common pointer size). Fixed the same issue for SIZEOF_PTHREAD_T. (No update to the NEWS file because this is a bugfix for an as yet unreleased feature) ........ 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 Tue Dec 1 16:55:14 2009 @@ -16,6 +16,8 @@ # undef SIZEOF_TIME_T # undef SIZEOF_VOID_P # undef SIZEOF__BOOL +# undef SIZEOF_UINTPTR_T +# undef SIZEOF_PTHREAD_T # undef WORDS_BIGENDIAN # undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 # undef DOUBLE_IS_BIG_ENDIAN_IEEE754 @@ -43,6 +45,8 @@ # define SIZEOF_SIZE_T 8 # define SIZEOF_TIME_T 8 # define SIZEOF_VOID_P 8 +# define SIZEOF_UINTPTR_T 8 +# define SIZEOF_PTHREAD_T 8 # else # ifdef __ppc__ # define SIZEOF__BOOL 4 @@ -54,6 +58,8 @@ # define SIZEOF_SIZE_T 4 # define SIZEOF_TIME_T 4 # define SIZEOF_VOID_P 4 +# define SIZEOF_UINTPTR_T 4 +# define SIZEOF_PTHREAD_T 4 # endif # if defined(__LP64__) From python-checkins at python.org Tue Dec 1 22:51:05 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Tue, 01 Dec 2009 21:51:05 -0000 Subject: [Python-checkins] r76625 - in python/trunk: Lib/test/test_locale.py Misc/NEWS Modules/_localemodule.c Message-ID: Author: amaury.forgeotdarc Date: Tue Dec 1 22:51:04 2009 New Revision: 76625 Log: #7419: Fix a crash on Windows in locale.setlocale() when the category is outside the allowed range. Modified: python/trunk/Lib/test/test_locale.py python/trunk/Misc/NEWS python/trunk/Modules/_localemodule.c Modified: python/trunk/Lib/test/test_locale.py ============================================================================== --- python/trunk/Lib/test/test_locale.py (original) +++ python/trunk/Lib/test/test_locale.py Tue Dec 1 22:51:04 2009 @@ -360,6 +360,17 @@ # test crasher from bug #3303 self.assertRaises(TypeError, locale.strcoll, u"a", None) + def test_setlocale_category(self): + locale.setlocale(locale.LC_ALL) + locale.setlocale(locale.LC_TIME) + locale.setlocale(locale.LC_CTYPE) + locale.setlocale(locale.LC_COLLATE) + locale.setlocale(locale.LC_MONETARY) + locale.setlocale(locale.LC_NUMERIC) + + # crasher from bug #7419 + self.assertRaises(locale.Error, locale.setlocale, 12345) + def test_main(): tests = [ Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Dec 1 22:51:04 2009 @@ -12,10 +12,13 @@ Core and Builtins ----------------- +- Issue #7419: setlocale() could crash the interpreter on Windows when called + with invalid values. + - Issue #3382: 'F' formatting for float and complex now convert the result to upper case. This only affects 'inf' and 'nan', since 'f' no longer converts to 'g' for large values. - + - Remove switch from "%f" formatting to "%g" formatting for floats larger than 1e50 in absolute value. Modified: python/trunk/Modules/_localemodule.c ============================================================================== --- python/trunk/Modules/_localemodule.c (original) +++ python/trunk/Modules/_localemodule.c Tue Dec 1 22:51:04 2009 @@ -163,6 +163,14 @@ if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale)) return NULL; +#if defined(MS_WINDOWS) + if (category < LC_MIN || category > LC_MAX) + { + PyErr_SetString(Error, "invalid locale category"); + return NULL; + } +#endif + if (locale) { /* set locale */ result = setlocale(category, locale); From python-checkins at python.org Tue Dec 1 22:59:19 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Tue, 01 Dec 2009 21:59:19 -0000 Subject: [Python-checkins] r76626 - in python/branches/py3k: Lib/test/test_locale.py Misc/NEWS Modules/_localemodule.c Message-ID: Author: amaury.forgeotdarc Date: Tue Dec 1 22:59:18 2009 New Revision: 76626 Log: Merged revisions 76625 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76625 | amaury.forgeotdarc | 2009-12-01 22:51:04 +0100 (mar., 01 d?c. 2009) | 3 lines #7419: Fix a crash on Windows in locale.setlocale() when the category is outside the allowed range. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_locale.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_localemodule.c 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 Tue Dec 1 22:59:18 2009 @@ -353,6 +353,17 @@ self.assertRaises(TypeError, locale.strcoll, "a", None) self.assertRaises(TypeError, locale.strcoll, b"a", None) + def test_setlocale_category(self): + locale.setlocale(locale.LC_ALL) + locale.setlocale(locale.LC_TIME) + locale.setlocale(locale.LC_CTYPE) + locale.setlocale(locale.LC_COLLATE) + locale.setlocale(locale.LC_MONETARY) + locale.setlocale(locale.LC_NUMERIC) + + # crasher from bug #7419 + self.assertRaises(locale.Error, locale.setlocale, 12345) + def test_main(): tests = [ Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Dec 1 22:59:18 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7419: setlocale() could crash the interpreter on Windows when called + with invalid values. + - Issue #6077: On Windows, files opened with tempfile.TemporaryFile in "wt+" mode would appear truncated on the first '0x1a' byte (aka. Ctrl+Z). Modified: python/branches/py3k/Modules/_localemodule.c ============================================================================== --- python/branches/py3k/Modules/_localemodule.c (original) +++ python/branches/py3k/Modules/_localemodule.c Tue Dec 1 22:59:18 2009 @@ -133,6 +133,14 @@ if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale)) return NULL; +#if defined(MS_WINDOWS) + if (category < LC_MIN || category > LC_MAX) + { + PyErr_SetString(Error, "invalid locale category"); + return NULL; + } +#endif + if (locale) { /* set locale */ result = setlocale(category, locale); From python-checkins at python.org Tue Dec 1 23:03:45 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Tue, 01 Dec 2009 22:03:45 -0000 Subject: [Python-checkins] r76627 - in python/branches/release31-maint: Lib/test/test_locale.py Misc/NEWS Modules/_localemodule.c Message-ID: Author: amaury.forgeotdarc Date: Tue Dec 1 23:03:44 2009 New Revision: 76627 Log: Merged revisions 76626 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76626 | amaury.forgeotdarc | 2009-12-01 22:59:18 +0100 (mar., 01 d?c. 2009) | 10 lines Merged revisions 76625 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76625 | amaury.forgeotdarc | 2009-12-01 22:51:04 +0100 (mar., 01 d?c. 2009) | 3 lines #7419: Fix a crash on Windows in locale.setlocale() when the category is outside the allowed range. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_locale.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/_localemodule.c Modified: python/branches/release31-maint/Lib/test/test_locale.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_locale.py (original) +++ python/branches/release31-maint/Lib/test/test_locale.py Tue Dec 1 23:03:44 2009 @@ -353,6 +353,17 @@ self.assertRaises(TypeError, locale.strcoll, "a", None) self.assertRaises(TypeError, locale.strcoll, b"a", None) + def test_setlocale_category(self): + locale.setlocale(locale.LC_ALL) + locale.setlocale(locale.LC_TIME) + locale.setlocale(locale.LC_CTYPE) + locale.setlocale(locale.LC_COLLATE) + locale.setlocale(locale.LC_MONETARY) + locale.setlocale(locale.LC_NUMERIC) + + # crasher from bug #7419 + self.assertRaises(locale.Error, locale.setlocale, 12345) + def test_main(): tests = [ Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Tue Dec 1 23:03:44 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7419: setlocale() could crash the interpreter on Windows when called + with invalid values. + - Issue #6077: On Windows, files opened with tempfile.TemporaryFile in "wt+" mode would appear truncated on the first '0x1a' byte (aka. Ctrl+Z). Modified: python/branches/release31-maint/Modules/_localemodule.c ============================================================================== --- python/branches/release31-maint/Modules/_localemodule.c (original) +++ python/branches/release31-maint/Modules/_localemodule.c Tue Dec 1 23:03:44 2009 @@ -133,6 +133,14 @@ if (!PyArg_ParseTuple(args, "i|z:setlocale", &category, &locale)) return NULL; +#if defined(MS_WINDOWS) + if (category < LC_MIN || category > LC_MAX) + { + PyErr_SetString(Error, "invalid locale category"); + return NULL; + } +#endif + if (locale) { /* set locale */ result = setlocale(category, locale); From solipsis at pitrou.net Wed Dec 2 00:48:21 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 2 Dec 2009 00:48:21 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76626): sum=48 Message-ID: <20091201234821.6BBD917715@ns6635.ovh.net> py3k results for svn r76626 (hg cset 98519891a973) -------------------------------------------------- test_multiprocessing leaked [0, 0, 3] references, sum=3 test_urllib leaked [10, 2, 4] references, sum=16 test_zipimport_support leaked [29, 0, 0] references, sum=29 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogW9JM82', '-x', 'test_httpservers'] From nnorwitz at gmail.com Wed Dec 2 11:54:17 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 2 Dec 2009 05:54:17 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091202105417.GA9683@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [0, 0, 80] references, sum=80 Less important issues: ---------------------- From python-checkins at python.org Wed Dec 2 15:27:11 2009 From: python-checkins at python.org (andrew.kuchling) Date: Wed, 02 Dec 2009 14:27:11 -0000 Subject: [Python-checkins] r76628 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: andrew.kuchling Date: Wed Dec 2 15:27:11 2009 New Revision: 76628 Log: Markup fixes 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 Wed Dec 2 15:27:11 2009 @@ -583,14 +583,14 @@ an invalid file descriptor. (Implemented by Benjamin Peterson; :issue:`4991`.) -* New function: ``itertools.compress(*data*, *selectors*)`` takes two +* 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*)`` + 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:: @@ -1076,5 +1076,5 @@ The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this -article: no one yet. +article: Hugh Secker-Walker. From python-checkins at python.org Wed Dec 2 18:33:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 02 Dec 2009 17:33:41 -0000 Subject: [Python-checkins] r76629 - in python/trunk: Objects/intobject.c Python/ceval.c Message-ID: Author: mark.dickinson Date: Wed Dec 2 18:33:41 2009 New Revision: 76629 Log: Issue #7406: Fix some occurrences of potential signed overflow in int arithmetic. Modified: python/trunk/Objects/intobject.c python/trunk/Python/ceval.c Modified: python/trunk/Objects/intobject.c ============================================================================== --- python/trunk/Objects/intobject.c (original) +++ python/trunk/Objects/intobject.c Wed Dec 2 18:33:41 2009 @@ -461,7 +461,8 @@ register long a, b, x; CONVERT_TO_LONG(v, a); CONVERT_TO_LONG(w, b); - x = a + b; + /* casts in the line below avoid undefined behaviour on overflow */ + x = (long)((unsigned long)a + b); if ((x^a) >= 0 || (x^b) >= 0) return PyInt_FromLong(x); return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w); @@ -473,7 +474,8 @@ register long a, b, x; CONVERT_TO_LONG(v, a); CONVERT_TO_LONG(w, b); - x = a - b; + /* casts in the line below avoid undefined behaviour on overflow */ + x = (long)((unsigned long)a - b); if ((x^a) >= 0 || (x^~b) >= 0) return PyInt_FromLong(x); return PyLong_Type.tp_as_number->nb_subtract((PyObject *)v, @@ -516,7 +518,8 @@ CONVERT_TO_LONG(v, a); CONVERT_TO_LONG(w, b); - longprod = a * b; + /* casts in the next line avoid undefined behaviour on overflow */ + longprod = (long)((unsigned long)a * b); doubleprod = (double)a * (double)b; doubled_longprod = (double)longprod; Modified: python/trunk/Python/ceval.c ============================================================================== --- python/trunk/Python/ceval.c (original) +++ python/trunk/Python/ceval.c Wed Dec 2 18:33:41 2009 @@ -1321,7 +1321,9 @@ register long a, b, i; a = PyInt_AS_LONG(v); b = PyInt_AS_LONG(w); - i = a + b; + /* cast to avoid undefined behaviour + on overflow */ + i = (long)((unsigned long)a + b); if ((i^a) < 0 && (i^b) < 0) goto slow_add; x = PyInt_FromLong(i); @@ -1351,7 +1353,9 @@ register long a, b, i; a = PyInt_AS_LONG(v); b = PyInt_AS_LONG(w); - i = a - b; + /* cast to avoid undefined behaviour + on overflow */ + i = (long)((unsigned long)a - b); if ((i^a) < 0 && (i^~b) < 0) goto slow_sub; x = PyInt_FromLong(i); From python-checkins at python.org Wed Dec 2 18:36:34 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 02 Dec 2009 17:36:34 -0000 Subject: [Python-checkins] r76630 - in python/branches/release26-maint: Objects/intobject.c Python/ceval.c Message-ID: Author: mark.dickinson Date: Wed Dec 2 18:36:34 2009 New Revision: 76630 Log: Merged revisions 76629 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76629 | mark.dickinson | 2009-12-02 17:33:41 +0000 (Wed, 02 Dec 2009) | 3 lines Issue #7406: Fix some occurrences of potential signed overflow in int arithmetic. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Objects/intobject.c python/branches/release26-maint/Python/ceval.c Modified: python/branches/release26-maint/Objects/intobject.c ============================================================================== --- python/branches/release26-maint/Objects/intobject.c (original) +++ python/branches/release26-maint/Objects/intobject.c Wed Dec 2 18:36:34 2009 @@ -465,7 +465,8 @@ register long a, b, x; CONVERT_TO_LONG(v, a); CONVERT_TO_LONG(w, b); - x = a + b; + /* casts in the line below avoid undefined behaviour on overflow */ + x = (long)((unsigned long)a + b); if ((x^a) >= 0 || (x^b) >= 0) return PyInt_FromLong(x); return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w); @@ -477,7 +478,8 @@ register long a, b, x; CONVERT_TO_LONG(v, a); CONVERT_TO_LONG(w, b); - x = a - b; + /* casts in the line below avoid undefined behaviour on overflow */ + x = (long)((unsigned long)a - b); if ((x^a) >= 0 || (x^~b) >= 0) return PyInt_FromLong(x); return PyLong_Type.tp_as_number->nb_subtract((PyObject *)v, @@ -520,7 +522,8 @@ CONVERT_TO_LONG(v, a); CONVERT_TO_LONG(w, b); - longprod = a * b; + /* casts in the next line avoid undefined behaviour on overflow */ + longprod = (long)((unsigned long)a * b); doubleprod = (double)a * (double)b; doubled_longprod = (double)longprod; Modified: python/branches/release26-maint/Python/ceval.c ============================================================================== --- python/branches/release26-maint/Python/ceval.c (original) +++ python/branches/release26-maint/Python/ceval.c Wed Dec 2 18:36:34 2009 @@ -1191,7 +1191,9 @@ register long a, b, i; a = PyInt_AS_LONG(v); b = PyInt_AS_LONG(w); - i = a + b; + /* cast to avoid undefined behaviour + on overflow */ + i = (long)((unsigned long)a + b); if ((i^a) < 0 && (i^b) < 0) goto slow_add; x = PyInt_FromLong(i); @@ -1221,7 +1223,9 @@ register long a, b, i; a = PyInt_AS_LONG(v); b = PyInt_AS_LONG(w); - i = a - b; + /* cast to avoid undefined behaviour + on overflow */ + i = (long)((unsigned long)a - b); if ((i^a) < 0 && (i^~b) < 0) goto slow_sub; x = PyInt_FromLong(i); From python-checkins at python.org Wed Dec 2 18:37:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 02 Dec 2009 17:37:21 -0000 Subject: [Python-checkins] r76631 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Wed Dec 2 18:37:21 2009 New Revision: 76631 Log: Blocked revisions 76629 via svnmerge ........ r76629 | mark.dickinson | 2009-12-02 17:33:41 +0000 (Wed, 02 Dec 2009) | 3 lines Issue #7406: Fix some occurrences of potential signed overflow in int arithmetic. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Wed Dec 2 18:43:07 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 02 Dec 2009 17:43:07 -0000 Subject: [Python-checkins] r76632 - python/trunk/Lib/test/test_float.py Message-ID: Author: eric.smith Date: Wed Dec 2 18:43:06 2009 New Revision: 76632 Log: Issue #4482: Add tests for special float value formatting. Modified: python/trunk/Lib/test/test_float.py Modified: python/trunk/Lib/test/test_float.py ============================================================================== --- python/trunk/Lib/test/test_float.py (original) +++ python/trunk/Lib/test/test_float.py Wed Dec 2 18:43:06 2009 @@ -490,6 +490,41 @@ self.assertAlmostEqual(round(0.5e22, -22), 1e22) self.assertAlmostEqual(round(1.5e22, -22), 2e22) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_format_specials(self): + # Test formatting of nans and infs. + + def test(fmt, value, expected): + # Test with both % and format(). + self.assertEqual(fmt % value, expected, fmt) + if not '#' in fmt: + # Until issue 7094 is implemented, format() for floats doesn't + # support '#' formatting + fmt = fmt[1:] # strip off the % + self.assertEqual(format(value, fmt), expected, fmt) + + for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g', + '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']: + pfmt = '%+' + fmt[1:] + sfmt = '% ' + fmt[1:] + test(fmt, INF, 'inf') + test(fmt, -INF, '-inf') + test(fmt, NAN, 'nan') + test(fmt, -NAN, 'nan') + # When asking for a sign, it's always provided. nans are + # always positive. + test(pfmt, INF, '+inf') + test(pfmt, -INF, '-inf') + test(pfmt, NAN, '+nan') + test(pfmt, -NAN, '+nan') + # When using ' ' for a sign code, only infs can be negative. + # Others have a space. + test(sfmt, INF, ' inf') + test(sfmt, -INF, '-inf') + test(sfmt, NAN, ' nan') + test(sfmt, -NAN, ' nan') + # Beginning with Python 2.6 float has cross platform compatible # ways to create and represent inf and nan From python-checkins at python.org Wed Dec 2 18:46:47 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 02 Dec 2009 17:46:47 -0000 Subject: [Python-checkins] r76633 - python/branches/release26-maint Message-ID: Author: eric.smith Date: Wed Dec 2 18:46:47 2009 New Revision: 76633 Log: Blocked revisions 76632 via svnmerge ........ r76632 | eric.smith | 2009-12-02 12:43:06 -0500 (Wed, 02 Dec 2009) | 1 line Issue #4482: Add tests for special float value formatting. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Dec 2 18:58:24 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 02 Dec 2009 17:58:24 -0000 Subject: [Python-checkins] r76634 - in python/branches/py3k: Lib/test/test_float.py Message-ID: Author: eric.smith Date: Wed Dec 2 18:58:24 2009 New Revision: 76634 Log: Merged revisions 76632 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76632 | eric.smith | 2009-12-02 12:43:06 -0500 (Wed, 02 Dec 2009) | 1 line Issue #4482: Add tests for special float value formatting. ........ Modified: python/branches/py3k/ (props changed) 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 Wed Dec 2 18:58:24 2009 @@ -495,6 +495,41 @@ self.assertEqual(float(format(x, '.3f')), round(x, 3)) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_format_specials(self): + # Test formatting of nans and infs. + + def test(fmt, value, expected): + # Test with both % and format(). + self.assertEqual(fmt % value, expected, fmt) + if not '#' in fmt: + # Until issue 7094 is implemented, format() for floats doesn't + # support '#' formatting + fmt = fmt[1:] # strip off the % + self.assertEqual(format(value, fmt), expected, fmt) + + for fmt in ['%e', '%f', '%g', '%.0e', '%.6f', '%.20g', + '%#e', '%#f', '%#g', '%#.20e', '%#.15f', '%#.3g']: + pfmt = '%+' + fmt[1:] + sfmt = '% ' + fmt[1:] + test(fmt, INF, 'inf') + test(fmt, -INF, '-inf') + test(fmt, NAN, 'nan') + test(fmt, -NAN, 'nan') + # When asking for a sign, it's always provided. nans are + # always positive. + test(pfmt, INF, '+inf') + test(pfmt, -INF, '-inf') + test(pfmt, NAN, '+nan') + test(pfmt, -NAN, '+nan') + # When using ' ' for a sign code, only infs can be negative. + # Others have a space. + test(sfmt, INF, ' inf') + test(sfmt, -INF, '-inf') + test(sfmt, NAN, ' nan') + test(sfmt, -NAN, ' nan') + # Beginning with Python 2.6 float has cross platform compatible # ways to create and represent inf and nan From python-checkins at python.org Wed Dec 2 18:59:46 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 02 Dec 2009 17:59:46 -0000 Subject: [Python-checkins] r76635 - python/branches/release31-maint Message-ID: Author: eric.smith Date: Wed Dec 2 18:59:45 2009 New Revision: 76635 Log: Blocked revisions 76634 via svnmerge ................ r76634 | eric.smith | 2009-12-02 12:58:24 -0500 (Wed, 02 Dec 2009) | 9 lines Merged revisions 76632 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76632 | eric.smith | 2009-12-02 12:43:06 -0500 (Wed, 02 Dec 2009) | 1 line Issue #4482: Add tests for special float value formatting. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Wed Dec 2 21:37:55 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 02 Dec 2009 20:37:55 -0000 Subject: [Python-checkins] r76636 - in python/trunk: Doc/library/os.rst Lib/test/test_posix.py Misc/NEWS Modules/posixmodule.c configure configure.in pyconfig.h.in Message-ID: Author: antoine.pitrou Date: Wed Dec 2 21:37:54 2009 New Revision: 76636 Log: Issue #7333: The `posix` module gains an `initgroups()` function providing access to the initgroups(3) C library call on Unix systems which implement it. Patch by Jean-Paul Calderone. Modified: python/trunk/Doc/library/os.rst python/trunk/Lib/test/test_posix.py python/trunk/Misc/NEWS python/trunk/Modules/posixmodule.c python/trunk/configure python/trunk/configure.in python/trunk/pyconfig.h.in Modified: python/trunk/Doc/library/os.rst ============================================================================== --- python/trunk/Doc/library/os.rst (original) +++ python/trunk/Doc/library/os.rst Wed Dec 2 21:37:54 2009 @@ -136,6 +136,15 @@ Availability: Unix. +.. function:: initgroups(username, gid) + + Call the system initgroups() to initialize the group access list with all of + the groups of which the specified username is a member, plus the specified + group id. Availability: Unix. + + .. versionadded:: 2.7 + + .. function:: getlogin() Return the name of the user logged in on the controlling terminal of the Modified: python/trunk/Lib/test/test_posix.py ============================================================================== --- python/trunk/Lib/test/test_posix.py (original) +++ python/trunk/Lib/test/test_posix.py Wed Dec 2 21:37:54 2009 @@ -5,6 +5,7 @@ # Skip these tests if there is no posix module. posix = test_support.import_module('posix') +import errno import time import os import pwd @@ -83,6 +84,27 @@ new_group_ids = (current_group_ids[0]+1, -1, -1) self.assertRaises(OSError, posix.setresgid, *new_group_ids) + @unittest.skipUnless(hasattr(posix, 'initgroups'), + "test needs os.initgroups()") + def test_initgroups(self): + # It takes a string and an integer; check that it raises a TypeError + # for other argument lists. + self.assertRaises(TypeError, posix.initgroups) + self.assertRaises(TypeError, posix.initgroups, None) + self.assertRaises(TypeError, posix.initgroups, 3, "foo") + self.assertRaises(TypeError, posix.initgroups, "foo", 3, object()) + + # If a non-privileged user invokes it, it should fail with OSError + # EPERM. + if os.getuid() != 0: + name = pwd.getpwuid(posix.getuid()).pw_name + try: + posix.initgroups(name, 13) + except OSError as e: + self.assertEquals(e.errno, errno.EPERM) + else: + self.fail("Expected OSError to be raised by initgroups") + def test_statvfs(self): if hasattr(posix, 'statvfs'): self.assertTrue(posix.statvfs(os.curdir)) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Dec 2 21:37:54 2009 @@ -490,6 +490,10 @@ Library ------- +- Issue #7333: The `posix` module gains an `initgroups()` function providing + access to the initgroups(3) C library call on Unix systems which implement + it. Patch by Jean-Paul Calderone. + - Issue #7408: Fixed distutils.tests.sdist so it doesn't check for group ownership when the group is not forced, because the group may be different from the user's group and inherit from its container when the test is run. Modified: python/trunk/Modules/posixmodule.c ============================================================================== --- python/trunk/Modules/posixmodule.c (original) +++ python/trunk/Modules/posixmodule.c Wed Dec 2 21:37:54 2009 @@ -3861,6 +3861,30 @@ } #endif +#ifdef HAVE_INITGROUPS +PyDoc_STRVAR(posix_initgroups__doc__, +"initgroups(username, gid) -> None\n\n\ +Call the system initgroups() to initialize the group access list with all of\n\ +the groups of which the specified username is a member, plus the specified\n\ +group id."); + +static PyObject * +posix_initgroups(PyObject *self, PyObject *args) +{ + char *username; + long gid; + + if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid)) + return NULL; + + if (initgroups(username, (gid_t) gid) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + + Py_INCREF(Py_None); + return Py_None; +} +#endif + #ifdef HAVE_GETPGID PyDoc_STRVAR(posix_getpgid__doc__, "getpgid(pid) -> pgid\n\n\ @@ -8629,6 +8653,9 @@ #ifdef HAVE_SETGROUPS {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__}, #endif /* HAVE_SETGROUPS */ +#ifdef HAVE_INITGROUPS + {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__}, +#endif /* HAVE_INITGROUPS */ #ifdef HAVE_GETPGID {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, #endif /* HAVE_GETPGID */ Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Wed Dec 2 21:37:54 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76558 . +# From configure.in Revision: 76568 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -17895,11 +17895,12 @@ + 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 \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ - kill killpg lchmod lchown lstat mkfifo mknod mktime \ + initgroups kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Wed Dec 2 21:37:54 2009 @@ -2547,7 +2547,7 @@ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ - kill killpg lchmod lchown lstat mkfifo mknod mktime \ + initgroups kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ Modified: python/trunk/pyconfig.h.in ============================================================================== --- python/trunk/pyconfig.h.in (original) +++ python/trunk/pyconfig.h.in Wed Dec 2 21:37:54 2009 @@ -301,6 +301,9 @@ /* Define to 1 if you have the `getpeername' function. */ #undef HAVE_GETPEERNAME +/* Define to 1 if you have the `initgroups' function. */ +#undef HAVE_INITGROUPS + /* Define to 1 if you have the `getpgid' function. */ #undef HAVE_GETPGID From python-checkins at python.org Wed Dec 2 21:46:49 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 02 Dec 2009 20:46:49 -0000 Subject: [Python-checkins] r76637 - in python/branches/py3k: Doc/library/os.rst Lib/test/test_posix.py Misc/NEWS Modules/posixmodule.c configure configure.in pyconfig.h.in Message-ID: Author: antoine.pitrou Date: Wed Dec 2 21:46:48 2009 New Revision: 76637 Log: Merged revisions 76636 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76636 | antoine.pitrou | 2009-12-02 21:37:54 +0100 (mer., 02 d?c. 2009) | 5 lines Issue #7333: The `posix` module gains an `initgroups()` function providing access to the initgroups(3) C library call on Unix systems which implement it. Patch by Jean-Paul Calderone. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/os.rst python/branches/py3k/Lib/test/test_posix.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/posixmodule.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Wed Dec 2 21:46:48 2009 @@ -161,6 +161,15 @@ Availability: Unix. +.. function:: initgroups(username, gid) + + Call the system initgroups() to initialize the group access list with all of + the groups of which the specified username is a member, plus the specified + group id. Availability: Unix. + + .. versionadded:: 3.2 + + .. function:: getlogin() Return the name of the user logged in on the controlling terminal of the 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 Dec 2 21:46:48 2009 @@ -5,6 +5,7 @@ # Skip these tests if there is no posix module. posix = support.import_module('posix') +import errno import time import os import pwd @@ -82,6 +83,27 @@ new_group_ids = (current_group_ids[0]+1, -1, -1) self.assertRaises(OSError, posix.setresgid, *new_group_ids) + @unittest.skipUnless(hasattr(posix, 'initgroups'), + "test needs os.initgroups()") + def test_initgroups(self): + # It takes a string and an integer; check that it raises a TypeError + # for other argument lists. + self.assertRaises(TypeError, posix.initgroups) + self.assertRaises(TypeError, posix.initgroups, None) + self.assertRaises(TypeError, posix.initgroups, 3, "foo") + self.assertRaises(TypeError, posix.initgroups, "foo", 3, object()) + + # If a non-privileged user invokes it, it should fail with OSError + # EPERM. + if os.getuid() != 0: + name = pwd.getpwuid(posix.getuid()).pw_name + try: + posix.initgroups(name, 13) + except OSError as e: + self.assertEquals(e.errno, errno.EPERM) + else: + self.fail("Expected OSError to be raised by initgroups") + def test_statvfs(self): if hasattr(posix, 'statvfs'): self.assertTrue(posix.statvfs(os.curdir)) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 2 21:46:48 2009 @@ -146,6 +146,10 @@ Library ------- +- Issue #7333: The `posix` module gains an `initgroups()` function providing + access to the initgroups(3) C library call on Unix systems which implement + it. Patch by Jean-Paul Calderone. + - Issue #7408: Fixed distutils.tests.sdist so it doesn't check for group ownership when the group is not forced, because the group may be different from the user's group and inherit from its container when the test is run. Modified: python/branches/py3k/Modules/posixmodule.c ============================================================================== --- python/branches/py3k/Modules/posixmodule.c (original) +++ python/branches/py3k/Modules/posixmodule.c Wed Dec 2 21:46:48 2009 @@ -3979,6 +3979,30 @@ } #endif +#ifdef HAVE_INITGROUPS +PyDoc_STRVAR(posix_initgroups__doc__, +"initgroups(username, gid) -> None\n\n\ +Call the system initgroups() to initialize the group access list with all of\n\ +the groups of which the specified username is a member, plus the specified\n\ +group id."); + +static PyObject * +posix_initgroups(PyObject *self, PyObject *args) +{ + char *username; + long gid; + + if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid)) + return NULL; + + if (initgroups(username, (gid_t) gid) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + + Py_INCREF(Py_None); + return Py_None; +} +#endif + #ifdef HAVE_GETPGID PyDoc_STRVAR(posix_getpgid__doc__, "getpgid(pid) -> pgid\n\n\ @@ -7184,6 +7208,9 @@ #ifdef HAVE_SETGROUPS {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__}, #endif /* HAVE_SETGROUPS */ +#ifdef HAVE_INITGROUPS + {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__}, +#endif /* HAVE_INITGROUPS */ #ifdef HAVE_GETPGID {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, #endif /* HAVE_GETPGID */ Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Wed Dec 2 21:46:48 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76552 . +# From configure.in Revision: 76566 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -17379,11 +17379,12 @@ + 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 \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ - kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \ + initgroups kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Wed Dec 2 21:46:48 2009 @@ -2418,7 +2418,7 @@ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ - kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \ + initgroups kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Wed Dec 2 21:46:48 2009 @@ -299,6 +299,9 @@ /* Define to 1 if you have the `getpeername' function. */ #undef HAVE_GETPEERNAME +/* Define to 1 if you have the `initgroups' function. */ +#undef HAVE_INITGROUPS + /* Define to 1 if you have the `getpgid' function. */ #undef HAVE_GETPGID From python-checkins at python.org Wed Dec 2 23:14:13 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Dec 2009 22:14:13 -0000 Subject: [Python-checkins] r76638 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Wed Dec 2 23:14:13 2009 New Revision: 76638 Log: massive editing to extend the rational - thanks Pachi Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Wed Dec 2 23:14:13 2009 @@ -12,20 +12,25 @@ Abstract ======== -This PEP proposes the inclusion of a new version comparison system in -Distutils. +This PEP proposes a new version comparison schema system in Distutils. Motivation ========== -Distutils will soon extend the metadata standard, by including an -``install_requires``-like field from Setuptools [#requires]_ among -other changes. This field will be called ``Requires-Dist``. +In Python there are no real restriction yet on how a project should manage its +versions, and how they should be incremented. -These changes are located in PEP 345 [#pep345]_. +Distutile provides a `version` distribution meta-data field but it is freeform and +current users, such as PyPI usually consider the latest version pushed as the +`latest` one, regardless of the expected semantics. + +Distutils will soon extend its capabilities to allow distributions to express a +dependency on other distributions through the `Requires-Dist` metadata field +(see PEP 345 [#pep345]_) and it will optionally allow to use that field to +restrict the dependency to a set of compatible versions. -The ``Requires-Dist`` field will allow a package to define a dependency on +The ``Requires-Dist`` field will allow a distribution to define a dependency on another package and optionally restrict this dependency to a set of compatible versions, so one may write:: @@ -38,33 +43,45 @@ than the tool that will be used to install them, so they are able to compare versions. -That's why Distutils needs to provide a robust standard and reference -version scheme, and an API to provide version comparisons. +That is why this PEP proposes, for the sake of interoperability, a standard +schema to express version information and its comparison semantics. -This PEP describes a new version scheme that will be added in Distutils. - -Of course developers are **not** required to conform to this scheme, but -it is suggested to use it as a standard for interoperability between the -existing Python distributions installers. - -Current status -============== - -In Python there are no real restriction yet on how a project should manage -its versions, and how they should be incremented. They are no standard -either, even if they are a few conventions widely used, like having a major -and a minor revision (1.1, 1.2, etc.). - -Developers are free to put in the `version` meta-data of their package any -string they want, and push a new release at PyPI. This version will appear -as the `latest` for end users. - -Some project are also using dates as their major version numbers, or a custom -versioning standard that is sometimes quite exotic. - -The problem with this freedom is that the package will be harder to re-package -for OS packagers, that need to have stricter conventions. The worst case is -when a packager is unable to easily compare the versions he needs to package. +Furthermore, this will make OS packagers work easier when repackaging standards +compliant distributions, as of now it can be difficult to decide how two +distribution versions compare. + + +Requisites and current status +============================= + +It is not in the scope of this PEP to come with an universal versioning schema, +intented to support many or all existing versioning schemas. There will always +be competing grammars, either mandated by distro or project policies or by +historical reasons and we cannot expect that to change. + +The proposed schema should be able to express the usual versioning semantics, +so it's possible to parse any alternative versioning schema and transform it +into a compliant one. This is how OS packagers usually deal with the existing +version schemas and is a preferable alternative than supporting an arbitrary +set of versioning schemas. + +Conformance to usual practice and conventions, as well as a simplicity are a +plus, to ease frictionless adoption and painless transition. Practicality beats +purity, sometimes. + +Projects have very different versioning needs, but the following are widely +considered important semantics: + +1. there should be possible to express more than one versioning level + (usually this is expressed as major and minor revision and, sometimes, + also a micro revision). +2. most projects need special meaning versions for "pre-releases" (such as + "alpha", "beta", "rc"), and these have widely used aliases ("a" stands + for "alpha", "b" for "beta" and "c" for "rc"). +3. some projects also need "post-releases" of regular versions, + mainly for installer work which can't be clearly expressed otherwise. +4. development versions allow packagers of unreleased work to avoid version + clash with later regular releases. For people that want to go further and use a tool to manage their version numbers, the two major ones are: @@ -120,6 +137,11 @@ >>> v1 > v2 False +The problem with this is that while it allows expressing requisite any +nesting level it doesn't allow to express special meaning versions +(pre and post-releases as well as development versions), as expressed in +requisites 2, 3 and 4. + The `StrictVersion` class is more strict. From the doc:: Version numbering for meticulous retentive and software idealists. @@ -166,13 +188,12 @@ >>> v2 < v3 True -Although, it lacks a few elements to make it usable: +It adds pre-release versions, and some structure, but lacks a few semantic +elements to make it usable, such as development releases or post-release tags, +as expressed in requisites 3 and 4. -- development releases -- post-release tags -- development releases of post-release tags. +Also, notice that Distutils version classes are not really used in the community. -Notice that Distutils version classes are not really used in the community. Setuptools ---------- @@ -226,13 +247,18 @@ >>> V('FunkyVersion') ('*funkyversion', '*final') +In this schema practicality takes priority over purity, but as a result it +doesn't enforce any policy and leads to very complex semantics due to the lack +of a clear standard. It just tries to adapt to widely used conventions. + Caveats of existing systems --------------------------- The major problem with the described version comparison tools is that they are -too permissive. Many of the versions on PyPI [#pypi]_ are obviously not useful -versions, which makes it difficult for users to grok the versioning that a -particular package was using and to provide tools on top of PyPI. +too permissive and, at the same time, aren't capable of expressing some of the +required semantics. Many of the versions on PyPI [#pypi]_ are obviously not +useful versions, which makes it difficult for users to grok the versioning that +a particular package was using and to provide tools on top of PyPI. Distutils classes are not really used in Python projects, but the Setuptools function is quite spread because it's used by tools like @@ -273,6 +299,7 @@ ... < V('1.0a2.1') ... < V('1.0b1.dev456') ... < V('1.0b2') + ... < V('1.0b2.post345') ... < V('1.0c1.dev456') ... < V('1.0c1') ... < V('1.0.dev456') @@ -355,38 +382,41 @@ suggestion - 3474 (81.04%) match when using this suggestion method -When a tool needs to work with versions, the best strategy is to use +When a tool needs to work with versions, a strategy is to use ``suggest_rational_version`` on the versions string. If this function returns ``None``, it means that the provided version is not close enough to the -standard scheme:: +standard scheme. If it returns a version that slighlty differs from +the original version, it's a suggested rational version. Last, if it +returns the same string, it means that the version matches the scheme. + +Here's an example of usage :: >>> from verlib import suggest_rational_version, RationalVersion + >>> import warnings >>> def validate_version(version): ... rversion = suggest_rational_version(version) ... if rversion is None: ... raise ValueError('Cannot work with "%s"' % version) + ... if rversion != version: + ... warnings.warn('"%s" is not a rational version, ' + ... 'it has been transformed into "%s" ' + ... 'for interoperability.' % (version, rversion)) ... return RationalVersion(rversion) ... >>> validate_version('2.4rc1') + __main__:8: UserWarning: "2.4rc1" is not a rational version, it has been transformed into "2.4c1" for interoperability. + RationalVersion('2.4c1') + + >>> validate_version('2.4c1') RationalVersion('2.4c1') >>> validate_version('foo') Traceback (most recent call last): - ... + File "", line 1, in + File "", line 4, in validate_version ValueError: Cannot work with "foo" - >>> validate_version('1.24.33') - RationalVersion('1.24.33') - - >>> validate_version('1.24.330pre1') - RationalVersion('1.24.330c1') - - >>> validate_version('2008.12.11') - Traceback (most recent call last): - ... - ValueError: Cannot work with "2008.12.11" - Roadmap ======= From python-checkins at python.org Wed Dec 2 23:45:03 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Dec 2009 22:45:03 -0000 Subject: [Python-checkins] r76639 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Wed Dec 2 23:45:03 2009 New Revision: 76639 Log: fixed typo Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Wed Dec 2 23:45:03 2009 @@ -40,7 +40,7 @@ version is superior to ``3.5.0``. This also means that Python projects will need to follow the same convention -than the tool that will be used to install them, so they are able to compare +as the tool that will be used to install them, so they are able to compare versions. That is why this PEP proposes, for the sake of interoperability, a standard From solipsis at pitrou.net Thu Dec 3 00:47:32 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 3 Dec 2009 00:47:32 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76637): sum=20 Message-ID: <20091202234732.E0B3F1771F@ns6635.ovh.net> py3k results for svn r76637 (hg cset 51beb6105e05) -------------------------------------------------- test_urllib leaked [12, 4, 4] references, sum=20 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogu3Lhi4', '-x', 'test_httpservers'] From python-checkins at python.org Thu Dec 3 03:25:54 2009 From: python-checkins at python.org (philip.jenvey) Date: Thu, 03 Dec 2009 02:25:54 -0000 Subject: [Python-checkins] r76640 - python/trunk/Doc/library/subprocess.rst Message-ID: Author: philip.jenvey Date: Thu Dec 3 03:25:54 2009 New Revision: 76640 Log: #7177: clarify the potential PIPE deadlock warnings 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 Dec 3 03:25:54 2009 @@ -166,9 +166,10 @@ .. warning:: - Like :meth:`Popen.wait`, this will deadlock if the child process - generates enough output to a stdout or stderr pipe such that it blocks - waiting for the OS pipe buffer to accept more data. + Like :meth:`Popen.wait`, this will deadlock when using + ``stdout=PIPE`` and/or ``stderr=PIPE`` and the child process + generates enough output to a pipe such that it blocks waiting + for the OS pipe buffer to accept more data. .. function:: check_call(*popenargs, **kwargs) @@ -260,9 +261,10 @@ .. warning:: - This will deadlock if the child process generates enough output to a - stdout or stderr pipe such that it blocks waiting for the OS pipe buffer - to accept more data. Use :meth:`communicate` to avoid that. + This will deadlock when using ``stdout=PIPE`` and/or + ``stderr=PIPE`` and the child process generates enough output to + a pipe such that it blocks waiting for the OS pipe buffer to + accept more data. Use :meth:`communicate` to avoid that. .. method:: Popen.communicate(input=None) From python-checkins at python.org Thu Dec 3 03:29:36 2009 From: python-checkins at python.org (philip.jenvey) Date: Thu, 03 Dec 2009 02:29:36 -0000 Subject: [Python-checkins] r76641 - in python/branches/py3k: Doc/library/subprocess.rst Message-ID: Author: philip.jenvey Date: Thu Dec 3 03:29:36 2009 New Revision: 76641 Log: Merged revisions 76640 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76640 | philip.jenvey | 2009-12-02 18:25:54 -0800 (Wed, 02 Dec 2009) | 2 lines #7177: clarify the potential PIPE deadlock warnings ........ 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 Dec 3 03:29:36 2009 @@ -161,9 +161,10 @@ .. warning:: - Like :meth:`Popen.wait`, this will deadlock if the child process - generates enough output to a stdout or stderr pipe such that it blocks - waiting for the OS pipe buffer to accept more data. + Like :meth:`Popen.wait`, this will deadlock when using + ``stdout=PIPE`` and/or ``stderr=PIPE`` and the child process + generates enough output to a pipe such that it blocks waiting + for the OS pipe buffer to accept more data. .. function:: check_call(*popenargs, **kwargs) @@ -286,9 +287,10 @@ .. warning:: - This will deadlock if the child process generates enough output to a - stdout or stderr pipe such that it blocks waiting for the OS pipe buffer - to accept more data. Use :meth:`communicate` to avoid that. + This will deadlock when using ``stdout=PIPE`` and/or + ``stderr=PIPE`` and the child process generates enough output to + a pipe such that it blocks waiting for the OS pipe buffer to + accept more data. Use :meth:`communicate` to avoid that. .. method:: Popen.communicate(input=None) From python-checkins at python.org Thu Dec 3 03:40:13 2009 From: python-checkins at python.org (philip.jenvey) Date: Thu, 03 Dec 2009 02:40:13 -0000 Subject: [Python-checkins] r76642 - python/trunk/Lib/urllib.py Message-ID: Author: philip.jenvey Date: Thu Dec 3 03:40:13 2009 New Revision: 76642 Log: actually close files Modified: python/trunk/Lib/urllib.py Modified: python/trunk/Lib/urllib.py ============================================================================== --- python/trunk/Lib/urllib.py (original) +++ python/trunk/Lib/urllib.py Thu Dec 3 03:40:13 2009 @@ -231,7 +231,7 @@ try: fp = self.open_local_file(url1) hdrs = fp.info() - del fp + fp.close() return url2pathname(splithost(url1)[1]), hdrs except IOError, msg: pass @@ -275,8 +275,6 @@ tfp.close() finally: fp.close() - del fp - del tfp # raise exception if actual size does not match content-length header if size >= 0 and read < size: @@ -1570,9 +1568,8 @@ print '======' for k in h.keys(): print k + ':', h[k] print '======' - fp = open(fn, 'rb') - data = fp.read() - del fp + with open(fn, 'rb') as fp: + data = fp.read() if '\r' in data: table = string.maketrans("", "") data = data.translate(table, "\r") From python-checkins at python.org Thu Dec 3 03:45:01 2009 From: python-checkins at python.org (philip.jenvey) Date: Thu, 03 Dec 2009 02:45:01 -0000 Subject: [Python-checkins] r76643 - in python/branches/py3k: Lib/urllib/request.py Message-ID: Author: philip.jenvey Date: Thu Dec 3 03:45:01 2009 New Revision: 76643 Log: Recorded merge of revisions 76642 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76642 | philip.jenvey | 2009-12-02 18:40:13 -0800 (Wed, 02 Dec 2009) | 1 line actually close files ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/urllib/request.py Modified: python/branches/py3k/Lib/urllib/request.py ============================================================================== --- python/branches/py3k/Lib/urllib/request.py (original) +++ python/branches/py3k/Lib/urllib/request.py Thu Dec 3 03:45:01 2009 @@ -1471,7 +1471,7 @@ try: fp = self.open_local_file(url1) hdrs = fp.info() - del fp + fp.close() return url2pathname(splithost(url1)[1]), hdrs except IOError as msg: pass @@ -1515,8 +1515,6 @@ tfp.close() finally: fp.close() - del fp - del tfp # raise exception if actual size does not match content-length header if size >= 0 and read < size: From python-checkins at python.org Thu Dec 3 03:52:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 03 Dec 2009 02:52:40 -0000 Subject: [Python-checkins] r76644 - in python/trunk: Misc/NEWS Objects/obmalloc.c configure configure.in pyconfig.h.in Message-ID: Author: benjamin.peterson Date: Thu Dec 3 03:52:39 2009 New Revision: 76644 Log: disable pymalloc tricks with the --with-valgrind option #2422 Patch from James Henstridge. Modified: python/trunk/Misc/NEWS python/trunk/Objects/obmalloc.c python/trunk/configure python/trunk/configure.in python/trunk/pyconfig.h.in Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Dec 3 03:52:39 2009 @@ -487,6 +487,11 @@ - Issue #3739: The unicode-internal encoder now reports the number of characters consumed like any other encoder (instead of the number of bytes). +- Issue #2422: When compiled with the ``--with-valgrind`` option, the + pymalloc allocator will be automatically disabled when running under + Valgrind. This gives improved memory leak detection when running + under Valgrind, while taking advantage of pymalloc at other times. + Library ------- Modified: python/trunk/Objects/obmalloc.c ============================================================================== --- python/trunk/Objects/obmalloc.c (original) +++ python/trunk/Objects/obmalloc.c Thu Dec 3 03:52:39 2009 @@ -2,6 +2,21 @@ #ifdef WITH_PYMALLOC +#ifdef WITH_VALGRIND +#include + +/* If we're using GCC, use __builtin_expect() to reduce overhead of + the valgrind checks */ +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) +# define UNLIKELY(value) __builtin_expect((value), 0) +#else +# define UNLIKELY(value) (value) +#endif + +/* -1 indicates that we haven't checked that we're running on valgrind yet. */ +static int running_on_valgrind = -1; +#endif + /* An object allocator for Python. Here is an introduction to the layers of the Python memory architecture, @@ -728,6 +743,13 @@ poolp next; uint size; +#ifdef WITH_VALGRIND + if (UNLIKELY(running_on_valgrind == -1)) + running_on_valgrind = RUNNING_ON_VALGRIND; + if (UNLIKELY(running_on_valgrind)) + goto redirect; +#endif + /* * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes. * Most python internals blindly use a signed Py_ssize_t to track @@ -927,6 +949,11 @@ if (p == NULL) /* free(NULL) has no effect */ return; +#ifdef WITH_VALGRIND + if (UNLIKELY(running_on_valgrind > 0)) + goto redirect; +#endif + pool = POOL_ADDR(p); if (Py_ADDRESS_IN_RANGE(p, pool)) { /* We allocated this address. */ @@ -1121,6 +1148,9 @@ return; } +#ifdef WITH_VALGRIND +redirect: +#endif /* We didn't allocate this address. */ free(p); } @@ -1150,6 +1180,12 @@ if (nbytes > PY_SSIZE_T_MAX) return NULL; +#ifdef WITH_VALGRIND + /* Treat running_on_valgrind == -1 the same as 0 */ + if (UNLIKELY(running_on_valgrind > 0)) + goto redirect; +#endif + pool = POOL_ADDR(p); if (Py_ADDRESS_IN_RANGE(p, pool)) { /* We're in charge of this block */ @@ -1177,6 +1213,9 @@ } return bp; } +#ifdef WITH_VALGRIND + redirect: +#endif /* We're not managing this block. If nbytes <= * SMALL_REQUEST_THRESHOLD, it's tempting to try to take over this * block. However, if we do, we need to copy the valid data from Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Thu Dec 3 03:52:39 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76568 . +# From configure.in Revision: 76636 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -1362,6 +1362,7 @@ --with(out)-doc-strings disable/enable documentation strings --with(out)-tsc enable/disable timestamp counter profile --with(out)-pymalloc disable/enable specialized mallocs + --with-valgrind Enable Valgrind support --with-wctype-functions use wctype.h functions --with-fpectl enable SIGFPE catching --with-libm=STRING math library @@ -17616,6 +17617,166 @@ { echo "$as_me:$LINENO: result: $with_pymalloc" >&5 echo "${ECHO_T}$with_pymalloc" >&6; } +# Check for Valgrind support +{ echo "$as_me:$LINENO: checking for --with-valgrind" >&5 +echo $ECHO_N "checking for --with-valgrind... $ECHO_C" >&6; } + +# Check whether --with-valgrind was given. +if test "${with_valgrind+set}" = set; then + withval=$with_valgrind; +else + with_valgrind=no +fi + +{ echo "$as_me:$LINENO: result: $with_valgrind" >&5 +echo "${ECHO_T}$with_valgrind" >&6; } +if test "$with_valgrind" != no; then + if test "${ac_cv_header_valgrind_valgrind_h+set}" = set; then + { echo "$as_me:$LINENO: checking for valgrind/valgrind.h" >&5 +echo $ECHO_N "checking for valgrind/valgrind.h... $ECHO_C" >&6; } +if test "${ac_cv_header_valgrind_valgrind_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_valgrind_valgrind_h" >&5 +echo "${ECHO_T}$ac_cv_header_valgrind_valgrind_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking valgrind/valgrind.h usability" >&5 +echo $ECHO_N "checking valgrind/valgrind.h usability... $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. */ +$ac_includes_default +#include +_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 + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking valgrind/valgrind.h presence" >&5 +echo $ECHO_N "checking valgrind/valgrind.h presence... $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. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +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_cpp conftest.$ac_ext") 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); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## -------------------------------------- ## +## Report this to http://bugs.python.org/ ## +## -------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for valgrind/valgrind.h" >&5 +echo $ECHO_N "checking for valgrind/valgrind.h... $ECHO_C" >&6; } +if test "${ac_cv_header_valgrind_valgrind_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_valgrind_valgrind_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_valgrind_valgrind_h" >&5 +echo "${ECHO_T}$ac_cv_header_valgrind_valgrind_h" >&6; } + +fi +if test $ac_cv_header_valgrind_valgrind_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define WITH_VALGRIND 1 +_ACEOF + +else + { { echo "$as_me:$LINENO: error: Valgrind support requested but headers not available" >&5 +echo "$as_me: error: Valgrind support requested but headers not available" >&2;} + { (exit 1); exit 1; }; } + +fi + + +fi + # Check for --with-wctype-functions { echo "$as_me:$LINENO: checking for --with-wctype-functions" >&5 echo $ECHO_N "checking for --with-wctype-functions... $ECHO_C" >&6; } Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Thu Dec 3 03:52:39 2009 @@ -2472,6 +2472,19 @@ fi AC_MSG_RESULT($with_pymalloc) +# Check for Valgrind support +AC_MSG_CHECKING([for --with-valgrind]) +AC_ARG_WITH([valgrind], + AC_HELP_STRING([--with-valgrind], [Enable Valgrind support]),, + with_valgrind=no) +AC_MSG_RESULT([$with_valgrind]) +if test "$with_valgrind" != no; then + AC_CHECK_HEADER([valgrind/valgrind.h], + [AC_DEFINE([WITH_VALGRIND], 1, [Define if you want pymalloc to be disabled when running under valgrind])], + [AC_MSG_ERROR([Valgrind support requested but headers not available])] + ) +fi + # Check for --with-wctype-functions AC_MSG_CHECKING(for --with-wctype-functions) AC_ARG_WITH(wctype-functions, Modified: python/trunk/pyconfig.h.in ============================================================================== --- python/trunk/pyconfig.h.in (original) +++ python/trunk/pyconfig.h.in Thu Dec 3 03:52:39 2009 @@ -301,9 +301,6 @@ /* Define to 1 if you have the `getpeername' function. */ #undef HAVE_GETPEERNAME -/* Define to 1 if you have the `initgroups' function. */ -#undef HAVE_INITGROUPS - /* Define to 1 if you have the `getpgid' function. */ #undef HAVE_GETPGID @@ -358,6 +355,9 @@ /* Define if you have the 'inet_pton' function. */ #undef HAVE_INET_PTON +/* Define to 1 if you have the `initgroups' function. */ +#undef HAVE_INITGROUPS + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -1061,6 +1061,9 @@ /* Define to profile with the Pentium timestamp counter */ #undef WITH_TSC +/* Define if you want pymalloc to be disabled when running under valgrind */ +#undef WITH_VALGRIND + /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN From python-checkins at python.org Thu Dec 3 04:01:27 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 03 Dec 2009 03:01:27 -0000 Subject: [Python-checkins] r76645 - in python/branches/py3k: Misc/NEWS Objects/obmalloc.c configure configure.in pyconfig.h.in Message-ID: Author: benjamin.peterson Date: Thu Dec 3 04:01:27 2009 New Revision: 76645 Log: Merged revisions 76644 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76644 | benjamin.peterson | 2009-12-02 20:52:39 -0600 (Wed, 02 Dec 2009) | 4 lines disable pymalloc tricks with the --with-valgrind option #2422 Patch from James Henstridge. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/obmalloc.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 3 04:01:27 2009 @@ -143,6 +143,11 @@ ``const char *`` as the string is stored beyond the call. +- Issue #2422: When compiled with the ``--with-valgrind`` option, the + pymalloc allocator will be automatically disabled when running under + Valgrind. This gives improved memory leak detection when running + under Valgrind, while taking advantage of pymalloc at other times. + Library ------- Modified: python/branches/py3k/Objects/obmalloc.c ============================================================================== --- python/branches/py3k/Objects/obmalloc.c (original) +++ python/branches/py3k/Objects/obmalloc.c Thu Dec 3 04:01:27 2009 @@ -2,6 +2,21 @@ #ifdef WITH_PYMALLOC +#ifdef WITH_VALGRIND +#include + +/* If we're using GCC, use __builtin_expect() to reduce overhead of + the valgrind checks */ +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) +# define UNLIKELY(value) __builtin_expect((value), 0) +#else +# define UNLIKELY(value) (value) +#endif + +/* -1 indicates that we haven't checked that we're running on valgrind yet. */ +static int running_on_valgrind = -1; +#endif + /* An object allocator for Python. Here is an introduction to the layers of the Python memory architecture, @@ -728,6 +743,13 @@ poolp next; uint size; +#ifdef WITH_VALGRIND + if (UNLIKELY(running_on_valgrind == -1)) + running_on_valgrind = RUNNING_ON_VALGRIND; + if (UNLIKELY(running_on_valgrind)) + goto redirect; +#endif + /* * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes. * Most python internals blindly use a signed Py_ssize_t to track @@ -927,6 +949,11 @@ if (p == NULL) /* free(NULL) has no effect */ return; +#ifdef WITH_VALGRIND + if (UNLIKELY(running_on_valgrind > 0)) + goto redirect; +#endif + pool = POOL_ADDR(p); if (Py_ADDRESS_IN_RANGE(p, pool)) { /* We allocated this address. */ @@ -1121,6 +1148,9 @@ return; } +#ifdef WITH_VALGRIND +redirect: +#endif /* We didn't allocate this address. */ free(p); } @@ -1150,6 +1180,12 @@ if (nbytes > PY_SSIZE_T_MAX) return NULL; +#ifdef WITH_VALGRIND + /* Treat running_on_valgrind == -1 the same as 0 */ + if (UNLIKELY(running_on_valgrind > 0)) + goto redirect; +#endif + pool = POOL_ADDR(p); if (Py_ADDRESS_IN_RANGE(p, pool)) { /* We're in charge of this block */ @@ -1177,6 +1213,9 @@ } return bp; } +#ifdef WITH_VALGRIND + redirect: +#endif /* We're not managing this block. If nbytes <= * SMALL_REQUEST_THRESHOLD, it's tempting to try to take over this * block. However, if we do, we need to copy the valid data from Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Thu Dec 3 04:01:27 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76566 . +# From configure.in Revision: 76637 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -1355,6 +1355,7 @@ --with(out)-doc-strings disable/enable documentation strings --with(out)-tsc enable/disable timestamp counter profile --with(out)-pymalloc disable/enable specialized mallocs + --with-valgrind Enable Valgrind support --with-wctype-functions use wctype.h functions --with-fpectl enable SIGFPE catching --with-libm=STRING math library @@ -17107,6 +17108,166 @@ { echo "$as_me:$LINENO: result: $with_pymalloc" >&5 echo "${ECHO_T}$with_pymalloc" >&6; } +# Check for Valgrind support +{ echo "$as_me:$LINENO: checking for --with-valgrind" >&5 +echo $ECHO_N "checking for --with-valgrind... $ECHO_C" >&6; } + +# Check whether --with-valgrind was given. +if test "${with_valgrind+set}" = set; then + withval=$with_valgrind; +else + with_valgrind=no +fi + +{ echo "$as_me:$LINENO: result: $with_valgrind" >&5 +echo "${ECHO_T}$with_valgrind" >&6; } +if test "$with_valgrind" != no; then + if test "${ac_cv_header_valgrind_valgrind_h+set}" = set; then + { echo "$as_me:$LINENO: checking for valgrind/valgrind.h" >&5 +echo $ECHO_N "checking for valgrind/valgrind.h... $ECHO_C" >&6; } +if test "${ac_cv_header_valgrind_valgrind_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_valgrind_valgrind_h" >&5 +echo "${ECHO_T}$ac_cv_header_valgrind_valgrind_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking valgrind/valgrind.h usability" >&5 +echo $ECHO_N "checking valgrind/valgrind.h usability... $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. */ +$ac_includes_default +#include +_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 + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking valgrind/valgrind.h presence" >&5 +echo $ECHO_N "checking valgrind/valgrind.h presence... $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. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +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_cpp conftest.$ac_ext") 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); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: valgrind/valgrind.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: valgrind/valgrind.h: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## -------------------------------------- ## +## Report this to http://bugs.python.org/ ## +## -------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for valgrind/valgrind.h" >&5 +echo $ECHO_N "checking for valgrind/valgrind.h... $ECHO_C" >&6; } +if test "${ac_cv_header_valgrind_valgrind_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_valgrind_valgrind_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_valgrind_valgrind_h" >&5 +echo "${ECHO_T}$ac_cv_header_valgrind_valgrind_h" >&6; } + +fi +if test $ac_cv_header_valgrind_valgrind_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define WITH_VALGRIND 1 +_ACEOF + +else + { { echo "$as_me:$LINENO: error: Valgrind support requested but headers not available" >&5 +echo "$as_me: error: Valgrind support requested but headers not available" >&2;} + { (exit 1); exit 1; }; } + +fi + + +fi + # Check for --with-wctype-functions { echo "$as_me:$LINENO: checking for --with-wctype-functions" >&5 echo $ECHO_N "checking for --with-wctype-functions... $ECHO_C" >&6; } Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Thu Dec 3 04:01:27 2009 @@ -2345,6 +2345,19 @@ fi AC_MSG_RESULT($with_pymalloc) +# Check for Valgrind support +AC_MSG_CHECKING([for --with-valgrind]) +AC_ARG_WITH([valgrind], + AC_HELP_STRING([--with-valgrind], [Enable Valgrind support]),, + with_valgrind=no) +AC_MSG_RESULT([$with_valgrind]) +if test "$with_valgrind" != no; then + AC_CHECK_HEADER([valgrind/valgrind.h], + [AC_DEFINE([WITH_VALGRIND], 1, [Define if you want pymalloc to be disabled when running under valgrind])], + [AC_MSG_ERROR([Valgrind support requested but headers not available])] + ) +fi + # Check for --with-wctype-functions AC_MSG_CHECKING(for --with-wctype-functions) AC_ARG_WITH(wctype-functions, Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Thu Dec 3 04:01:27 2009 @@ -299,9 +299,6 @@ /* Define to 1 if you have the `getpeername' function. */ #undef HAVE_GETPEERNAME -/* Define to 1 if you have the `initgroups' function. */ -#undef HAVE_INITGROUPS - /* Define to 1 if you have the `getpgid' function. */ #undef HAVE_GETPGID @@ -356,6 +353,9 @@ /* Define if you have the 'inet_pton' function. */ #undef HAVE_INET_PTON +/* Define to 1 if you have the `initgroups' function. */ +#undef HAVE_INITGROUPS + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -1065,6 +1065,9 @@ /* Define to profile with the Pentium timestamp counter */ #undef WITH_TSC +/* Define if you want pymalloc to be disabled when running under valgrind */ +#undef WITH_VALGRIND + /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN From python-checkins at python.org Thu Dec 3 11:59:46 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 03 Dec 2009 10:59:46 -0000 Subject: [Python-checkins] r76646 - in python/branches/py3k: Misc/NEWS Modules/_testcapimodule.c Python/getargs.c Message-ID: Author: mark.dickinson Date: Thu Dec 3 11:59:46 2009 New Revision: 76646 Log: Issue #7414: Add missing 'case 'C'' to skipitem() in getargs.c. This was causing PyArg_ParseTupleAndKeywords(args, kwargs, "|CC", ...) to fail with a RuntimeError. Thanks Case Van Horsen for tracking down the source of this error. Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_testcapimodule.c python/branches/py3k/Python/getargs.c Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 3 11:59:46 2009 @@ -121,6 +121,9 @@ C-API ----- +- Issue #7414: 'C' code wasn't being skipped properly (for keyword arguments) + in PyArg_ParseTupleAndKeywords. + - Issue #Add '%lld' and '%llu' support to PyString_FromFormat(V) and PyErr_Format, on machines with HAVE_LONG_LONG defined. Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Thu Dec 3 11:59:46 2009 @@ -616,6 +616,52 @@ Py_RETURN_NONE; } +static PyObject * +test_bug_7414(PyObject *self) +{ + /* Issue #7414: for PyArg_ParseTupleAndKeywords, 'C' code wasn't being + skipped properly in skipitem() */ + int a = 0, b = 0, result; + char *kwlist[] = {"a", "b", NULL}; + PyObject *tuple = NULL, *dict = NULL, *b_str; + + tuple = PyTuple_New(0); + if (tuple == NULL) + goto failure; + dict = PyDict_New(); + if (dict == NULL) + goto failure; + b_str = PyUnicode_FromString("b"); + if (b_str == NULL) + goto failure; + result = PyDict_SetItemString(dict, "b", b_str); + Py_DECREF(b_str); + if (result < 0) + goto failure; + + result = PyArg_ParseTupleAndKeywords(tuple, dict, "|CC", + kwlist, &a, &b); + if (!result) + goto failure; + + if (a != 0) + return raiseTestError("test_bug_7414", + "C format code not skipped properly"); + if (b != 'b') + return raiseTestError("test_bug_7414", + "C format code returned wrong value"); + + Py_DECREF(dict); + Py_DECREF(tuple); + Py_RETURN_NONE; + + failure: + Py_XDECREF(dict); + Py_XDECREF(tuple); + return NULL; +} + + static volatile int x; /* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case @@ -1477,6 +1523,7 @@ {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, + {"test_bug_7414", (PyCFunction)test_bug_7414, METH_NOARGS}, {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS}, {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, {"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS, Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Thu Dec 3 11:59:46 2009 @@ -1772,6 +1772,7 @@ case 'd': /* double */ case 'D': /* complex double */ case 'c': /* char */ + case 'C': /* unicode char */ { (void) va_arg(*p_va, void *); break; From python-checkins at python.org Thu Dec 3 12:01:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 03 Dec 2009 11:01:53 -0000 Subject: [Python-checkins] r76647 - in python/branches/release31-maint: Misc/NEWS Modules/_testcapimodule.c Python/getargs.c Message-ID: Author: mark.dickinson Date: Thu Dec 3 12:01:53 2009 New Revision: 76647 Log: Merged revisions 76646 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76646 | mark.dickinson | 2009-12-03 10:59:46 +0000 (Thu, 03 Dec 2009) | 6 lines Issue #7414: Add missing 'case 'C'' to skipitem() in getargs.c. This was causing PyArg_ParseTupleAndKeywords(args, kwargs, "|CC", ...) to fail with a RuntimeError. Thanks Case Van Horsen for tracking down the source of this error. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/_testcapimodule.c python/branches/release31-maint/Python/getargs.c Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Dec 3 12:01:53 2009 @@ -270,6 +270,9 @@ C-API ----- +- Issue #7414: 'C' code wasn't being skipped properly (for keyword arguments) + in PyArg_ParseTupleAndKeywords. + - Issue #6624: yArg_ParseTuple with "s" format when parsing argument with NUL: Bogus TypeError detail string. Modified: python/branches/release31-maint/Modules/_testcapimodule.c ============================================================================== --- python/branches/release31-maint/Modules/_testcapimodule.c (original) +++ python/branches/release31-maint/Modules/_testcapimodule.c Thu Dec 3 12:01:53 2009 @@ -616,6 +616,52 @@ Py_RETURN_NONE; } +static PyObject * +test_bug_7414(PyObject *self) +{ + /* Issue #7414: for PyArg_ParseTupleAndKeywords, 'C' code wasn't being + skipped properly in skipitem() */ + int a = 0, b = 0, result; + char *kwlist[] = {"a", "b", NULL}; + PyObject *tuple = NULL, *dict = NULL, *b_str; + + tuple = PyTuple_New(0); + if (tuple == NULL) + goto failure; + dict = PyDict_New(); + if (dict == NULL) + goto failure; + b_str = PyUnicode_FromString("b"); + if (b_str == NULL) + goto failure; + result = PyDict_SetItemString(dict, "b", b_str); + Py_DECREF(b_str); + if (result < 0) + goto failure; + + result = PyArg_ParseTupleAndKeywords(tuple, dict, "|CC", + kwlist, &a, &b); + if (!result) + goto failure; + + if (a != 0) + return raiseTestError("test_bug_7414", + "C format code not skipped properly"); + if (b != 'b') + return raiseTestError("test_bug_7414", + "C format code returned wrong value"); + + Py_DECREF(dict); + Py_DECREF(tuple); + Py_RETURN_NONE; + + failure: + Py_XDECREF(dict); + Py_XDECREF(tuple); + return NULL; +} + + static volatile int x; /* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case @@ -1457,6 +1503,7 @@ {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, + {"test_bug_7414", (PyCFunction)test_bug_7414, METH_NOARGS}, {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS}, {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, {"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS, Modified: python/branches/release31-maint/Python/getargs.c ============================================================================== --- python/branches/release31-maint/Python/getargs.c (original) +++ python/branches/release31-maint/Python/getargs.c Thu Dec 3 12:01:53 2009 @@ -1776,6 +1776,7 @@ case 'D': /* complex double */ #endif case 'c': /* char */ + case 'C': /* unicode char */ { (void) va_arg(*p_va, void *); break; From python-checkins at python.org Thu Dec 3 13:08:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 03 Dec 2009 12:08:56 -0000 Subject: [Python-checkins] r76648 - python/trunk/Python/bltinmodule.c Message-ID: Author: mark.dickinson Date: Thu Dec 3 13:08:56 2009 New Revision: 76648 Log: Issue #6985: number of range() items should be constrained to lie in a Py_ssize_t, not an int. Modified: python/trunk/Python/bltinmodule.c Modified: python/trunk/Python/bltinmodule.c ============================================================================== --- python/trunk/Python/bltinmodule.c (original) +++ python/trunk/Python/bltinmodule.c Thu Dec 3 13:08:56 2009 @@ -1754,7 +1754,7 @@ PyObject *curnum = NULL; PyObject *v = NULL; long bign; - int i, n; + Py_ssize_t i, n; int cmp_result; PyObject *zero = PyLong_FromLong(0); @@ -1834,7 +1834,7 @@ Py_DECREF(neg_istep); } - n = (int)bign; + n = (Py_ssize_t)bign; if (bign < 0 || (long)n != bign) { PyErr_SetString(PyExc_OverflowError, "range() result has too many items"); @@ -1914,7 +1914,7 @@ { long ilow = 0, ihigh = 0, istep = 1; long bign; - int i, n; + Py_ssize_t i, n; PyObject *v; @@ -1943,7 +1943,7 @@ bign = get_len_of_range(ilow, ihigh, istep); else bign = get_len_of_range(ihigh, ilow, -istep); - n = (int)bign; + n = (Py_ssize_t)bign; if (bign < 0 || (long)n != bign) { PyErr_SetString(PyExc_OverflowError, "range() result has too many items"); From python-checkins at python.org Thu Dec 3 13:09:33 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 03 Dec 2009 12:09:33 -0000 Subject: [Python-checkins] r76649 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Thu Dec 3 13:09:33 2009 New Revision: 76649 Log: Blocked revisions 76648 via svnmerge ........ r76648 | mark.dickinson | 2009-12-03 12:08:56 +0000 (Thu, 03 Dec 2009) | 3 lines Issue #6985: number of range() items should be constrained to lie in a Py_ssize_t, not an int. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Dec 3 13:10:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 03 Dec 2009 12:10:00 -0000 Subject: [Python-checkins] r76650 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Thu Dec 3 13:10:00 2009 New Revision: 76650 Log: Blocked revisions 76648 via svnmerge ........ r76648 | mark.dickinson | 2009-12-03 12:08:56 +0000 (Thu, 03 Dec 2009) | 3 lines Issue #6985: number of range() items should be constrained to lie in a Py_ssize_t, not an int. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Dec 3 21:53:51 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 03 Dec 2009 20:53:51 -0000 Subject: [Python-checkins] r76651 - in python/trunk: Lib/distutils/msvc9compiler.py Misc/NEWS Message-ID: Author: martin.v.loewis Date: Thu Dec 3 21:53:51 2009 New Revision: 76651 Log: Issue #4120: Drop reference to CRT from manifest when building extensions with msvc9compiler. Modified: python/trunk/Lib/distutils/msvc9compiler.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/msvc9compiler.py ============================================================================== --- python/trunk/Lib/distutils/msvc9compiler.py (original) +++ python/trunk/Lib/distutils/msvc9compiler.py Thu Dec 3 21:53:51 2009 @@ -17,6 +17,7 @@ import os import subprocess import sys +import re from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ CompileError, LibError, LinkError @@ -646,6 +647,28 @@ mfid = 1 else: mfid = 2 + try: + # Remove references to the Visual C runtime, so they will + # fall through to the Visual C dependency of Python.exe. + # This way, when installed for a restricted user (e.g. + # runtimes are not in WinSxS folder, but in Python's own + # folder), the runtimes do not need to be in every folder + # with .pyd's. + manifest_f = open(temp_manifest, "rb") + manifest_buf = manifest_f.read() + manifest_f.close() + pattern = re.compile( + r"""|)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "\s*" + manifest_buf = re.sub(pattern, "", manifest_buf) + manifest_f = open(temp_manifest, "wb") + manifest_f.write(manifest_buf) + manifest_f.close() + except IOError: + pass out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Dec 3 21:53:51 2009 @@ -495,6 +495,9 @@ Library ------- +- Issue #4120: Drop reference to CRT from manifest when building extensions with + msvc9compiler. + - Issue #7333: The `posix` module gains an `initgroups()` function providing access to the initgroups(3) C library call on Unix systems which implement it. Patch by Jean-Paul Calderone. From python-checkins at python.org Thu Dec 3 21:56:16 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 03 Dec 2009 20:56:16 -0000 Subject: [Python-checkins] r76652 - in python/branches/release26-maint: Lib/distutils/msvc9compiler.py Misc/NEWS Message-ID: Author: martin.v.loewis Date: Thu Dec 3 21:56:15 2009 New Revision: 76652 Log: Merged revisions 76651 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76651 | martin.v.loewis | 2009-12-03 21:53:51 +0100 (Do, 03 Dez 2009) | 3 lines Issue #4120: Drop reference to CRT from manifest when building extensions with msvc9compiler. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/msvc9compiler.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/distutils/msvc9compiler.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/msvc9compiler.py (original) +++ python/branches/release26-maint/Lib/distutils/msvc9compiler.py Thu Dec 3 21:56:15 2009 @@ -17,6 +17,7 @@ import os import subprocess import sys +import re from distutils.errors import (DistutilsExecError, DistutilsPlatformError, CompileError, LibError, LinkError) from distutils.ccompiler import (CCompiler, gen_preprocess_options, @@ -641,7 +642,32 @@ # will still consider the DLL up-to-date, but it will not have a # manifest. Maybe we should link to a temp file? OTOH, that # implies a build environment error that shouldn't go undetected. - mfid = 1 if target_desc == CCompiler.EXECUTABLE else 2 + if target_desc == CCompiler.EXECUTABLE: + mfid = 1 + else: + mfid = 2 + try: + # Remove references to the Visual C runtime, so they will + # fall through to the Visual C dependency of Python.exe. + # This way, when installed for a restricted user (e.g. + # runtimes are not in WinSxS folder, but in Python's own + # folder), the runtimes do not need to be in every folder + # with .pyd's. + manifest_f = open(temp_manifest, "rb") + manifest_buf = manifest_f.read() + manifest_f.close() + pattern = re.compile( + r"""|)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "\s*" + manifest_buf = re.sub(pattern, "", manifest_buf) + manifest_f = open(temp_manifest, "wb") + manifest_f.write(manifest_buf) + manifest_f.close() + except IOError: + pass out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Dec 3 21:56:15 2009 @@ -33,6 +33,9 @@ Library ------- +- Issue #4120: Drop reference to CRT from manifest when building extensions with + msvc9compiler. + - Issue #7410: deepcopy of itertools.count() erroneously reset the count. - Issue #7403: logging: Fixed possible race condition in lock creation. From python-checkins at python.org Thu Dec 3 21:57:49 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 03 Dec 2009 20:57:49 -0000 Subject: [Python-checkins] r76653 - in python/branches/py3k: Lib/distutils/msvc9compiler.py Misc/NEWS Message-ID: Author: martin.v.loewis Date: Thu Dec 3 21:57:49 2009 New Revision: 76653 Log: Merged revisions 76651 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76651 | martin.v.loewis | 2009-12-03 21:53:51 +0100 (Do, 03 Dez 2009) | 3 lines Issue #4120: Drop reference to CRT from manifest when building extensions with msvc9compiler. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/msvc9compiler.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/msvc9compiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/msvc9compiler.py (original) +++ python/branches/py3k/Lib/distutils/msvc9compiler.py Thu Dec 3 21:57:49 2009 @@ -17,6 +17,7 @@ import os import subprocess import sys +import re from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ CompileError, LibError, LinkError @@ -645,6 +646,28 @@ mfid = 1 else: mfid = 2 + try: + # Remove references to the Visual C runtime, so they will + # fall through to the Visual C dependency of Python.exe. + # This way, when installed for a restricted user (e.g. + # runtimes are not in WinSxS folder, but in Python's own + # folder), the runtimes do not need to be in every folder + # with .pyd's. + manifest_f = open(temp_manifest, "rb") + manifest_buf = manifest_f.read() + manifest_f.close() + pattern = re.compile( + r"""|)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "\s*" + manifest_buf = re.sub(pattern, "", manifest_buf) + manifest_f = open(temp_manifest, "wb") + manifest_f.write(manifest_buf) + manifest_f.close() + except IOError: + pass out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 3 21:57:49 2009 @@ -154,6 +154,9 @@ Library ------- +- Issue #4120: Drop reference to CRT from manifest when building extensions with + msvc9compiler. + - Issue #7333: The `posix` module gains an `initgroups()` function providing access to the initgroups(3) C library call on Unix systems which implement it. Patch by Jean-Paul Calderone. From python-checkins at python.org Thu Dec 3 21:59:58 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 03 Dec 2009 20:59:58 -0000 Subject: [Python-checkins] r76654 - in python/tags/r311: Lib/distutils/msvc9compiler.py Misc/NEWS Message-ID: Author: martin.v.loewis Date: Thu Dec 3 21:59:57 2009 New Revision: 76654 Log: Merged revisions 76653 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76653 | martin.v.loewis | 2009-12-03 21:57:49 +0100 (Do, 03 Dez 2009) | 10 lines Merged revisions 76651 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76651 | martin.v.loewis | 2009-12-03 21:53:51 +0100 (Do, 03 Dez 2009) | 3 lines Issue #4120: Drop reference to CRT from manifest when building extensions with msvc9compiler. ........ ................ Modified: python/tags/r311/ (props changed) python/tags/r311/Lib/distutils/msvc9compiler.py python/tags/r311/Misc/NEWS Modified: python/tags/r311/Lib/distutils/msvc9compiler.py ============================================================================== --- python/tags/r311/Lib/distutils/msvc9compiler.py (original) +++ python/tags/r311/Lib/distutils/msvc9compiler.py Thu Dec 3 21:59:57 2009 @@ -17,6 +17,7 @@ import os import subprocess import sys +import re from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ CompileError, LibError, LinkError @@ -645,6 +646,28 @@ mfid = 1 else: mfid = 2 + try: + # Remove references to the Visual C runtime, so they will + # fall through to the Visual C dependency of Python.exe. + # This way, when installed for a restricted user (e.g. + # runtimes are not in WinSxS folder, but in Python's own + # folder), the runtimes do not need to be in every folder + # with .pyd's. + manifest_f = open(temp_manifest, "rb") + manifest_buf = manifest_f.read() + manifest_f.close() + pattern = re.compile( + r"""|)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "\s*" + manifest_buf = re.sub(pattern, "", manifest_buf) + manifest_f = open(temp_manifest, "wb") + manifest_f.write(manifest_buf) + manifest_f.close() + except IOError: + pass out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', Modified: python/tags/r311/Misc/NEWS ============================================================================== --- python/tags/r311/Misc/NEWS (original) +++ python/tags/r311/Misc/NEWS Thu Dec 3 21:59:57 2009 @@ -47,6 +47,9 @@ Library ------- +- Issue #4120: Drop reference to CRT from manifest when building extensions with + msvc9compiler. + - Issue #6106: telnetlib.Telnet.process_rawq doesn't handle default WILL/WONT DO/DONT correctly. From python-checkins at python.org Thu Dec 3 22:01:16 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 03 Dec 2009 21:01:16 -0000 Subject: [Python-checkins] r76655 - python/trunk/Misc/ACKS Message-ID: Author: martin.v.loewis Date: Thu Dec 3 22:01:16 2009 New Revision: 76655 Log: Add Christoph Gohlke, for the issue 4120 work. Modified: python/trunk/Misc/ACKS Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Thu Dec 3 22:01:16 2009 @@ -275,6 +275,7 @@ Jonathan Giddy Johannes Gijsbers Michael Gilfix +Christoph Gohlke Tim Golden Chris Gonnerman David Goodger From python-checkins at python.org Thu Dec 3 22:01:55 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 03 Dec 2009 21:01:55 -0000 Subject: [Python-checkins] r76656 - in python/branches/py3k: Misc/ACKS Message-ID: Author: martin.v.loewis Date: Thu Dec 3 22:01:55 2009 New Revision: 76656 Log: Merged revisions 76655 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76655 | martin.v.loewis | 2009-12-03 22:01:16 +0100 (Do, 03 Dez 2009) | 2 lines Add Christoph Gohlke, for the issue 4120 work. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/ACKS Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Thu Dec 3 22:01:55 2009 @@ -275,6 +275,7 @@ Jonathan Giddy Johannes Gijsbers Michael Gilfix +Christoph Gohlke Tim Golden Chris Gonnerman David Goodger From python-checkins at python.org Thu Dec 3 22:11:41 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 03 Dec 2009 21:11:41 -0000 Subject: [Python-checkins] r76657 - in python/tags/r311: Lib/distutils/msvc9compiler.py Misc/NEWS Message-ID: Author: martin.v.loewis Date: Thu Dec 3 22:11:40 2009 New Revision: 76657 Log: Restore tag. Modified: python/tags/r311/ (props changed) python/tags/r311/Lib/distutils/msvc9compiler.py python/tags/r311/Misc/NEWS Modified: python/tags/r311/Lib/distutils/msvc9compiler.py ============================================================================== --- python/tags/r311/Lib/distutils/msvc9compiler.py (original) +++ python/tags/r311/Lib/distutils/msvc9compiler.py Thu Dec 3 22:11:40 2009 @@ -17,7 +17,6 @@ import os import subprocess import sys -import re from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ CompileError, LibError, LinkError @@ -646,28 +645,6 @@ mfid = 1 else: mfid = 2 - try: - # Remove references to the Visual C runtime, so they will - # fall through to the Visual C dependency of Python.exe. - # This way, when installed for a restricted user (e.g. - # runtimes are not in WinSxS folder, but in Python's own - # folder), the runtimes do not need to be in every folder - # with .pyd's. - manifest_f = open(temp_manifest, "rb") - manifest_buf = manifest_f.read() - manifest_f.close() - pattern = re.compile( - r"""|)""", - re.DOTALL) - manifest_buf = re.sub(pattern, "", manifest_buf) - pattern = "\s*" - manifest_buf = re.sub(pattern, "", manifest_buf) - manifest_f = open(temp_manifest, "wb") - manifest_f.write(manifest_buf) - manifest_f.close() - except IOError: - pass out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', Modified: python/tags/r311/Misc/NEWS ============================================================================== --- python/tags/r311/Misc/NEWS (original) +++ python/tags/r311/Misc/NEWS Thu Dec 3 22:11:40 2009 @@ -47,9 +47,6 @@ Library ------- -- Issue #4120: Drop reference to CRT from manifest when building extensions with - msvc9compiler. - - Issue #6106: telnetlib.Telnet.process_rawq doesn't handle default WILL/WONT DO/DONT correctly. From python-checkins at python.org Thu Dec 3 22:14:10 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 03 Dec 2009 21:14:10 -0000 Subject: [Python-checkins] r76658 - in python/branches/release31-maint: Lib/distutils/msvc9compiler.py Misc/NEWS Message-ID: Author: martin.v.loewis Date: Thu Dec 3 22:14:10 2009 New Revision: 76658 Log: Merged revisions 76653 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76653 | martin.v.loewis | 2009-12-03 21:57:49 +0100 (Do, 03 Dez 2009) | 10 lines Merged revisions 76651 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76651 | martin.v.loewis | 2009-12-03 21:53:51 +0100 (Do, 03 Dez 2009) | 3 lines Issue #4120: Drop reference to CRT from manifest when building extensions with msvc9compiler. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/distutils/msvc9compiler.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/distutils/msvc9compiler.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/msvc9compiler.py (original) +++ python/branches/release31-maint/Lib/distutils/msvc9compiler.py Thu Dec 3 22:14:10 2009 @@ -17,6 +17,7 @@ import os import subprocess import sys +import re from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ CompileError, LibError, LinkError @@ -645,6 +646,28 @@ mfid = 1 else: mfid = 2 + try: + # Remove references to the Visual C runtime, so they will + # fall through to the Visual C dependency of Python.exe. + # This way, when installed for a restricted user (e.g. + # runtimes are not in WinSxS folder, but in Python's own + # folder), the runtimes do not need to be in every folder + # with .pyd's. + manifest_f = open(temp_manifest, "rb") + manifest_buf = manifest_f.read() + manifest_f.close() + pattern = re.compile( + r"""|)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "\s*" + manifest_buf = re.sub(pattern, "", manifest_buf) + manifest_f = open(temp_manifest, "wb") + manifest_f.write(manifest_buf) + manifest_f.close() + except IOError: + pass out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Dec 3 22:14:10 2009 @@ -55,6 +55,9 @@ Library ------- +- Issue #4120: Drop reference to CRT from manifest when building extensions with + msvc9compiler. + - Issue #7410: deepcopy of itertools.count was resetting the count. - Issue #4486: When an exception has an explicit cause, do not print its From solipsis at pitrou.net Fri Dec 4 00:47:21 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 4 Dec 2009 00:47:21 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76656): sum=10 Message-ID: <20091203234721.8828B17722@ns6635.ovh.net> py3k results for svn r76656 (hg cset 5a511dc112d7) -------------------------------------------------- test_cmd_line leaked [-29, 29, 0] references, sum=0 test_urllib leaked [2, 6, 2] references, sum=10 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogDCyqiw', '-x', 'test_httpservers'] From python-checkins at python.org Fri Dec 4 00:58:00 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 03 Dec 2009 23:58:00 -0000 Subject: [Python-checkins] r76659 - in python/trunk: Lib/test/test_linecache.py Misc/NEWS Message-ID: Author: r.david.murray Date: Fri Dec 4 00:57:59 2009 New Revision: 76659 Log: Issue 7431: use TESTFN in test_linecache instead of trying to create a file in the Lib/test directory, which might be read-only for the user running the tests. Modified: python/trunk/Lib/test/test_linecache.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_linecache.py ============================================================================== --- python/trunk/Lib/test/test_linecache.py (original) +++ python/trunk/Lib/test/test_linecache.py Fri Dec 4 00:57:59 2009 @@ -83,44 +83,40 @@ getline = linecache.getline try: # Create a source file and cache its contents - source_name = os.path.join(TEST_PATH, 'linecache_test.py') - source = open(source_name, 'w') - source.write(SOURCE_1) - source.close() - getline(source_name, 1) - - # Keep a copy of the old contents - source_list = [] - source = open(source_name) - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) - source.close() - - source = open(source_name, 'w') - source.write(SOURCE_2) - source.close() - - # Try to update a bogus cache entry - linecache.checkcache('dummy') - - # Check that the cache matches the old contents - for index, line in enumerate(source_list): - self.assertEquals(line, getline(source_name, index + 1)) - - # Update the cache and check whether it matches the new source file - linecache.checkcache(source_name) - source = open(source_name) - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) - source.close() + source_name = support.TESTFN + '.py' + with open(source_name, 'w') as source: + source.write(SOURCE_1) + source.close() + getline(source_name, 1) - finally: - try: + # Keep a copy of the old contents + source_list = [] + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + source.close() + + source = open(source_name, 'w') + source.write(SOURCE_2) source.close() - finally: - support.unlink(source_name) + + # Try to update a bogus cache entry + linecache.checkcache('dummy') + + # Check that the cache matches the old contents + for index, line in enumerate(source_list): + self.assertEquals(line, getline(source_name, index + 1)) + + # Update the cache and check whether it matches the new source file + linecache.checkcache(source_name) + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + + finally: + support.unlink(source_name) def test_main(): support.run_unittest(LineCacheTests) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Dec 4 00:57:59 2009 @@ -1695,6 +1695,10 @@ Tests ----- +- Issue #7431: use TESTFN in test_linecache instead of trying to create a + file in the Lib/test directory, which might be read-only for the + user running the tests. + - Issue #7324: add a sanity check to regrtest argument parsing to catch the case of an option with no handler. From python-checkins at python.org Fri Dec 4 01:01:31 2009 From: python-checkins at python.org (r.david.murray) Date: Fri, 04 Dec 2009 00:01:31 -0000 Subject: [Python-checkins] r76660 - in python/branches/release26-maint: Lib/test/test_linecache.py Misc/NEWS Message-ID: Author: r.david.murray Date: Fri Dec 4 01:01:31 2009 New Revision: 76660 Log: Merged revisions 76659 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76659 | r.david.murray | 2009-12-03 18:57:59 -0500 (Thu, 03 Dec 2009) | 4 lines Issue 7431: use TESTFN in test_linecache instead of trying to create a file in the Lib/test directory, which might be read-only for the user running the tests. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_linecache.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/test/test_linecache.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_linecache.py (original) +++ python/branches/release26-maint/Lib/test/test_linecache.py Fri Dec 4 01:01:31 2009 @@ -83,44 +83,40 @@ getline = linecache.getline try: # Create a source file and cache its contents - source_name = os.path.join(TEST_PATH, 'linecache_test.py') - source = open(source_name, 'w') - source.write(SOURCE_1) - source.close() - getline(source_name, 1) - - # Keep a copy of the old contents - source_list = [] - source = open(source_name) - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) - source.close() - - source = open(source_name, 'w') - source.write(SOURCE_2) - source.close() - - # Try to update a bogus cache entry - linecache.checkcache('dummy') - - # Check that the cache matches the old contents - for index, line in enumerate(source_list): - self.assertEquals(line, getline(source_name, index + 1)) - - # Update the cache and check whether it matches the new source file - linecache.checkcache(source_name) - source = open(source_name) - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) - source.close() + source_name = support.TESTFN + '.py' + with open(source_name, 'w') as source: + source.write(SOURCE_1) + source.close() + getline(source_name, 1) - finally: - try: + # Keep a copy of the old contents + source_list = [] + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + source.close() + + source = open(source_name, 'w') + source.write(SOURCE_2) source.close() - finally: - support.unlink(source_name) + + # Try to update a bogus cache entry + linecache.checkcache('dummy') + + # Check that the cache matches the old contents + for index, line in enumerate(source_list): + self.assertEquals(line, getline(source_name, index + 1)) + + # Update the cache and check whether it matches the new source file + linecache.checkcache(source_name) + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + + finally: + support.unlink(source_name) def test_main(): support.run_unittest(LineCacheTests) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Fri Dec 4 01:01:31 2009 @@ -101,6 +101,10 @@ Tests ----- +- Issue #7431: use TESTFN in test_linecache instead of trying to create a + file in the Lib/test directory, which might be read-only for the + user running the tests. + - Issue #7324: add a sanity check to regrtest argument parsing to catch the case of an option with no handler. From python-checkins at python.org Fri Dec 4 01:09:14 2009 From: python-checkins at python.org (r.david.murray) Date: Fri, 04 Dec 2009 00:09:14 -0000 Subject: [Python-checkins] r76661 - in python/branches/py3k: Lib/test/test_linecache.py Misc/NEWS Message-ID: Author: r.david.murray Date: Fri Dec 4 01:09:14 2009 New Revision: 76661 Log: Merged revisions 76659 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76659 | r.david.murray | 2009-12-03 18:57:59 -0500 (Thu, 03 Dec 2009) | 4 lines Issue 7431: use TESTFN in test_linecache instead of trying to create a file in the Lib/test directory, which might be read-only for the user running the tests. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_linecache.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/test_linecache.py ============================================================================== --- python/branches/py3k/Lib/test/test_linecache.py (original) +++ python/branches/py3k/Lib/test/test_linecache.py Fri Dec 4 01:09:14 2009 @@ -83,44 +83,40 @@ getline = linecache.getline try: # Create a source file and cache its contents - source_name = os.path.join(TEST_PATH, 'linecache_test.py') - source = open(source_name, 'w') - source.write(SOURCE_1) - source.close() - getline(source_name, 1) - - # Keep a copy of the old contents - source_list = [] - source = open(source_name) - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) - source.close() - - source = open(source_name, 'w') - source.write(SOURCE_2) - source.close() - - # Try to update a bogus cache entry - linecache.checkcache('dummy') - - # Check that the cache matches the old contents - for index, line in enumerate(source_list): - self.assertEquals(line, getline(source_name, index + 1)) - - # Update the cache and check whether it matches the new source file - linecache.checkcache(source_name) - source = open(source_name) - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) - source.close() + source_name = support.TESTFN + '.py' + with open(source_name, 'w') as source: + source.write(SOURCE_1) + source.close() + getline(source_name, 1) - finally: - try: + # Keep a copy of the old contents + source_list = [] + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + source.close() + + source = open(source_name, 'w') + source.write(SOURCE_2) source.close() - finally: - support.unlink(source_name) + + # Try to update a bogus cache entry + linecache.checkcache('dummy') + + # Check that the cache matches the old contents + for index, line in enumerate(source_list): + self.assertEquals(line, getline(source_name, index + 1)) + + # Update the cache and check whether it matches the new source file + linecache.checkcache(source_name) + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + + finally: + support.unlink(source_name) def test_main(): support.run_unittest(LineCacheTests) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 4 01:09:14 2009 @@ -475,6 +475,10 @@ Tests ----- +- Issue #7431: use TESTFN in test_linecache instead of trying to create a + file in the Lib/test directory, which might be read-only for the + user running the tests. + - Issue #7324: add a sanity check to regrtest argument parsing to catch the case of an option with no handler. From python-checkins at python.org Fri Dec 4 01:13:33 2009 From: python-checkins at python.org (r.david.murray) Date: Fri, 04 Dec 2009 00:13:33 -0000 Subject: [Python-checkins] r76662 - in python/branches/release31-maint: Lib/test/test_linecache.py Misc/NEWS Message-ID: Author: r.david.murray Date: Fri Dec 4 01:13:33 2009 New Revision: 76662 Log: Merged revisions 76661 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76661 | r.david.murray | 2009-12-03 19:09:14 -0500 (Thu, 03 Dec 2009) | 11 lines Merged revisions 76659 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76659 | r.david.murray | 2009-12-03 18:57:59 -0500 (Thu, 03 Dec 2009) | 4 lines Issue 7431: use TESTFN in test_linecache instead of trying to create a file in the Lib/test directory, which might be read-only for the user running the tests. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_linecache.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/test/test_linecache.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_linecache.py (original) +++ python/branches/release31-maint/Lib/test/test_linecache.py Fri Dec 4 01:13:33 2009 @@ -83,44 +83,40 @@ getline = linecache.getline try: # Create a source file and cache its contents - source_name = os.path.join(TEST_PATH, 'linecache_test.py') - source = open(source_name, 'w') - source.write(SOURCE_1) - source.close() - getline(source_name, 1) - - # Keep a copy of the old contents - source_list = [] - source = open(source_name) - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) - source.close() - - source = open(source_name, 'w') - source.write(SOURCE_2) - source.close() - - # Try to update a bogus cache entry - linecache.checkcache('dummy') - - # Check that the cache matches the old contents - for index, line in enumerate(source_list): - self.assertEquals(line, getline(source_name, index + 1)) - - # Update the cache and check whether it matches the new source file - linecache.checkcache(source_name) - source = open(source_name) - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) - source.close() + source_name = support.TESTFN + '.py' + with open(source_name, 'w') as source: + source.write(SOURCE_1) + source.close() + getline(source_name, 1) - finally: - try: + # Keep a copy of the old contents + source_list = [] + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + source.close() + + source = open(source_name, 'w') + source.write(SOURCE_2) source.close() - finally: - support.unlink(source_name) + + # Try to update a bogus cache entry + linecache.checkcache('dummy') + + # Check that the cache matches the old contents + for index, line in enumerate(source_list): + self.assertEquals(line, getline(source_name, index + 1)) + + # Update the cache and check whether it matches the new source file + linecache.checkcache(source_name) + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + + finally: + support.unlink(source_name) def test_main(): support.run_unittest(LineCacheTests) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Dec 4 01:13:33 2009 @@ -192,6 +192,10 @@ Tests ----- +- Issue #7431: use TESTFN in test_linecache instead of trying to create a + file in the Lib/test directory, which might be read-only for the + user running the tests. + - Issue #7324: add a sanity check to regrtest argument parsing to catch the case of an option with no handler. From python-checkins at python.org Fri Dec 4 11:06:06 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 04 Dec 2009 10:06:06 -0000 Subject: [Python-checkins] r76663 - python/branches/py3k/Objects/object.c Message-ID: Author: mark.dickinson Date: Fri Dec 4 11:06:06 2009 New Revision: 76663 Log: Issue #7430: Remove lingering reference to cmp in recursion error message. Modified: python/branches/py3k/Objects/object.c Modified: python/branches/py3k/Objects/object.c ============================================================================== --- python/branches/py3k/Objects/object.c (original) +++ python/branches/py3k/Objects/object.c Fri Dec 4 11:06:06 2009 @@ -603,7 +603,7 @@ PyErr_BadInternalCall(); return NULL; } - if (Py_EnterRecursiveCall(" in cmp")) + if (Py_EnterRecursiveCall(" in comparison")) return NULL; res = do_richcompare(v, w, op); Py_LeaveRecursiveCall(); From python-checkins at python.org Fri Dec 4 11:07:02 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 04 Dec 2009 10:07:02 -0000 Subject: [Python-checkins] r76664 - in python/branches/release31-maint: Objects/object.c Message-ID: Author: mark.dickinson Date: Fri Dec 4 11:07:01 2009 New Revision: 76664 Log: Merged revisions 76663 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76663 | mark.dickinson | 2009-12-04 10:06:06 +0000 (Fri, 04 Dec 2009) | 1 line Issue #7430: Remove lingering reference to cmp in recursion error message. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Objects/object.c Modified: python/branches/release31-maint/Objects/object.c ============================================================================== --- python/branches/release31-maint/Objects/object.c (original) +++ python/branches/release31-maint/Objects/object.c Fri Dec 4 11:07:01 2009 @@ -601,7 +601,7 @@ PyErr_BadInternalCall(); return NULL; } - if (Py_EnterRecursiveCall(" in cmp")) + if (Py_EnterRecursiveCall(" in comparison")) return NULL; res = do_richcompare(v, w, op); Py_LeaveRecursiveCall(); From python-checkins at python.org Fri Dec 4 12:24:38 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 04 Dec 2009 11:24:38 -0000 Subject: [Python-checkins] r76665 - python/trunk/Objects/intobject.c Message-ID: Author: mark.dickinson Date: Fri Dec 4 12:24:38 2009 New Revision: 76665 Log: Avoid undefined behaviour due to overflow in i_divmod (Objects/intobject.c). Modified: python/trunk/Objects/intobject.c Modified: python/trunk/Objects/intobject.c ============================================================================== --- python/trunk/Objects/intobject.c (original) +++ python/trunk/Objects/intobject.c Fri Dec 4 12:24:38 2009 @@ -580,7 +580,16 @@ if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x)) return DIVMOD_OVERFLOW; xdivy = x / y; - xmody = x - xdivy * y; + /* xdiv*y can overflow on platforms where x/y gives floor(x/y) + * for x and y with differing signs. (This is unusual + * behaviour, and C99 prohibits it, but it's allowed by C89; + * for an example of overflow, take x = LONG_MIN, y = 5 or x = + * LONG_MAX, y = -5.) However, x - xdivy*y is always + * representable as a long, since it lies strictly between + * -abs(y) and abs(y). We add casts to avoid intermediate + * overflow. + */ + xmody = (long)(x - (unsigned long)xdivy * y); /* If the signs of x and y differ, and the remainder is non-0, * C89 doesn't define whether xdivy is now the floor or the * ceiling of the infinitely precise quotient. We want the floor, From python-checkins at python.org Fri Dec 4 12:25:30 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 04 Dec 2009 11:25:30 -0000 Subject: [Python-checkins] r76666 - in python/branches/release26-maint: Objects/intobject.c Message-ID: Author: mark.dickinson Date: Fri Dec 4 12:25:29 2009 New Revision: 76666 Log: Merged revisions 76665 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76665 | mark.dickinson | 2009-12-04 11:24:38 +0000 (Fri, 04 Dec 2009) | 2 lines Avoid undefined behaviour due to overflow in i_divmod (Objects/intobject.c). ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Objects/intobject.c Modified: python/branches/release26-maint/Objects/intobject.c ============================================================================== --- python/branches/release26-maint/Objects/intobject.c (original) +++ python/branches/release26-maint/Objects/intobject.c Fri Dec 4 12:25:29 2009 @@ -584,7 +584,16 @@ if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x)) return DIVMOD_OVERFLOW; xdivy = x / y; - xmody = x - xdivy * y; + /* xdiv*y can overflow on platforms where x/y gives floor(x/y) + * for x and y with differing signs. (This is unusual + * behaviour, and C99 prohibits it, but it's allowed by C89; + * for an example of overflow, take x = LONG_MIN, y = 5 or x = + * LONG_MAX, y = -5.) However, x - xdivy*y is always + * representable as a long, since it lies strictly between + * -abs(y) and abs(y). We add casts to avoid intermediate + * overflow. + */ + xmody = (long)(x - (unsigned long)xdivy * y); /* If the signs of x and y differ, and the remainder is non-0, * C89 doesn't define whether xdivy is now the floor or the * ceiling of the infinitely precise quotient. We want the floor, From python-checkins at python.org Fri Dec 4 12:26:07 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 04 Dec 2009 11:26:07 -0000 Subject: [Python-checkins] r76667 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Fri Dec 4 12:26:06 2009 New Revision: 76667 Log: Blocked revisions 76665 via svnmerge ........ r76665 | mark.dickinson | 2009-12-04 11:24:38 +0000 (Fri, 04 Dec 2009) | 2 lines Avoid undefined behaviour due to overflow in i_divmod (Objects/intobject.c). ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Fri Dec 4 12:30:16 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 04 Dec 2009 11:30:16 -0000 Subject: [Python-checkins] r76668 - python/trunk/Misc/NEWS Message-ID: Author: mark.dickinson Date: Fri Dec 4 12:30:16 2009 New Revision: 76668 Log: Add missing issue number in Misc/NEWS entry. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Dec 4 12:30:16 2009 @@ -1576,7 +1576,7 @@ C-API ----- -- Issue #Add '%lld' and '%llu' support to PyString_FromFormat(V) +- Issue #7228: Add '%lld' and '%llu' support to PyString_FromFormat(V) and PyErr_Format, on machines with HAVE_LONG_LONG defined. - Add new C-API function PyOS_string_to_double, and deprecated From python-checkins at python.org Fri Dec 4 12:30:45 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 04 Dec 2009 11:30:45 -0000 Subject: [Python-checkins] r76669 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Fri Dec 4 12:30:45 2009 New Revision: 76669 Log: Blocked revisions 76668 via svnmerge ........ r76668 | mark.dickinson | 2009-12-04 11:30:16 +0000 (Fri, 04 Dec 2009) | 1 line Add missing issue number in Misc/NEWS entry. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Dec 4 12:32:26 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 04 Dec 2009 11:32:26 -0000 Subject: [Python-checkins] r76670 - in python/branches/py3k: Misc/NEWS Message-ID: Author: mark.dickinson Date: Fri Dec 4 12:32:26 2009 New Revision: 76670 Log: Merged revisions 76668 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76668 | mark.dickinson | 2009-12-04 11:30:16 +0000 (Fri, 04 Dec 2009) | 1 line Add missing issue number in Misc/NEWS entry. ........ 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 Fri Dec 4 12:32:26 2009 @@ -124,7 +124,7 @@ - Issue #7414: 'C' code wasn't being skipped properly (for keyword arguments) in PyArg_ParseTupleAndKeywords. -- Issue #Add '%lld' and '%llu' support to PyString_FromFormat(V) +- Issue #7228: Add '%lld' and '%llu' support to PyString_FromFormat(V) and PyErr_Format, on machines with HAVE_LONG_LONG defined. - Issue #6151: Made PyDescr_COMMON conform to standard C (like PyObject_HEAD From python-checkins at python.org Fri Dec 4 12:32:54 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 04 Dec 2009 11:32:54 -0000 Subject: [Python-checkins] r76671 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Fri Dec 4 12:32:54 2009 New Revision: 76671 Log: Blocked revisions 76670 via svnmerge ................ r76670 | mark.dickinson | 2009-12-04 11:32:26 +0000 (Fri, 04 Dec 2009) | 9 lines Merged revisions 76668 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76668 | mark.dickinson | 2009-12-04 11:30:16 +0000 (Fri, 04 Dec 2009) | 1 line Add missing issue number in Misc/NEWS entry. ........ ................ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Sat Dec 5 00:47:39 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 5 Dec 2009 00:47:39 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76670): sum=12 Message-ID: <20091204234739.A479417722@ns6635.ovh.net> py3k results for svn r76670 (hg cset 255adf6a5ca7) -------------------------------------------------- test_urllib leaked [2, 4, 6] references, sum=12 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogF6Rz3u', '-x', 'test_httpservers'] From python-checkins at python.org Sat Dec 5 18:45:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 05 Dec 2009 17:45:40 -0000 Subject: [Python-checkins] r76672 - python/trunk/Lib/pydoc_data/topics.py Message-ID: Author: benjamin.peterson Date: Sat Dec 5 18:45:40 2009 New Revision: 76672 Log: regenerate 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 Sat Dec 5 18:45:40 2009 @@ -1,83 +1,83 @@ -# 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 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', +# Autogenerated by Sphinx on Sat Dec 5 11:45:04 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 Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n ``a.x`` can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target ``a.x`` is\n always set as an instance attribute, creating it if necessary.\n Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n same attribute: if the RHS expression refers to a class attribute,\n the LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield 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**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print x\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', 'atom-identifiers': 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-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 built-in 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* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``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 ::= 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', + '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 same *caveat about\nclass and instance attributes* applies as for regular assignments.\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\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-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\n than once in an effort to acquire as close to *size* bytes as\n possible. Also note that when in non-blocking mode, less data than\n was requested may be returned, even if no *size* parameter was\n given.\n\n Note: This function is simply a wrapper for the underlying ``fread()``\n C 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). [5] 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', + '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\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword. In CPython, this is the case\nfor functions implemented in C that use ``PyArg_ParseTuple()`` to\nparse their arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``*identifier`` is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``**identifier`` is present; in this case, that\nformal parameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax ``*expression`` appears in the function call,\n``expression`` must evaluate to a sequence. Elements from this\nsequence are treated as if they were additional positional arguments;\nif there are positional arguments *x1*,..., *xN*, and ``expression``\nevaluates to a sequence *y1*, ..., *yM*, this is equivalent to a call\nwith M+N positional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the ``*expression`` syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the ``**expression`` argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print a, b\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the ``*expression``\nsyntax to be used in the same call, so in practice this confusion does\nnot arise.\n\nIf the syntax ``**expression`` appears in the function call,\n``expression`` must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both ``expression`` and as an explicit keyword argument,\na ``TypeError`` exception is raised.\n\nFormal parameters using the syntax ``*identifier`` or ``**identifier``\ncannot be used as positional argument slots or as keyword argument\nnames. 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 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 *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', + '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-built-in 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 built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\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__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [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\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" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\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\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n 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 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', + '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()`` built-in; 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\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the ``c`` command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print spam\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print spam\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement[, globals[, 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\nThe ``run_*`` functions and ``set_trace()`` are aliases for\ninstantiating the ``Pdb`` class and calling the method of the same\nname. If you want to access further features, you have to do this\nyourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None)\n\n ``Pdb`` is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying ``cmd.Cmd`` class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 2.7: The *skip* argument.\n\n run(statement[, globals[, locals]])\n runeval(expression[, globals[, locals]])\n runcall(function[, argument, ...])\n set_trace()\n\n See the documentation for the functions explained above.\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', + '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 builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. 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``__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\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the built-in namespace should ``import``\nthe ``__builtin__`` (no \'s\') module and modify its attributes\nappropriately.\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', - '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', + '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 ::= 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 can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\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\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value.\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\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding. This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available 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. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Postive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | 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', + '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**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in 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\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', + '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\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 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 built-in\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-built-in 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 built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\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__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [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'\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", + '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 builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. 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``__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\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the built-in namespace should ``import``\nthe ``__builtin__`` (no 's') module and modify its attributes\nappropriately.\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 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', + '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.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the ``gc`` module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change.\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement 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', + '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 a whitespace character except ``\' \'``, or (3) when the last\nwrite operation on standard output was not a ``print`` statement. (In\nsome cases it may be functional to write an empty string to standard\noutput for this reason.)\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", + '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()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\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 For objects that don't define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n", '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\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', + '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] 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()`` built-in; 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 built-in 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* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``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()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\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 For objects that don\'t define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n\n\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 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', + 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support.\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\n Changed in version 2.7: Support for keyword arguments 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\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\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(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n 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\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 where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\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 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 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', + '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 **CPython implementation detail:** Keys and values are listed in\n an arbitrary order which is non-random, varies across Python\n implementations, and depends on the dictionary\'s history of\n insertions and deletions.\n\n If ``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 ``iterkeys()``\n and ``itervalues()`` methods: ``pairs = zip(d.itervalues(),\n d.iterkeys())`` provides the same value for ``pairs``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n 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 may raise a ``RuntimeError`` or fail to iterate over\n all entries.\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 may raise a ``RuntimeError`` or fail to iterate over\n all entries.\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 may raise a ``RuntimeError`` or fail to iterate over\n all entries.\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 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.\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", + '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 built-in 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. **CPython implementation detail:** If *s* and *t* are both strings,\n some Python implementations such as CPython can usually perform an\n in-place optimization for assignments of the form ``s = s + t`` or\n ``s += t``. When applicable, this optimization makes quadratic\n run-time much less likely. This optimization is both version and\n implementation dependent. For performance sensitive code, it is\n preferable to use the ``str.join()`` method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n 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.\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\n Changed in version 2.7: Support for keyword arguments 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\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\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(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n 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\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 where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\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\nChanged in version 2.7: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\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. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been 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. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\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', + '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" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\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\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', '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 Sat Dec 5 18:46:34 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 05 Dec 2009 17:46:34 -0000 Subject: [Python-checkins] r76673 - in python/trunk/Misc/RPM: python-2.6.spec python-2.7.spec Message-ID: Author: benjamin.peterson Date: Sat Dec 5 18:46:33 2009 New Revision: 76673 Log: move RPM spec for 2.7 Added: python/trunk/Misc/RPM/python-2.7.spec - copied unchanged from r76671, /python/trunk/Misc/RPM/python-2.6.spec Removed: python/trunk/Misc/RPM/python-2.6.spec Deleted: python/trunk/Misc/RPM/python-2.6.spec ============================================================================== --- python/trunk/Misc/RPM/python-2.6.spec Sat Dec 5 18:46:33 2009 +++ (empty file) @@ -1,387 +0,0 @@ -########################## -# User-modifiable configs -########################## - -# Is the resulting package and the installed binary named "python" or -# "python2"? -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_binsuffix none -%define config_binsuffix 2.6 - -# Build tkinter? "auto" enables it if /usr/bin/wish exists. -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_tkinter no -%define config_tkinter yes -%define config_tkinter auto - -# Use pymalloc? The last line (commented or not) determines wether -# pymalloc is used. -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_pymalloc no -%define config_pymalloc yes - -# Enable IPV6? -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_ipv6 yes -%define config_ipv6 no - -# Location of the HTML directory. -%define config_htmldir /var/www/html/python - -################################# -# End of user-modifiable configs -################################# - -%define name python -#--start constants-- -%define version 2.6 -%define libver 2.6 -#--end constants-- -%define release 1pydotorg -%define __prefix /usr - -# kludge to get around rpm define weirdness -%define ipv6 %(if [ "%{config_ipv6}" = yes ]; then echo --enable-ipv6; else echo --disable-ipv6; fi) -%define pymalloc %(if [ "%{config_pymalloc}" = yes ]; then echo --with-pymalloc; else echo --without-pymalloc; fi) -%define binsuffix %(if [ "%{config_binsuffix}" = none ]; then echo ; else echo "%{config_binsuffix}"; fi) -%define include_tkinter %(if [ \\( "%{config_tkinter}" = auto -a -f /usr/bin/wish \\) -o "%{config_tkinter}" = yes ]; then echo 1; else echo 0; fi) -%define libdirname %(( uname -m | egrep -q '_64$' && [ -d /usr/lib64 ] && echo lib64 ) || echo lib) - -# detect if documentation is available -%define include_docs %(if [ -f "%{_sourcedir}/html-%{version}.tar.bz2" ]; then echo 1; else echo 0; fi) - -Summary: An interpreted, interactive, object-oriented programming language. -Name: %{name}%{binsuffix} -Version: %{version} -Release: %{release} -Copyright: Modified CNRI Open Source License -Group: Development/Languages -Source: Python-%{version}.tar.bz2 -%if %{include_docs} -Source1: html-%{version}.tar.bz2 -%endif -BuildRoot: %{_tmppath}/%{name}-%{version}-root -BuildPrereq: expat-devel -BuildPrereq: db4-devel -BuildPrereq: gdbm-devel -BuildPrereq: sqlite-devel -Prefix: %{__prefix} -Packager: Sean Reifschneider - -%description -Python is an interpreted, interactive, object-oriented programming -language. It incorporates modules, exceptions, dynamic typing, very high -level dynamic data types, and classes. Python combines remarkable power -with very clear syntax. It has interfaces to many system calls and -libraries, as well as to various window systems, and is extensible in C or -C++. It is also usable as an extension language for applications that need -a programmable interface. Finally, Python is portable: it runs on many -brands of UNIX, on PCs under Windows, MS-DOS, and OS/2, and on the -Mac. - -%package devel -Summary: The libraries and header files needed for Python extension development. -Prereq: python%{binsuffix} = %{PACKAGE_VERSION} -Group: Development/Libraries - -%description devel -The Python programming language's interpreter can be extended with -dynamically loaded extensions and can be embedded in other programs. -This package contains the header files and libraries needed to do -these types of tasks. - -Install python-devel if you want to develop Python extensions. The -python package will also need to be installed. You'll probably also -want to install the python-docs package, which contains Python -documentation. - -%if %{include_tkinter} -%package tkinter -Summary: A graphical user interface for the Python scripting language. -Group: Development/Languages -Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release} - -%description tkinter -The Tkinter (Tk interface) program is an graphical user interface for -the Python scripting language. - -You should install the tkinter package if you'd like to use a graphical -user interface for Python programming. -%endif - -%package tools -Summary: A collection of development tools included with Python. -Group: Development/Tools -Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release} - -%description tools -The Python package includes several development tools that are used -to build python programs. This package contains a selection of those -tools, including the IDLE Python IDE. - -Install python-tools if you want to use these tools to develop -Python programs. You will also need to install the python and -tkinter packages. - -%if %{include_docs} -%package docs -Summary: Python-related documentation. -Group: Development/Documentation - -%description docs -Documentation relating to the Python programming language in HTML and info -formats. -%endif - -%changelog -* Mon Dec 20 2004 Sean Reifschneider [2.4-2pydotorg] -- Changing the idle wrapper so that it passes arguments to idle. - -* Tue Oct 19 2004 Sean Reifschneider [2.4b1-1pydotorg] -- Updating to 2.4. - -* Thu Jul 22 2004 Sean Reifschneider [2.3.4-3pydotorg] -- Paul Tiemann fixes for %{prefix}. -- Adding permission changes for directory as suggested by reimeika.ca -- Adding code to detect when it should be using lib64. -- Adding a define for the location of /var/www/html for docs. - -* Thu May 27 2004 Sean Reifschneider [2.3.4-2pydotorg] -- Including changes from Ian Holsman to build under Red Hat 7.3. -- Fixing some problems with the /usr/local path change. - -* Sat Mar 27 2004 Sean Reifschneider [2.3.2-3pydotorg] -- Being more agressive about finding the paths to fix for - #!/usr/local/bin/python. - -* Sat Feb 07 2004 Sean Reifschneider [2.3.3-2pydotorg] -- Adding code to remove "#!/usr/local/bin/python" from particular files and - causing the RPM build to terminate if there are any unexpected files - which have that line in them. - -* Mon Oct 13 2003 Sean Reifschneider [2.3.2-1pydotorg] -- Adding code to detect wether documentation is available to build. - -* Fri Sep 19 2003 Sean Reifschneider [2.3.1-1pydotorg] -- Updating to the 2.3.1 release. - -* Mon Feb 24 2003 Sean Reifschneider [2.3b1-1pydotorg] -- Updating to 2.3b1 release. - -* Mon Feb 17 2003 Sean Reifschneider [2.3a1-1] -- Updating to 2.3 release. - -* Sun Dec 23 2001 Sean Reifschneider -[Release 2.2-2] -- Added -docs package. -- Added "auto" config_tkinter setting which only enables tk if - /usr/bin/wish exists. - -* Sat Dec 22 2001 Sean Reifschneider -[Release 2.2-1] -- Updated to 2.2. -- Changed the extension to "2" from "2.2". - -* Tue Nov 18 2001 Sean Reifschneider -[Release 2.2c1-1] -- Updated to 2.2c1. - -* Thu Nov 1 2001 Sean Reifschneider -[Release 2.2b1-3] -- Changed the way the sed for fixing the #! in pydoc works. - -* Wed Oct 24 2001 Sean Reifschneider -[Release 2.2b1-2] -- Fixed missing "email" package, thanks to anonymous report on sourceforge. -- Fixed missing "compiler" package. - -* Mon Oct 22 2001 Sean Reifschneider -[Release 2.2b1-1] -- Updated to 2.2b1. - -* Mon Oct 9 2001 Sean Reifschneider -[Release 2.2a4-4] -- otto at balinor.mat.unimi.it mentioned that the license file is missing. - -* Sun Sep 30 2001 Sean Reifschneider -[Release 2.2a4-3] -- Ignacio Vazquez-Abrams pointed out that I had a spruious double-quote in - the spec files. Thanks. - -* Wed Jul 25 2001 Sean Reifschneider -[Release 2.2a1-1] -- Updated to 2.2a1 release. -- Changed idle and pydoc to use binsuffix macro - -####### -# PREP -####### -%prep -%setup -n Python-%{version} - -######## -# BUILD -######## -%build -./configure --enable-unicode=ucs4 %{ipv6} %{pymalloc} --prefix=%{__prefix} -make - -########## -# INSTALL -########## -%install -# set the install path -echo '[install_scripts]' >setup.cfg -echo 'install_dir='"${RPM_BUILD_ROOT}%{__prefix}/bin" >>setup.cfg - -[ -d "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload -make prefix=$RPM_BUILD_ROOT%{__prefix} install - -# REPLACE PATH IN PYDOC -if [ ! -z "%{binsuffix}" ] -then - ( - cd $RPM_BUILD_ROOT%{__prefix}/bin - mv pydoc pydoc.old - sed 's|#!.*|#!%{__prefix}/bin/env python'%{binsuffix}'|' \ - pydoc.old >pydoc - chmod 755 pydoc - rm -f pydoc.old - ) -fi - -# add the binsuffix -if [ ! -z "%{binsuffix}" ] -then - ( cd $RPM_BUILD_ROOT%{__prefix}/bin; rm -f python[0-9a-zA-Z]*; - mv -f python python"%{binsuffix}" ) - ( cd $RPM_BUILD_ROOT%{__prefix}/man/man1; mv python.1 python%{binsuffix}.1 ) - ( cd $RPM_BUILD_ROOT%{__prefix}/bin; mv -f pydoc pydoc"%{binsuffix}" ) - ( cd $RPM_BUILD_ROOT%{__prefix}/bin; mv -f idle idle"%{binsuffix}" ) -fi - -######## -# Tools -echo '#!%{__prefix}/bin/env python%{binsuffix}' >${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'import os, sys' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'os.execvp("%{__prefix}/bin/python%{binsuffix}", ["%{__prefix}/bin/python%{binsuffix}", "%{__prefix}/lib/python%{libvers}/idlelib/idle.py"] + sys.argv[1:])' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'print "Failed to exec Idle"' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'sys.exit(1)' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -chmod 755 $RPM_BUILD_ROOT%{__prefix}/bin/idle%{binsuffix} -cp -a Tools $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers} - -# MAKE FILE LISTS -rm -f mainpkg.files -find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/lib-dynload -type f | - sed "s|^${RPM_BUILD_ROOT}|/|" | - grep -v -e '_tkinter.so$' >mainpkg.files -find "$RPM_BUILD_ROOT""%{__prefix}"/bin -type f | - sed "s|^${RPM_BUILD_ROOT}|/|" | - grep -v -e '/bin/idle%{binsuffix}$' >>mainpkg.files - -rm -f tools.files -find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/idlelib \ - "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/Tools -type f | - sed "s|^${RPM_BUILD_ROOT}|/|" >tools.files -echo "%{__prefix}"/bin/idle%{binsuffix} >>tools.files - -###### -# Docs -%if %{include_docs} -mkdir -p "$RPM_BUILD_ROOT"%{config_htmldir} -( - cd "$RPM_BUILD_ROOT"%{config_htmldir} - bunzip2 < %{SOURCE1} | tar x -) -%endif - -# fix the #! line in installed files -find "$RPM_BUILD_ROOT" -type f -print0 | - xargs -0 grep -l /usr/local/bin/python | while read file -do - FIXFILE="$file" - sed 's|^#!.*python|#!%{__prefix}/bin/env python'"%{binsuffix}"'|' \ - "$FIXFILE" >/tmp/fix-python-path.$$ - cat /tmp/fix-python-path.$$ >"$FIXFILE" - rm -f /tmp/fix-python-path.$$ -done - -# check to see if there are any straggling #! lines -find "$RPM_BUILD_ROOT" -type f | xargs egrep -n '^#! */usr/local/bin/python' \ - | grep ':1:#!' >/tmp/python-rpm-files.$$ || true -if [ -s /tmp/python-rpm-files.$$ ] -then - echo '*****************************************************' - cat /tmp/python-rpm-files.$$ - cat <<@EOF - ***************************************************** - There are still files referencing /usr/local/bin/python in the - install directory. They are listed above. Please fix the .spec - file and try again. If you are an end-user, you probably want - to report this to jafo-rpms at tummy.com as well. - ***************************************************** - at EOF - rm -f /tmp/python-rpm-files.$$ - exit 1 -fi -rm -f /tmp/python-rpm-files.$$ - -######## -# CLEAN -######## -%clean -[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT -rm -f mainpkg.files tools.files - -######## -# FILES -######## -%files -f mainpkg.files -%defattr(-,root,root) -%doc Misc/README Misc/cheatsheet Misc/Porting -%doc LICENSE Misc/ACKS Misc/HISTORY Misc/NEWS -%{__prefix}/man/man1/python%{binsuffix}.1* - -%attr(755,root,root) %dir %{__prefix}/include/python%{libvers} -%attr(755,root,root) %dir %{__prefix}/%{libdirname}/python%{libvers}/ -%{__prefix}/%{libdirname}/python%{libvers}/*.txt -%{__prefix}/%{libdirname}/python%{libvers}/*.py* -%{__prefix}/%{libdirname}/python%{libvers}/pdb.doc -%{__prefix}/%{libdirname}/python%{libvers}/profile.doc -%{__prefix}/%{libdirname}/python%{libvers}/curses -%{__prefix}/%{libdirname}/python%{libvers}/distutils -%{__prefix}/%{libdirname}/python%{libvers}/encodings -%{__prefix}/%{libdirname}/python%{libvers}/plat-linux2 -%{__prefix}/%{libdirname}/python%{libvers}/site-packages -%{__prefix}/%{libdirname}/python%{libvers}/test -%{__prefix}/%{libdirname}/python%{libvers}/xml -%{__prefix}/%{libdirname}/python%{libvers}/email -%{__prefix}/%{libdirname}/python%{libvers}/email/mime -%{__prefix}/%{libdirname}/python%{libvers}/sqlite3 -%{__prefix}/%{libdirname}/python%{libvers}/compiler -%{__prefix}/%{libdirname}/python%{libvers}/bsddb -%{__prefix}/%{libdirname}/python%{libvers}/hotshot -%{__prefix}/%{libdirname}/python%{libvers}/logging -%{__prefix}/%{libdirname}/python%{libvers}/lib-old - -%files devel -%defattr(-,root,root) -%{__prefix}/include/python%{libvers}/*.h -%{__prefix}/%{libdirname}/python%{libvers}/config - -%files -f tools.files tools -%defattr(-,root,root) - -%if %{include_tkinter} -%files tkinter -%defattr(-,root,root) -%{__prefix}/%{libdirname}/python%{libvers}/lib-tk -%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload/_tkinter.so* -%endif - -%if %{include_docs} -%files docs -%defattr(-,root,root) -%{config_htmldir}/* -%endif From python-checkins at python.org Sat Dec 5 18:47:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 05 Dec 2009 17:47:56 -0000 Subject: [Python-checkins] r76674 - in python/trunk: Include/patchlevel.h Lib/distutils/__init__.py Lib/idlelib/idlever.py Misc/NEWS Misc/RPM/python-2.7.spec README Message-ID: Author: benjamin.peterson Date: Sat Dec 5 18:47:56 2009 New Revision: 76674 Log: bump version to 2.7a1 Modified: python/trunk/Include/patchlevel.h python/trunk/Lib/distutils/__init__.py python/trunk/Lib/idlelib/idlever.py python/trunk/Misc/NEWS python/trunk/Misc/RPM/python-2.7.spec python/trunk/README Modified: python/trunk/Include/patchlevel.h ============================================================================== --- python/trunk/Include/patchlevel.h (original) +++ python/trunk/Include/patchlevel.h Sat Dec 5 18:47:56 2009 @@ -24,10 +24,10 @@ #define PY_MINOR_VERSION 7 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 0 +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "2.7a0" +#define PY_VERSION "2.7a1" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository) */ Modified: python/trunk/Lib/distutils/__init__.py ============================================================================== --- python/trunk/Lib/distutils/__init__.py (original) +++ python/trunk/Lib/distutils/__init__.py Sat Dec 5 18:47:56 2009 @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "2.6" +__version__ = "2.7a1" #--end constants-- Modified: python/trunk/Lib/idlelib/idlever.py ============================================================================== --- python/trunk/Lib/idlelib/idlever.py (original) +++ python/trunk/Lib/idlelib/idlever.py Sat Dec 5 18:47:56 2009 @@ -1 +1 @@ -IDLE_VERSION = "2.7a0" +IDLE_VERSION = "2.7a1" Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Dec 5 18:47:56 2009 @@ -7,7 +7,7 @@ What's New in Python 2.7 alpha 1 ================================ -*Release date: XX-XXX-20XX* +*Release date: 2009-12-04* Core and Builtins ----------------- Modified: python/trunk/Misc/RPM/python-2.7.spec ============================================================================== --- python/trunk/Misc/RPM/python-2.7.spec (original) +++ python/trunk/Misc/RPM/python-2.7.spec Sat Dec 5 18:47:56 2009 @@ -34,8 +34,8 @@ %define name python #--start constants-- -%define version 2.6 -%define libver 2.6 +%define version 2.7a1 +%define libver 2.7 #--end constants-- %define release 1pydotorg %define __prefix /usr Modified: python/trunk/README ============================================================================== --- python/trunk/README (original) +++ python/trunk/README Sat Dec 5 18:47:56 2009 @@ -1,4 +1,4 @@ -This is Python version 2.7 alpha 0 +This is Python version 2.7 alpha 1 ================================== Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 From python-checkins at python.org Sat Dec 5 18:48:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 05 Dec 2009 17:48:36 -0000 Subject: [Python-checkins] r76675 - python/tags/r27a1 Message-ID: Author: benjamin.peterson Date: Sat Dec 5 18:48:36 2009 New Revision: 76675 Log: tag 2.7 alpha 1 Added: python/tags/r27a1/ - copied from r76674, /python/trunk/ From python-checkins at python.org Sat Dec 5 19:40:03 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 05 Dec 2009 18:40:03 -0000 Subject: [Python-checkins] r76676 - in python/trunk: Include/patchlevel.h Misc/NEWS Message-ID: Author: benjamin.peterson Date: Sat Dec 5 19:40:02 2009 New Revision: 76676 Log: post release version bump Modified: python/trunk/Include/patchlevel.h python/trunk/Misc/NEWS Modified: python/trunk/Include/patchlevel.h ============================================================================== --- python/trunk/Include/patchlevel.h (original) +++ python/trunk/Include/patchlevel.h Sat Dec 5 19:40:02 2009 @@ -27,7 +27,7 @@ #define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "2.7a1" +#define PY_VERSION "2.7a1+" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository) */ Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Dec 5 19:40:02 2009 @@ -4,6 +4,18 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) +What's New in Python 2.7 alpha 2? +================================= + +*Release date: XXXX-XX-XX* + +Core and Builtins +----------------- + +Library +------- + + What's New in Python 2.7 alpha 1 ================================ From python-checkins at python.org Sat Dec 5 19:42:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 05 Dec 2009 18:42:10 -0000 Subject: [Python-checkins] r76677 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Sat Dec 5 19:42:10 2009 New Revision: 76677 Log: Blocked revisions 76672-76674,76676 via svnmerge ........ r76672 | benjamin.peterson | 2009-12-05 11:45:40 -0600 (Sat, 05 Dec 2009) | 1 line regenerate pydoc_topics ........ r76673 | benjamin.peterson | 2009-12-05 11:46:33 -0600 (Sat, 05 Dec 2009) | 2 lines move RPM spec for 2.7 ........ r76674 | benjamin.peterson | 2009-12-05 11:47:56 -0600 (Sat, 05 Dec 2009) | 1 line bump version to 2.7a1 ........ r76676 | benjamin.peterson | 2009-12-05 12:40:02 -0600 (Sat, 05 Dec 2009) | 1 line post release version bump ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Dec 5 19:46:43 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 05 Dec 2009 18:46:43 -0000 Subject: [Python-checkins] r76678 - sandbox/trunk/release/release.py Message-ID: Author: benjamin.peterson Date: Sat Dec 5 19:46:43 2009 New Revision: 76678 Log: inserting the current date is rather pointless Modified: sandbox/trunk/release/release.py Modified: sandbox/trunk/release/release.py ============================================================================== --- sandbox/trunk/release/release.py (original) +++ sandbox/trunk/release/release.py Sat Dec 5 19:46:43 2009 @@ -14,7 +14,6 @@ import subprocess import shutil import tempfile -import time from contextlib import contextmanager from string import Template @@ -382,7 +381,7 @@ What's New in Python {XXX PUT NEXT VERSION HERE XXX}? ================================ -*Release date: %s* +*Release date: XXXX-XX-XX* Core and Builtins ----------------- @@ -402,11 +401,9 @@ if line.startswith("What's"): end = i break - release_date = time.strftime("%d-%b-%Y") - insert = NEWS_TEMPLATE % release_date with open('Misc/NEWS', 'w', encoding="utf-8") as fp: fp.writelines(lines[:start+1]) - fp.write(insert) + fp.write(NEWS_TEMPLATE) fp.writelines(lines[end-1:]) print("Please fill in the the name of the next version.") manual_edit('Misc/NEWS') From python-checkins at python.org Sat Dec 5 19:48:13 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 05 Dec 2009 18:48:13 -0000 Subject: [Python-checkins] r76679 - python/trunk/Misc/NEWS Message-ID: Author: benjamin.peterson Date: Sat Dec 5 19:48:13 2009 New Revision: 76679 Log: fix date Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Dec 5 19:48:13 2009 @@ -19,7 +19,7 @@ What's New in Python 2.7 alpha 1 ================================ -*Release date: 2009-12-04* +*Release date: 2009-12-05* Core and Builtins ----------------- From python-checkins at python.org Sat Dec 5 19:51:13 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 05 Dec 2009 18:51:13 -0000 Subject: [Python-checkins] r76680 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Sat Dec 5 19:51:13 2009 New Revision: 76680 Log: Blocked revisions 76679 via svnmerge ........ r76679 | benjamin.peterson | 2009-12-05 12:48:13 -0600 (Sat, 05 Dec 2009) | 1 line fix date ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Dec 5 21:28:35 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 05 Dec 2009 20:28:35 -0000 Subject: [Python-checkins] r76681 - in python/branches/py3k/Lib: random.py test/mapping_tests.py test/pickletester.py test/string_tests.py test/test_binop.py test/test_builtin.py test/test_datetime.py test/test_decimal.py test/test_descr.py test/test_dict.py test/test_getargs2.py test/test_int.py test/test_long.py test/test_types.py Message-ID: Author: mark.dickinson Date: Sat Dec 5 21:28:34 2009 New Revision: 76681 Log: Issue #7435: Remove duplicate int/long tests, and other references to long in py3k. Patch provided by flox. Modified: python/branches/py3k/Lib/random.py python/branches/py3k/Lib/test/mapping_tests.py python/branches/py3k/Lib/test/pickletester.py python/branches/py3k/Lib/test/string_tests.py python/branches/py3k/Lib/test/test_binop.py python/branches/py3k/Lib/test/test_builtin.py python/branches/py3k/Lib/test/test_datetime.py python/branches/py3k/Lib/test/test_decimal.py python/branches/py3k/Lib/test/test_descr.py python/branches/py3k/Lib/test/test_dict.py python/branches/py3k/Lib/test/test_getargs2.py python/branches/py3k/Lib/test/test_int.py python/branches/py3k/Lib/test/test_long.py python/branches/py3k/Lib/test/test_types.py Modified: python/branches/py3k/Lib/random.py ============================================================================== --- python/branches/py3k/Lib/random.py (original) +++ python/branches/py3k/Lib/random.py Sat Dec 5 21:28:34 2009 @@ -97,7 +97,7 @@ None or no argument seeds from current time or from an operating system specific randomness source if available. - If a is not None or an int or long, hash(a) is used instead. + If a is not None or an int, hash(a) is used instead. """ if a is None: Modified: python/branches/py3k/Lib/test/mapping_tests.py ============================================================================== --- python/branches/py3k/Lib/test/mapping_tests.py (original) +++ python/branches/py3k/Lib/test/mapping_tests.py Sat Dec 5 21:28:34 2009 @@ -528,13 +528,6 @@ d = self._empty_mapping() k, v = 'abc', 'def' - # verify longs/ints get same value when key > 32 bits (for 64-bit archs) - # see SF bug #689659 - x = 4503599627370496 - y = 4503599627370496 - h = self._full_mapping({x: 'anything', y: 'something else'}) - self.assertEqual(h[x], h[y]) - self.assertEqual(d.pop(k, v), v) d[k] = v self.assertEqual(d.pop(k, 1), v) Modified: python/branches/py3k/Lib/test/pickletester.py ============================================================================== --- python/branches/py3k/Lib/test/pickletester.py (original) +++ python/branches/py3k/Lib/test/pickletester.py Sat Dec 5 21:28:34 2009 @@ -1041,9 +1041,6 @@ class MyInt(int): sample = 1 -class MyLong(int): - sample = 1 - class MyFloat(float): sample = 1.0 @@ -1065,7 +1062,7 @@ class MyDict(dict): sample = {"a": 1, "b": 2} -myclasses = [MyInt, MyLong, MyFloat, +myclasses = [MyInt, MyFloat, MyComplex, MyStr, MyUnicode, MyTuple, MyList, MyDict] Modified: python/branches/py3k/Lib/test/string_tests.py ============================================================================== --- python/branches/py3k/Lib/test/string_tests.py (original) +++ python/branches/py3k/Lib/test/string_tests.py Sat Dec 5 21:28:34 2009 @@ -1071,7 +1071,6 @@ longvalue = sys.maxsize + 10 slongvalue = str(longvalue) - if slongvalue[-1] in ("L","l"): slongvalue = slongvalue[:-1] self.checkequal(' 42', '%3ld', '__mod__', 42) self.checkequal('42', '%d', '__mod__', 42.0) self.checkequal(slongvalue, '%d', '__mod__', longvalue) @@ -1086,7 +1085,7 @@ self.checkraises(ValueError, '%(foo', '__mod__', {}) self.checkraises(TypeError, '%(foo)s %(bar)s', '__mod__', ('foo', 42)) self.checkraises(TypeError, '%d', '__mod__', "42") # not numeric - self.checkraises(TypeError, '%d', '__mod__', (42+0j)) # no int/long conversion provided + self.checkraises(TypeError, '%d', '__mod__', (42+0j)) # no int conversion provided # argument names with properly nested brackets are supported self.checkequal('bar', '%((foo))s', '__mod__', {'(foo)': 'bar'}) Modified: python/branches/py3k/Lib/test/test_binop.py ============================================================================== --- python/branches/py3k/Lib/test/test_binop.py (original) +++ python/branches/py3k/Lib/test/test_binop.py Sat Dec 5 21:28:34 2009 @@ -11,8 +11,8 @@ return b def isint(x): - """Test whether an object is an instance of int or long.""" - return isinstance(x, int) or isinstance(x, int) + """Test whether an object is an instance of int.""" + return isinstance(x, int) def isnum(x): """Test whether an object is an instance of a built-in numeric type.""" @@ -27,18 +27,18 @@ class Rat(object): - """Rational number implemented as a normalized pair of longs.""" + """Rational number implemented as a normalized pair of ints.""" __slots__ = ['_Rat__num', '_Rat__den'] def __init__(self, num=0, den=1): """Constructor: Rat([num[, den]]). - The arguments must be ints or longs, and default to (0, 1).""" + The arguments must be ints, and default to (0, 1).""" if not isint(num): - raise TypeError("Rat numerator must be int or long (%r)" % num) + raise TypeError("Rat numerator must be int (%r)" % num) if not isint(den): - raise TypeError("Rat denominator must be int or long (%r)" % den) + raise TypeError("Rat denominator must be int (%r)" % den) # But the zero is always on if den == 0: raise ZeroDivisionError("zero denominator") @@ -220,9 +220,6 @@ a = Rat(10, 15) self.assertEqual(a.num, 2) self.assertEqual(a.den, 3) - a = Rat(10, 15) - self.assertEqual(a.num, 2) - self.assertEqual(a.den, 3) a = Rat(10, -15) self.assertEqual(a.num, -2) self.assertEqual(a.den, 3) Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Sat Dec 5 21:28:34 2009 @@ -126,10 +126,6 @@ self.assertEqual(abs(0.0), 0.0) self.assertEqual(abs(3.14), 3.14) self.assertEqual(abs(-3.14), 3.14) - # long - self.assertEqual(abs(0), 0) - self.assertEqual(abs(1234), 1234) - self.assertEqual(abs(-1234), 1234) # str self.assertRaises(TypeError, abs, 'a') @@ -164,7 +160,6 @@ def test_ascii(self): self.assertEqual(ascii(''), '\'\'') self.assertEqual(ascii(0), '0') - self.assertEqual(ascii(0), '0') self.assertEqual(ascii(()), '()') self.assertEqual(ascii([]), '[]') self.assertEqual(ascii({}), '{}') @@ -322,18 +317,7 @@ self.assertEqual(divmod(12, -7), (-2, -2)) self.assertEqual(divmod(-12, -7), (1, -5)) - self.assertEqual(divmod(12, 7), (1, 5)) - self.assertEqual(divmod(-12, 7), (-2, 2)) - self.assertEqual(divmod(12, -7), (-2, -2)) - self.assertEqual(divmod(-12, -7), (1, -5)) - - self.assertEqual(divmod(12, 7), (1, 5)) - self.assertEqual(divmod(-12, 7), (-2, 2)) - self.assertEqual(divmod(12, -7), (-2, -2)) - self.assertEqual(divmod(-12, -7), (1, -5)) - - self.assertEqual(divmod(-sys.maxsize-1, -1), - (sys.maxsize+1, 0)) + self.assertEqual(divmod(-sys.maxsize-1, -1), (sys.maxsize+1, 0)) self.assertTrue(not fcmp(divmod(3.25, 1.0), (3.0, 0.25))) self.assertTrue(not fcmp(divmod(-3.25, 1.0), (-4.0, 0.75))) @@ -528,10 +512,6 @@ def __hash__(self): return 2**100 self.assertEquals(type(hash(X())), int) - class Y(object): - def __hash__(self): - return 2**100 - self.assertEquals(type(hash(Y())), int) class Z(int): def __hash__(self): return self @@ -539,15 +519,12 @@ def test_hex(self): self.assertEqual(hex(16), '0x10') - self.assertEqual(hex(16), '0x10') - self.assertEqual(hex(-16), '-0x10') self.assertEqual(hex(-16), '-0x10') self.assertRaises(TypeError, hex, {}) def test_id(self): id(None) id(1) - id(1) id(1.0) id('spam') id((0,1,2,3)) @@ -790,8 +767,6 @@ def test_oct(self): self.assertEqual(oct(100), '0o144') - self.assertEqual(oct(100), '0o144') - self.assertEqual(oct(-100), '-0o144') self.assertEqual(oct(-100), '-0o144') self.assertRaises(TypeError, oct, ()) @@ -800,7 +775,6 @@ fp = open(TESTFN, 'w') try: fp.write('1+1\n') - fp.write('1+1\n') fp.write('The quick brown fox jumps over the lazy dog') fp.write('.\n') fp.write('Dear John\n') @@ -814,7 +788,6 @@ fp = open(TESTFN, 'r') try: self.assertEqual(fp.readline(4), '1+1\n') - self.assertEqual(fp.readline(4), '1+1\n') self.assertEqual(fp.readline(), 'The quick brown fox jumps over the lazy dog.\n') self.assertEqual(fp.readline(4), 'Dear') self.assertEqual(fp.readline(100), ' John\n') @@ -867,21 +840,6 @@ self.assertEqual(pow(-2,2), 4) self.assertEqual(pow(-2,3), -8) - self.assertEqual(pow(0,0), 1) - self.assertEqual(pow(0,1), 0) - self.assertEqual(pow(1,0), 1) - self.assertEqual(pow(1,1), 1) - - self.assertEqual(pow(2,0), 1) - self.assertEqual(pow(2,10), 1024) - self.assertEqual(pow(2,20), 1024*1024) - self.assertEqual(pow(2,30), 1024*1024*1024) - - self.assertEqual(pow(-2,0), 1) - self.assertEqual(pow(-2,1), -2) - self.assertEqual(pow(-2,2), 4) - self.assertEqual(pow(-2,3), -8) - self.assertAlmostEqual(pow(0.,0), 1.) self.assertAlmostEqual(pow(0.,1), 0.) self.assertAlmostEqual(pow(1.,0), 1.) @@ -897,9 +855,9 @@ self.assertAlmostEqual(pow(-2.,2), 4.) self.assertAlmostEqual(pow(-2.,3), -8.) - for x in 2, 2, 2.0: - for y in 10, 10, 10.0: - for z in 1000, 1000, 1000.0: + for x in 2, 2.0: + for y in 10, 10.0: + for z in 1000, 1000.0: if isinstance(x, float) or \ isinstance(y, float) or \ isinstance(z, float): @@ -912,8 +870,6 @@ self.assertRaises(TypeError, pow, -1, -2, 3) self.assertRaises(ValueError, pow, 1, 2, 0) - self.assertRaises(TypeError, pow, -1, -2, 3) - self.assertRaises(ValueError, pow, 1, 2, 0) self.assertRaises(TypeError, pow) @@ -943,7 +899,6 @@ self.assertEqual(len(x), 4) self.assertEqual(len(list(x)), 4) - """ XXX(nnorwitz): # Now test range() with longs self.assertEqual(list(range(-2**100)), []) self.assertEqual(list(range(0, -2**100)), []) @@ -978,6 +933,7 @@ self.assertRaises(ValueError, range, 1, 2, 0) self.assertRaises(ValueError, range, a, a + 1, int(0)) + """ XXX(nnorwitz): class badzero(int): def __eq__(self, other): raise RuntimeError @@ -1008,7 +964,6 @@ sys.stdin = fp sys.stdout = BitBucket() self.assertEqual(input(), "1+1") - self.assertEqual(input('testing\n'), "1+1") self.assertEqual(input(), 'The quick brown fox jumps over the lazy dog.') self.assertEqual(input('testing\n'), 'Dear John') @@ -1039,7 +994,6 @@ def test_repr(self): self.assertEqual(repr(''), '\'\'') self.assertEqual(repr(0), '0') - self.assertEqual(repr(0), '0') self.assertEqual(repr(()), '()') self.assertEqual(repr([]), '[]') self.assertEqual(repr({}), '{}') Modified: python/branches/py3k/Lib/test/test_datetime.py ============================================================================== --- python/branches/py3k/Lib/test/test_datetime.py (original) +++ python/branches/py3k/Lib/test/test_datetime.py Sat Dec 5 21:28:34 2009 @@ -22,7 +22,7 @@ # An arbitrary collection of objects of non-datetime types, for testing # mixed-type comparisons. -OTHERSTUFF = (10, 10, 34.5, "abc", {}, [], ()) +OTHERSTUFF = (10, 34.5, "abc", {}, [], ()) ############################################################################# @@ -232,8 +232,8 @@ def test_disallowed_computations(self): a = timedelta(42) - # Add/sub ints, longs, floats should be illegal - for i in 1, 1, 1.0: + # Add/sub ints or floats should be illegal + for i in 1, 1.0: self.assertRaises(TypeError, lambda: a+i) self.assertRaises(TypeError, lambda: a-i) self.assertRaises(TypeError, lambda: i+a) @@ -250,9 +250,9 @@ # Division of int by timedelta doesn't make sense. # Division by zero doesn't make sense. - for zero in 0, 0: - self.assertRaises(TypeError, lambda: zero // a) - self.assertRaises(ZeroDivisionError, lambda: a // zero) + zero = 0 + self.assertRaises(TypeError, lambda: zero // a) + self.assertRaises(ZeroDivisionError, lambda: a // zero) def test_basic_attributes(self): days, seconds, us = 1, 7, 31 @@ -685,8 +685,8 @@ self.assertEqual(a - (a - week), week) self.assertEqual(a - (a - day), day) - # Add/sub ints, longs, floats should be illegal - for i in 1, 1, 1.0: + # Add/sub ints or floats should be illegal + for i in 1, 1.0: self.assertRaises(TypeError, lambda: a+i) self.assertRaises(TypeError, lambda: a-i) self.assertRaises(TypeError, lambda: i+a) @@ -1376,8 +1376,8 @@ self.theclass(2002, 2, 22, 16, 5, 59, 999000)) self.assertEqual(a - (week + day + hour + millisec), (((a - week) - day) - hour) - millisec) - # Add/sub ints, longs, floats should be illegal - for i in 1, 1, 1.0: + # Add/sub ints or floats should be illegal + for i in 1, 1.0: self.assertRaises(TypeError, lambda: a+i) self.assertRaises(TypeError, lambda: a-i) self.assertRaises(TypeError, lambda: i+a) Modified: python/branches/py3k/Lib/test/test_decimal.py ============================================================================== --- python/branches/py3k/Lib/test/test_decimal.py (original) +++ python/branches/py3k/Lib/test/test_decimal.py Sat Dec 5 21:28:34 2009 @@ -1274,7 +1274,7 @@ self.assertEqual(repr(d), "Decimal('15.32')") # repr def test_tonum_methods(self): - #Test float, int and long methods. + #Test float and int methods. d1 = Decimal('66') d2 = Decimal('15.32') @@ -1283,10 +1283,6 @@ self.assertEqual(int(d1), 66) self.assertEqual(int(d2), 15) - #long - self.assertEqual(int(d1), 66) - self.assertEqual(int(d2), 15) - #float self.assertEqual(float(d1), 66) self.assertEqual(float(d2), 15.32) 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 Dec 5 21:28:34 2009 @@ -248,10 +248,6 @@ else: self.fail("NotImplemented should have caused TypeError") - def test_longs(self): - # Testing long operations... - self.number_operators(100, 3) - def test_floats(self): # Testing float operations... self.number_operators(100.0, 3.0) @@ -259,7 +255,7 @@ def test_complexes(self): # Testing complex operations... self.number_operators(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge', - 'int', 'long', 'float', + 'int', 'float', 'divmod', 'mod']) class Number(complex): @@ -1162,15 +1158,6 @@ self.assertEqual(I(3)*2, 6) self.assertEqual(I(3)*I(2), 6) - # Test handling of long*seq and seq*long - class L(int): - pass - self.assertEqual("a"*L(2), "aa") - self.assertEqual(L(2)*"a", "aa") - self.assertEqual(2*L(3), 6) - self.assertEqual(L(3)*2, 6) - self.assertEqual(L(3)*L(2), 6) - # Test comparison of classes with dynamic metaclasses class dynamicmetaclass(type): pass @@ -2231,10 +2218,7 @@ class octlong(int): __slots__ = [] def __str__(self): - s = oct(self) - if s[-1] == 'L': - s = s[:-1] - return s + return oct(self) def __add__(self, other): return self.__class__(super(octlong, self).__add__(other)) __radd__ = __add__ Modified: python/branches/py3k/Lib/test/test_dict.py ============================================================================== --- python/branches/py3k/Lib/test/test_dict.py (original) +++ python/branches/py3k/Lib/test/test_dict.py Sat Dec 5 21:28:34 2009 @@ -328,13 +328,6 @@ self.assertRaises(KeyError, d.pop, k) - # verify longs/ints get same value when key > 32 bits (for 64-bit archs) - # see SF bug #689659 - x = 4503599627370496 - y = 4503599627370496 - h = {x: 'anything', y: 'something else'} - self.assertEqual(h[x], h[y]) - self.assertEqual(d.pop(k, v), v) d[k] = v self.assertEqual(d.pop(k, 1), v) Modified: python/branches/py3k/Lib/test/test_getargs2.py ============================================================================== --- python/branches/py3k/Lib/test/test_getargs2.py (original) +++ python/branches/py3k/Lib/test/test_getargs2.py Sat Dec 5 21:28:34 2009 @@ -55,10 +55,6 @@ LLONG_MIN = -2**63 ULLONG_MAX = 2**64-1 -class Long: - def __int__(self): - return 99 - class Int: def __int__(self): return 99 @@ -68,7 +64,6 @@ from _testcapi import getargs_b # b returns 'unsigned char', and does range checking (0 ... UCHAR_MAX) self.assertRaises(TypeError, getargs_b, 3.14) - self.assertEqual(99, getargs_b(Long())) self.assertEqual(99, getargs_b(Int())) self.assertRaises(OverflowError, getargs_b, -1) @@ -77,31 +72,26 @@ self.assertRaises(OverflowError, getargs_b, UCHAR_MAX + 1) self.assertEqual(42, getargs_b(42)) - self.assertEqual(42, getargs_b(42)) self.assertRaises(OverflowError, getargs_b, VERY_LARGE) def test_B(self): from _testcapi import getargs_B # B returns 'unsigned char', no range checking self.assertRaises(TypeError, getargs_B, 3.14) - self.assertEqual(99, getargs_B(Long())) self.assertEqual(99, getargs_B(Int())) self.assertEqual(UCHAR_MAX, getargs_B(-1)) - self.assertEqual(UCHAR_MAX, getargs_B(-1)) self.assertEqual(0, getargs_B(0)) self.assertEqual(UCHAR_MAX, getargs_B(UCHAR_MAX)) self.assertEqual(0, getargs_B(UCHAR_MAX+1)) self.assertEqual(42, getargs_B(42)) - self.assertEqual(42, getargs_B(42)) self.assertEqual(UCHAR_MAX & VERY_LARGE, getargs_B(VERY_LARGE)) def test_H(self): from _testcapi import getargs_H # H returns 'unsigned short', no range checking self.assertRaises(TypeError, getargs_H, 3.14) - self.assertEqual(99, getargs_H(Long())) self.assertEqual(99, getargs_H(Int())) self.assertEqual(USHRT_MAX, getargs_H(-1)) @@ -110,7 +100,6 @@ self.assertEqual(0, getargs_H(USHRT_MAX+1)) self.assertEqual(42, getargs_H(42)) - self.assertEqual(42, getargs_H(42)) self.assertEqual(VERY_LARGE & USHRT_MAX, getargs_H(VERY_LARGE)) @@ -118,7 +107,6 @@ from _testcapi import getargs_I # I returns 'unsigned int', no range checking self.assertRaises(TypeError, getargs_I, 3.14) - self.assertEqual(99, getargs_I(Long())) self.assertEqual(99, getargs_I(Int())) self.assertEqual(UINT_MAX, getargs_I(-1)) @@ -127,7 +115,6 @@ self.assertEqual(0, getargs_I(UINT_MAX+1)) self.assertEqual(42, getargs_I(42)) - self.assertEqual(42, getargs_I(42)) self.assertEqual(VERY_LARGE & UINT_MAX, getargs_I(VERY_LARGE)) @@ -136,7 +123,6 @@ # k returns 'unsigned long', no range checking # it does not accept float, or instances with __int__ self.assertRaises(TypeError, getargs_k, 3.14) - self.assertRaises(TypeError, getargs_k, Long()) self.assertRaises(TypeError, getargs_k, Int()) self.assertEqual(ULONG_MAX, getargs_k(-1)) @@ -145,7 +131,6 @@ self.assertEqual(0, getargs_k(ULONG_MAX+1)) self.assertEqual(42, getargs_k(42)) - self.assertEqual(42, getargs_k(42)) self.assertEqual(VERY_LARGE & ULONG_MAX, getargs_k(VERY_LARGE)) @@ -154,7 +139,6 @@ from _testcapi import getargs_i # i returns 'int', and does range checking (INT_MIN ... INT_MAX) self.assertRaises(TypeError, getargs_i, 3.14) - self.assertEqual(99, getargs_i(Long())) self.assertEqual(99, getargs_i(Int())) self.assertRaises(OverflowError, getargs_i, INT_MIN-1) @@ -163,14 +147,12 @@ self.assertRaises(OverflowError, getargs_i, INT_MAX+1) self.assertEqual(42, getargs_i(42)) - self.assertEqual(42, getargs_i(42)) self.assertRaises(OverflowError, getargs_i, VERY_LARGE) def test_l(self): from _testcapi import getargs_l # l returns 'long', and does range checking (LONG_MIN ... LONG_MAX) self.assertRaises(TypeError, getargs_l, 3.14) - self.assertEqual(99, getargs_l(Long())) self.assertEqual(99, getargs_l(Int())) self.assertRaises(OverflowError, getargs_l, LONG_MIN-1) @@ -179,7 +161,6 @@ self.assertRaises(OverflowError, getargs_l, LONG_MAX+1) self.assertEqual(42, getargs_l(42)) - self.assertEqual(42, getargs_l(42)) self.assertRaises(OverflowError, getargs_l, VERY_LARGE) def test_n(self): @@ -187,7 +168,6 @@ # n returns 'Py_ssize_t', and does range checking # (PY_SSIZE_T_MIN ... PY_SSIZE_T_MAX) self.assertRaises(TypeError, getargs_n, 3.14) - self.assertRaises(TypeError, getargs_n, Long()) self.assertRaises(TypeError, getargs_n, Int()) self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MIN-1) @@ -196,7 +176,6 @@ self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MAX+1) self.assertEqual(42, getargs_n(42)) - self.assertEqual(42, getargs_n(42)) self.assertRaises(OverflowError, getargs_n, VERY_LARGE) @@ -206,7 +185,6 @@ # L returns 'long long', and does range checking (LLONG_MIN ... LLONG_MAX) self.assertRaises(TypeError, getargs_L, "Hello") self.assertEqual(3, getargs_L(3.14)) - self.assertEqual(99, getargs_L(Long())) self.assertEqual(99, getargs_L(Int())) self.assertRaises(OverflowError, getargs_L, LLONG_MIN-1) @@ -215,21 +193,18 @@ self.assertRaises(OverflowError, getargs_L, LLONG_MAX+1) self.assertEqual(42, getargs_L(42)) - self.assertEqual(42, getargs_L(42)) self.assertRaises(OverflowError, getargs_L, VERY_LARGE) def test_K(self): from _testcapi import getargs_K # K return 'unsigned long long', no range checking self.assertRaises(TypeError, getargs_K, 3.14) - self.assertRaises(TypeError, getargs_K, Long()) self.assertRaises(TypeError, getargs_K, Int()) self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX)) self.assertEqual(0, getargs_K(0)) self.assertEqual(0, getargs_K(ULLONG_MAX+1)) self.assertEqual(42, getargs_K(42)) - self.assertEqual(42, getargs_K(42)) self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE)) Modified: python/branches/py3k/Lib/test/test_int.py ============================================================================== --- python/branches/py3k/Lib/test/test_int.py (original) +++ python/branches/py3k/Lib/test/test_int.py Sat Dec 5 21:28:34 2009 @@ -34,6 +34,7 @@ self.assertEqual(int(-3.9), -3) self.assertEqual(int(3.5), 3) self.assertEqual(int(-3.5), -3) + self.assertEqual(int("-3"), -3) # Different base: self.assertEqual(int("10",16), 16) # Test conversion from strings and various anomalies Modified: python/branches/py3k/Lib/test/test_long.py ============================================================================== --- python/branches/py3k/Lib/test/test_long.py (original) +++ python/branches/py3k/Lib/test/test_long.py Sat Dec 5 21:28:34 2009 @@ -35,27 +35,6 @@ # add complements & negations special += [~x for x in special] + [-x for x in special] -L = [ - ('0', 0), - ('1', 1), - ('9', 9), - ('10', 10), - ('99', 99), - ('100', 100), - ('314', 314), - (' 314', 314), - ('314 ', 314), - (' \t\t 314 \t\t ', 314), - (repr(sys.maxsize), sys.maxsize), - (' 1x', ValueError), - (' 1 ', 1), - (' 1\02 ', ValueError), - ('', ValueError), - (' ', ValueError), - (' \t\t ', ValueError) -] - - class LongTest(unittest.TestCase): # Get quasi-random long consisting of ndigits digits (in base BASE). @@ -263,7 +242,7 @@ msg = Frm("%s returned %r but expected %r for %r", mapper.__name__, got, expected, x) self.assertEqual(got, expected, msg) - self.assertEqual(int(got, 0), x, Frm('long("%s", 0) != %r', got, x)) + self.assertEqual(int(got, 0), x, Frm('int("%s", 0) != %r', got, x)) # str() has to be checked a little differently since there's no # trailing "L" got = str(x) @@ -281,25 +260,12 @@ self.check_format_1(x) def test_long(self): - self.assertEqual(int(314), 314) - self.assertEqual(int(3.14), 3) - self.assertEqual(int(314), 314) - # Check that conversion from float truncates towards zero - self.assertEqual(int(-3.14), -3) - self.assertEqual(int(3.9), 3) - self.assertEqual(int(-3.9), -3) - self.assertEqual(int(3.5), 3) - self.assertEqual(int(-3.5), -3) - self.assertEqual(int("-3"), -3) - # Different base: - self.assertEqual(int("10",16), 16) - # Check conversions from string (same test set as for int(), and then some) + # Check conversions from string LL = [ ('1' + '0'*20, 10**20), ('1' + '0'*100, 10**100) ] - L2 = L[:] - for s, v in L2 + LL: + for s, v in LL: for sign in "", "+", "-": for prefix in "", " ", "\t", " \t\t ": ss = prefix + sign + s @@ -307,12 +273,10 @@ if sign == "-" and v is not ValueError: vv = -v try: - self.assertEqual(int(ss), int(vv)) + self.assertEqual(int(ss), vv) except ValueError: pass - self.assertRaises(ValueError, int, '123\0') - self.assertRaises(ValueError, int, '53', 40) # trailing L should no longer be accepted... self.assertRaises(ValueError, int, '123L') self.assertRaises(ValueError, int, '123l') @@ -323,302 +287,21 @@ # ... but it's just a normal digit if base >= 22 self.assertEqual(int('1L', 22), 43) - self.assertRaises(TypeError, int, 1, 12) - - # SF patch #1638879: embedded NULs were not detected with - # explicit base - self.assertRaises(ValueError, int, '123\0', 10) - self.assertRaises(ValueError, int, '123\x00 245', 20) - - self.assertEqual(int('100000000000000000000000000000000', 2), - 4294967296) - self.assertEqual(int('102002022201221111211', 3), 4294967296) - self.assertEqual(int('10000000000000000', 4), 4294967296) - self.assertEqual(int('32244002423141', 5), 4294967296) - self.assertEqual(int('1550104015504', 6), 4294967296) - self.assertEqual(int('211301422354', 7), 4294967296) - self.assertEqual(int('40000000000', 8), 4294967296) - self.assertEqual(int('12068657454', 9), 4294967296) - self.assertEqual(int('4294967296', 10), 4294967296) - self.assertEqual(int('1904440554', 11), 4294967296) - self.assertEqual(int('9ba461594', 12), 4294967296) - self.assertEqual(int('535a79889', 13), 4294967296) - self.assertEqual(int('2ca5b7464', 14), 4294967296) - self.assertEqual(int('1a20dcd81', 15), 4294967296) - self.assertEqual(int('100000000', 16), 4294967296) - self.assertEqual(int('a7ffda91', 17), 4294967296) - self.assertEqual(int('704he7g4', 18), 4294967296) - self.assertEqual(int('4f5aff66', 19), 4294967296) - self.assertEqual(int('3723ai4g', 20), 4294967296) - self.assertEqual(int('281d55i4', 21), 4294967296) - self.assertEqual(int('1fj8b184', 22), 4294967296) - self.assertEqual(int('1606k7ic', 23), 4294967296) - self.assertEqual(int('mb994ag', 24), 4294967296) - self.assertEqual(int('hek2mgl', 25), 4294967296) - self.assertEqual(int('dnchbnm', 26), 4294967296) - self.assertEqual(int('b28jpdm', 27), 4294967296) - self.assertEqual(int('8pfgih4', 28), 4294967296) - self.assertEqual(int('76beigg', 29), 4294967296) - self.assertEqual(int('5qmcpqg', 30), 4294967296) - self.assertEqual(int('4q0jto4', 31), 4294967296) - self.assertEqual(int('4000000', 32), 4294967296) - self.assertEqual(int('3aokq94', 33), 4294967296) - self.assertEqual(int('2qhxjli', 34), 4294967296) - self.assertEqual(int('2br45qb', 35), 4294967296) - self.assertEqual(int('1z141z4', 36), 4294967296) - - self.assertEqual(int('100000000000000000000000000000001', 2), - 4294967297) - self.assertEqual(int('102002022201221111212', 3), 4294967297) - self.assertEqual(int('10000000000000001', 4), 4294967297) - self.assertEqual(int('32244002423142', 5), 4294967297) - self.assertEqual(int('1550104015505', 6), 4294967297) - self.assertEqual(int('211301422355', 7), 4294967297) - self.assertEqual(int('40000000001', 8), 4294967297) - self.assertEqual(int('12068657455', 9), 4294967297) - self.assertEqual(int('4294967297', 10), 4294967297) - self.assertEqual(int('1904440555', 11), 4294967297) - self.assertEqual(int('9ba461595', 12), 4294967297) - self.assertEqual(int('535a7988a', 13), 4294967297) - self.assertEqual(int('2ca5b7465', 14), 4294967297) - self.assertEqual(int('1a20dcd82', 15), 4294967297) - self.assertEqual(int('100000001', 16), 4294967297) - self.assertEqual(int('a7ffda92', 17), 4294967297) - self.assertEqual(int('704he7g5', 18), 4294967297) - self.assertEqual(int('4f5aff67', 19), 4294967297) - self.assertEqual(int('3723ai4h', 20), 4294967297) - self.assertEqual(int('281d55i5', 21), 4294967297) - self.assertEqual(int('1fj8b185', 22), 4294967297) - self.assertEqual(int('1606k7id', 23), 4294967297) - self.assertEqual(int('mb994ah', 24), 4294967297) - self.assertEqual(int('hek2mgm', 25), 4294967297) - self.assertEqual(int('dnchbnn', 26), 4294967297) - self.assertEqual(int('b28jpdn', 27), 4294967297) - self.assertEqual(int('8pfgih5', 28), 4294967297) - self.assertEqual(int('76beigh', 29), 4294967297) - self.assertEqual(int('5qmcpqh', 30), 4294967297) - self.assertEqual(int('4q0jto5', 31), 4294967297) - self.assertEqual(int('4000001', 32), 4294967297) - self.assertEqual(int('3aokq95', 33), 4294967297) - self.assertEqual(int('2qhxjlj', 34), 4294967297) - self.assertEqual(int('2br45qc', 35), 4294967297) - self.assertEqual(int('1z141z5', 36), 4294967297) - - def test_conversion(self): - # Test __int__() - class ClassicMissingMethods: - pass - self.assertRaises(TypeError, int, ClassicMissingMethods()) - - class MissingMethods(object): - pass - self.assertRaises(TypeError, int, MissingMethods()) - class Foo0: - def __int__(self): + class JustLong: + # test that __long__ no longer used in 3.x + def __long__(self): return 42 + self.assertRaises(TypeError, int, JustLong()) - class Foo1(object): - def __int__(self): + class LongTrunc: + # __long__ should be ignored in 3.x + def __long__(self): return 42 - - class Foo2(int): - def __int__(self): - return 42 - - class Foo3(int): - def __int__(self): - return self - - class Foo4(int): - def __int__(self): - return 42 - - class Foo5(int): - def __int__(self): - return 42. - - self.assertEqual(int(Foo0()), 42) - self.assertEqual(int(Foo1()), 42) - self.assertEqual(int(Foo2()), 42) - self.assertEqual(int(Foo3()), 0) - self.assertEqual(int(Foo4()), 42) - self.assertRaises(TypeError, int, Foo5()) - - class Classic: - pass - for base in (object, Classic): - class IntOverridesTrunc(base): - def __int__(self): - return 42 - def __trunc__(self): - return -12 - self.assertEqual(int(IntOverridesTrunc()), 42) - - class JustTrunc(base): - def __trunc__(self): - return 42 - self.assertEqual(int(JustTrunc()), 42) - - class JustLong(base): - # test that __long__ no longer used in 3.x - def __long__(self): - return 42 - self.assertRaises(TypeError, int, JustLong()) - - class LongTrunc(base): - # __long__ should be ignored in 3.x - def __long__(self): - return 42 - def __trunc__(self): - return 1729 - self.assertEqual(int(LongTrunc()), 1729) - - for trunc_result_base in (object, Classic): - class Integral(trunc_result_base): - def __int__(self): - return 42 - - class TruncReturnsNonLong(base): - def __trunc__(self): - return Integral() - self.assertEqual(int(TruncReturnsNonLong()), 42) - - class NonIntegral(trunc_result_base): - def __trunc__(self): - # Check that we avoid infinite recursion. - return NonIntegral() - - class TruncReturnsNonIntegral(base): - def __trunc__(self): - return NonIntegral() - try: - int(TruncReturnsNonIntegral()) - except TypeError as e: - self.assertEquals(str(e), - "__trunc__ returned non-Integral" - " (type NonIntegral)") - else: - self.fail("Failed to raise TypeError with %s" % - ((base, trunc_result_base),)) - - def test_misc(self): - - # check the extremes in int<->long conversion - hugepos = sys.maxsize - hugeneg = -hugepos - 1 - hugepos_aslong = int(hugepos) - hugeneg_aslong = int(hugeneg) - self.assertEqual(hugepos, hugepos_aslong, "long(sys.maxsize) != sys.maxsize") - self.assertEqual(hugeneg, hugeneg_aslong, - "long(-sys.maxsize-1) != -sys.maxsize-1") - - # long -> int should not fail for hugepos_aslong or hugeneg_aslong - x = int(hugepos_aslong) - try: - self.assertEqual(x, hugepos, - "converting sys.maxsize to long and back to int fails") - except OverflowError: - self.fail("int(long(sys.maxsize)) overflowed!") - if not isinstance(x, int): - raise TestFailed("int(long(sys.maxsize)) should have returned int") - x = int(hugeneg_aslong) - try: - self.assertEqual(x, hugeneg, - "converting -sys.maxsize-1 to long and back to int fails") - except OverflowError: - self.fail("int(long(-sys.maxsize-1)) overflowed!") - if not isinstance(x, int): - raise TestFailed("int(long(-sys.maxsize-1)) should have " - "returned int") - # but long -> int should overflow for hugepos+1 and hugeneg-1 - x = hugepos_aslong + 1 - try: - y = int(x) - except OverflowError: - self.fail("int(long(sys.maxsize) + 1) mustn't overflow") - self.assertTrue(isinstance(y, int), - "int(long(sys.maxsize) + 1) should have returned long") - - x = hugeneg_aslong - 1 - try: - y = int(x) - except OverflowError: - self.fail("int(long(-sys.maxsize-1) - 1) mustn't overflow") - self.assertTrue(isinstance(y, int), - "int(long(-sys.maxsize-1) - 1) should have returned long") - - class long2(int): - pass - x = long2(1<<100) - y = int(x) - self.assertTrue(type(y) is int, - "overflowing int conversion must return long not long subtype") - -# ----------------------------------- tests of auto int->long conversion - - def test_auto_overflow(self): - import math, sys - - special = [0, 1, 2, 3, sys.maxsize-1, sys.maxsize, sys.maxsize+1] - sqrt = int(math.sqrt(sys.maxsize)) - special.extend([sqrt-1, sqrt, sqrt+1]) - special.extend([-i for i in special]) - - def checkit(*args): - # Heavy use of nested scopes here! - self.assertEqual(got, expected, - Frm("for %r expected %r got %r", args, expected, got)) - - for x in special: - longx = int(x) - - expected = -longx - got = -x - checkit('-', x) - - for y in special: - longy = int(y) - - expected = longx + longy - got = x + y - checkit(x, '+', y) - - expected = longx - longy - got = x - y - checkit(x, '-', y) - - expected = longx * longy - got = x * y - checkit(x, '*', y) - - if y: - expected = longx / longy - got = x / y - checkit(x, '/', y) - - expected = longx // longy - got = x // y - checkit(x, '//', y) - - expected = divmod(longx, longy) - got = divmod(longx, longy) - checkit(x, 'divmod', y) - - if abs(y) < 5 and not (x == 0 and y < 0): - expected = longx ** longy - got = x ** y - checkit(x, '**', y) - - for z in special: - if z != 0 : - if y >= 0: - expected = pow(longx, longy, int(z)) - got = pow(x, y, z) - checkit('pow', x, y, '%', z) - else: - self.assertRaises(TypeError, pow,longx, longy, int(z)) + def __trunc__(self): + return 1729 + self.assertEqual(int(LongTrunc()), 1729) @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") @@ -707,10 +390,10 @@ self.assertRaises(OverflowError, eval, test, namespace) - # XXX Perhaps float(shuge) can raise OverflowError on some box? - # The comparison should not. - self.assertNotEqual(float(shuge), int(shuge), - "float(shuge) should not equal int(shuge)") + # XXX Perhaps float(shuge) can raise OverflowError on some box? + # The comparison should not. + self.assertNotEqual(float(shuge), int(shuge), + "float(shuge) should not equal int(shuge)") def test_logs(self): import math @@ -807,7 +490,7 @@ cases.extend([t - 1.0, t - 0.3, t, t + 0.3, t + 1.0, int(t-1), int(t), int(t+1)]) cases.extend([0, 1, 2, sys.maxsize, float(sys.maxsize)]) - # 1L<<20000 should exceed all double formats. long(1e200) is to + # 1 << 20000 should exceed all double formats. int(1e200) is to # check that we get equality with 1e200 above. t = int(1e200) cases.extend([0, 1, 2, 1 << 20000, t-1, t, t+1]) 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 Sat Dec 5 21:28:34 2009 @@ -10,11 +10,9 @@ def test_truth_values(self): if None: self.fail('None is true instead of false') if 0: self.fail('0 is true instead of false') - if 0: self.fail('0L is true instead of false') if 0.0: self.fail('0.0 is true instead of false') if '': self.fail('\'\' is true instead of false') if not 1: self.fail('1 is false instead of true') - if not 1: self.fail('1L is false instead of true') if not 1.0: self.fail('1.0 is false instead of true') if not 'x': self.fail('\'x\' is false instead of true') if not {'x': 1}: self.fail('{\'x\': 1} is false instead of true') @@ -36,8 +34,6 @@ def test_comparisons(self): if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass else: self.fail('int comparisons failed') - if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass - else: self.fail('long int comparisons failed') if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass else: self.fail('float comparisons failed') if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass @@ -75,18 +71,13 @@ else: self.fail("5 % 0 didn't raise ZeroDivisionError") def test_numeric_types(self): - if 0 != 0 or 0 != 0.0 or 0 != 0.0: self.fail('mixed comparisons') - if 1 != 1 or 1 != 1.0 or 1 != 1.0: self.fail('mixed comparisons') - if -1 != -1 or -1 != -1.0 or -1 != -1.0: - self.fail('int/long/float value not equal') + if 0 != 0.0 or 1 != 1.0 or -1 != -1.0: + self.fail('int/float value not equal') # calling built-in types without argument must return 0 if int() != 0: self.fail('int() does not return 0') - if int() != 0: self.fail('long() does not return 0') if float() != 0.0: self.fail('float() does not return 0.0') if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass else: self.fail('int() does not round properly') - if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass - else: self.fail('long() does not round properly') if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass else: self.fail('float() does not work properly') @@ -141,58 +132,38 @@ if type(prod) is not int: self.fail("expected type(prod) to be int, not %r" % type(prod)) - # Check for expected * overflow to long. + # Check for unified integral type for divisor in 1, 2, 4, 8, 16, 32: j = m // divisor - 1 prod = divisor * j if type(prod) is not int: - self.fail("expected type(%r) to be long, not %r" % + self.fail("expected type(%r) to be int, not %r" % (prod, type(prod))) - # Check for expected * overflow to long. + # Check for unified integral type m = sys.maxsize for divisor in 1, 2, 4, 8, 16, 32: j = m // divisor + 1 prod = divisor * j if type(prod) is not int: - self.fail("expected type(%r) to be long, not %r" % + self.fail("expected type(%r) to be int, not %r" % (prod, type(prod))) - def test_long_integers(self): - if 12 + 24 != 36: self.fail('long op') - if 12 + (-24) != -12: self.fail('long op') - if (-12) + 24 != 12: self.fail('long op') - if (-12) + (-24) != -36: self.fail('long op') - if not 12 < 24: self.fail('long op') - if not -24 < -12: self.fail('long op') x = sys.maxsize - if int(int(x)) != x: self.fail('long op') - try: y = int(int(x)+1) - except OverflowError: self.fail('long op') - if not isinstance(y, int): self.fail('long op') - x = -x - if int(int(x)) != x: self.fail('long op') - x = x-1 - if int(int(x)) != x: self.fail('long op') - try: y = int(int(x)-1) - except OverflowError: self.fail('long op') - if not isinstance(y, int): self.fail('long op') + self.assertTrue(isinstance(x + 1, int), + "(sys.maxsize + 1) should have returned int") + self.assertTrue(isinstance(-x - 1, int), + "(-sys.maxsize - 1) should have returned int") + self.assertTrue(isinstance(-x - 2, int), + "(-sys.maxsize - 2) should have returned int") try: 5 << -5 except ValueError: pass else: self.fail('int negative shift <<') - try: 5 << -5 - except ValueError: pass - else: self.fail('long negative shift <<') - try: 5 >> -5 except ValueError: pass else: self.fail('int negative shift >>') - try: 5 >> -5 - except ValueError: pass - else: self.fail('long negative shift >>') - def test_floats(self): if 12.0 + 24.0 != 36.0: self.fail('float op') if 12.0 + (-24.0) != -12.0: self.fail('float op') @@ -232,7 +203,7 @@ def test_int__format__(self): def test(i, format_spec, result): - # just make sure I'm not accidentally checking longs + # just make sure we have the unified type for integers assert type(i) == int assert type(format_spec) == str self.assertEqual(i.__format__(format_spec), result) @@ -353,6 +324,10 @@ # issue 5782, commas with no specifier type test(1234, '010,', '00,001,234') + # Unified type for integers + test(10**100, 'd', '1' + '0' * 100) + test(10**100+100, 'd', '1' + '0' * 97 + '100') + # make sure these are errors # precision disallowed @@ -382,96 +357,6 @@ self.assertEqual(value.__format__(format_spec), float(value).__format__(format_spec)) - def test_long__format__(self): - def test(i, format_spec, result): - # make sure we're not accidentally checking ints - assert type(i) == int - assert type(format_spec) == str - self.assertEqual(i.__format__(format_spec), result) - - test(10**100, 'd', '1' + '0' * 100) - test(10**100+100, 'd', '1' + '0' * 97 + '100') - - test(123456789, 'd', '123456789') - test(123456789, 'd', '123456789') - - # sign and aligning are interdependent - test(1, "-", '1') - test(-1, "-", '-1') - test(1, "-3", ' 1') - test(-1, "-3", ' -1') - test(1, "+3", ' +1') - test(-1, "+3", ' -1') - test(1, " 3", ' 1') - test(-1, " 3", ' -1') - test(1, " ", ' 1') - test(-1, " ", '-1') - - test(1, 'c', '\01') - - # hex - test(3, "x", "3") - test(3, "X", "3") - test(1234, "x", "4d2") - test(-1234, "x", "-4d2") - test(1234, "8x", " 4d2") - test(-1234, "8x", " -4d2") - test(1234, "x", "4d2") - test(-1234, "x", "-4d2") - test(-3, "x", "-3") - test(-3, "X", "-3") - - # octal - test(3, "o", "3") - test(-3, "o", "-3") - test(65, "o", "101") - test(-65, "o", "-101") - test(1234, "o", "2322") - test(-1234, "o", "-2322") - test(1234, "-o", "2322") - test(-1234, "-o", "-2322") - test(1234, " o", " 2322") - test(-1234, " o", "-2322") - test(1234, "+o", "+2322") - test(-1234, "+o", "-2322") - - # binary - test(3, "b", "11") - test(-3, "b", "-11") - test(1234, "b", "10011010010") - test(-1234, "b", "-10011010010") - test(1234, "-b", "10011010010") - test(-1234, "-b", "-10011010010") - test(1234, " b", " 10011010010") - test(-1234, " b", "-10011010010") - test(1234, "+b", "+10011010010") - test(-1234, "+b", "-10011010010") - - # make sure these are errors - - # precision disallowed - self.assertRaises(ValueError, 3 .__format__, "1.3") - # sign not allowed with 'c' - self.assertRaises(ValueError, 3 .__format__, "+c") - # format spec must be string - self.assertRaises(TypeError, 3 .__format__, None) - self.assertRaises(TypeError, 3 .__format__, 0) - - # 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)]): - if not format_spec in 'bcdoxXeEfFgGn%': - self.assertRaises(ValueError, 0 .__format__, format_spec) - self.assertRaises(ValueError, 1 .__format__, format_spec) - self.assertRaises(ValueError, (-1) .__format__, format_spec) - - # ensure that float type specifiers work; format converts - # the long to a float - for format_spec in 'eEfFgG%': - for value in [0, 1, -1, 100, -100, 1234567890, -1234567890]: - 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' From python-checkins at python.org Sat Dec 5 21:31:25 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 05 Dec 2009 20:31:25 -0000 Subject: [Python-checkins] r76682 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sat Dec 5 21:31:25 2009 New Revision: 76682 Log: Blocked revisions 76681 via svnmerge ........ r76681 | mark.dickinson | 2009-12-05 20:28:34 +0000 (Sat, 05 Dec 2009) | 4 lines Issue #7435: Remove duplicate int/long tests, and other references to long in py3k. Patch provided by flox. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sat Dec 5 21:32:50 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 05 Dec 2009 20:32:50 -0000 Subject: [Python-checkins] r76683 - python/branches/release31-maint/Lib/random.py Message-ID: Author: mark.dickinson Date: Sat Dec 5 21:32:49 2009 New Revision: 76683 Log: Issue #7435: Remove reference to long in docstring. Thanks flox. Modified: python/branches/release31-maint/Lib/random.py Modified: python/branches/release31-maint/Lib/random.py ============================================================================== --- python/branches/release31-maint/Lib/random.py (original) +++ python/branches/release31-maint/Lib/random.py Sat Dec 5 21:32:49 2009 @@ -97,7 +97,7 @@ None or no argument seeds from current time or from an operating system specific randomness source if available. - If a is not None or an int or long, hash(a) is used instead. + If a is not None or an int, hash(a) is used instead. """ if a is None: From solipsis at pitrou.net Sun Dec 6 00:47:08 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 6 Dec 2009 00:47:08 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76681): sum=-15 Message-ID: <20091205234708.AA9A717722@ns6635.ovh.net> py3k results for svn r76681 (hg cset f2d64931c51a) -------------------------------------------------- test_cmd_line leaked [0, 0, -29] references, sum=-29 test_urllib leaked [6, 6, 2] references, sum=14 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogPfD6Mw', '-x', 'test_httpservers'] From python-checkins at python.org Sun Dec 6 10:22:41 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 06 Dec 2009 09:22:41 -0000 Subject: [Python-checkins] r76684 - in python/trunk: Lib/distutils/tests/test_dist.py Lib/distutils/util.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Sun Dec 6 10:22:40 2009 New Revision: 76684 Log: Fixed #1923: make sure we don't strip meaningful whitespace in PKG-INFO Description field Modified: python/trunk/Lib/distutils/tests/test_dist.py python/trunk/Lib/distutils/util.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/tests/test_dist.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_dist.py (original) +++ python/trunk/Lib/distutils/tests/test_dist.py Sun Dec 6 10:22:40 2009 @@ -6,6 +6,7 @@ import sys import unittest import warnings +import textwrap from distutils.dist import Distribution, fix_help_options from distutils.cmd import Command @@ -381,6 +382,21 @@ if line.strip() != ''] self.assertTrue(len(output) > 0) + def test_long_description(self): + long_desc = textwrap.dedent("""\ + example:: + We start here + and continue here + and end here.""") + attrs = {"name": "package", + "version": "1.0", + "long_description": long_desc} + + dist = distutils.dist.Distribution(attrs) + meta = self.format_metadata(dist) + meta = meta.replace('\n' + 8 * ' ', '\n') + self.assertTrue(long_desc in meta) + def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(DistributionTestCase)) Modified: python/trunk/Lib/distutils/util.py ============================================================================== --- python/trunk/Lib/distutils/util.py (original) +++ python/trunk/Lib/distutils/util.py Sun Dec 6 10:22:40 2009 @@ -558,8 +558,8 @@ """Return a version of the string escaped for inclusion in an RFC-822 header, by ensuring there are 8 spaces space after each newline. """ - lines = [x.strip() for x in header.split('\n')] - sep = '\n' + 8*' ' + lines = header.split('\n') + sep = '\n' + 8 * ' ' return sep.join(lines) _RE_VERSION = re.compile('(\d+\.\d+(\.\d+)*)') Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 6 10:22:40 2009 @@ -507,6 +507,9 @@ Library ------- +- Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is + generated in Distutils. Patch by Stephen Emslie. + - Issue #4120: Drop reference to CRT from manifest when building extensions with msvc9compiler. From python-checkins at python.org Sun Dec 6 10:26:45 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 06 Dec 2009 09:26:45 -0000 Subject: [Python-checkins] r76685 - in python/branches/release26-maint: Lib/distutils/tests/test_dist.py Lib/distutils/util.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Sun Dec 6 10:26:45 2009 New Revision: 76685 Log: Merged revisions 76684 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76684 | tarek.ziade | 2009-12-06 10:22:40 +0100 (Sun, 06 Dec 2009) | 1 line Fixed #1923: make sure we don't strip meaningful whitespace in PKG-INFO Description field ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/tests/test_dist.py python/branches/release26-maint/Lib/distutils/util.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/distutils/tests/test_dist.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/tests/test_dist.py (original) +++ python/branches/release26-maint/Lib/distutils/tests/test_dist.py Sun Dec 6 10:26:45 2009 @@ -9,6 +9,7 @@ import sys import unittest import warnings +import textwrap from test.test_support import TESTFN @@ -283,6 +284,21 @@ os.environ[key] = value os.remove(user_filename) + def test_long_description(self): + long_desc = textwrap.dedent("""\ + example:: + We start here + and continue here + and end here.""") + attrs = {"name": "package", + "version": "1.0", + "long_description": long_desc} + + dist = distutils.dist.Distribution(attrs) + meta = self.format_metadata(dist) + meta = meta.replace('\n' + 8 * ' ', '\n') + self.assertTrue(long_desc in meta) + def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(DistributionTestCase)) Modified: python/branches/release26-maint/Lib/distutils/util.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/util.py (original) +++ python/branches/release26-maint/Lib/distutils/util.py Sun Dec 6 10:26:45 2009 @@ -559,6 +559,5 @@ RFC-822 header, by ensuring there are 8 spaces space after each newline. """ lines = string.split(header, '\n') - lines = map(string.strip, lines) header = string.join(lines, '\n' + 8*' ') return header Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Dec 6 10:26:45 2009 @@ -33,6 +33,9 @@ Library ------- +- Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is + generated in Distutils. Patch by Stephen Emslie. + - Issue #4120: Drop reference to CRT from manifest when building extensions with msvc9compiler. From python-checkins at python.org Sun Dec 6 10:28:18 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 06 Dec 2009 09:28:18 -0000 Subject: [Python-checkins] r76686 - in python/branches/py3k: Lib/distutils/tests/test_dist.py Lib/distutils/util.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Sun Dec 6 10:28:17 2009 New Revision: 76686 Log: Merged revisions 76684 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76684 | tarek.ziade | 2009-12-06 10:22:40 +0100 (Sun, 06 Dec 2009) | 1 line Fixed #1923: make sure we don't strip meaningful whitespace in PKG-INFO Description field ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_dist.py python/branches/py3k/Lib/distutils/util.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/tests/test_dist.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_dist.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_dist.py Sun Dec 6 10:28:17 2009 @@ -5,6 +5,7 @@ import sys import unittest import warnings +import textwrap from distutils.dist import Distribution, fix_help_options from distutils.cmd import Command @@ -353,6 +354,21 @@ if line.strip() != ''] self.assertTrue(len(output) > 0) + def test_long_description(self): + long_desc = textwrap.dedent("""\ + example:: + We start here + and continue here + and end here.""") + attrs = {"name": "package", + "version": "1.0", + "long_description": long_desc} + + dist = distutils.dist.Distribution(attrs) + meta = self.format_metadata(dist) + meta = meta.replace('\n' + 8 * ' ', '\n') + self.assertTrue(long_desc in meta) + def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(DistributionTestCase)) Modified: python/branches/py3k/Lib/distutils/util.py ============================================================================== --- python/branches/py3k/Lib/distutils/util.py (original) +++ python/branches/py3k/Lib/distutils/util.py Sun Dec 6 10:28:17 2009 @@ -557,8 +557,8 @@ """Return a version of the string escaped for inclusion in an RFC-822 header, by ensuring there are 8 spaces space after each newline. """ - lines = [x.strip() for x in header.split('\n')] - sep = '\n' + 8*' ' + lines = header.split('\n') + sep = '\n' + 8 * ' ' return sep.join(lines) _RE_VERSION = re.compile(b'(\d+\.\d+(\.\d+)*)') Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Dec 6 10:28:17 2009 @@ -154,6 +154,9 @@ Library ------- +- Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is + generated in Distutils. Patch by Stephen Emslie. + - Issue #4120: Drop reference to CRT from manifest when building extensions with msvc9compiler. From python-checkins at python.org Sun Dec 6 10:30:48 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 06 Dec 2009 09:30:48 -0000 Subject: [Python-checkins] r76687 - in python/branches/release31-maint: Lib/distutils/tests/test_dist.py Lib/distutils/util.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Sun Dec 6 10:30:47 2009 New Revision: 76687 Log: Merged revisions 76686 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76686 | tarek.ziade | 2009-12-06 10:28:17 +0100 (Sun, 06 Dec 2009) | 9 lines Merged revisions 76684 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76684 | tarek.ziade | 2009-12-06 10:22:40 +0100 (Sun, 06 Dec 2009) | 1 line Fixed #1923: make sure we don't strip meaningful whitespace in PKG-INFO Description field ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/distutils/tests/test_dist.py python/branches/release31-maint/Lib/distutils/util.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/distutils/tests/test_dist.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/tests/test_dist.py (original) +++ python/branches/release31-maint/Lib/distutils/tests/test_dist.py Sun Dec 6 10:30:47 2009 @@ -5,6 +5,7 @@ import sys import unittest import warnings +import textwrap from distutils.dist import Distribution, fix_help_options from distutils.cmd import Command @@ -301,6 +302,21 @@ if line.strip() != ''] self.assertTrue(len(output) > 0) + def test_long_description(self): + long_desc = textwrap.dedent("""\ + example:: + We start here + and continue here + and end here.""") + attrs = {"name": "package", + "version": "1.0", + "long_description": long_desc} + + dist = Distribution(attrs) + meta = self.format_metadata(dist) + meta = meta.replace('\n' + 8 * ' ', '\n') + self.assertTrue(long_desc in meta) + def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(DistributionTestCase)) Modified: python/branches/release31-maint/Lib/distutils/util.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/util.py (original) +++ python/branches/release31-maint/Lib/distutils/util.py Sun Dec 6 10:30:47 2009 @@ -557,8 +557,8 @@ """Return a version of the string escaped for inclusion in an RFC-822 header, by ensuring there are 8 spaces space after each newline. """ - lines = [x.strip() for x in header.split('\n')] - sep = '\n' + 8*' ' + lines = header.split('\n') + sep = '\n' + 8 * ' ' return sep.join(lines) # 2to3 support Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Dec 6 10:30:47 2009 @@ -55,6 +55,9 @@ Library ------- +- Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is + generated in Distutils. Patch by Stephen Emslie. + - Issue #4120: Drop reference to CRT from manifest when building extensions with msvc9compiler. From python-checkins at python.org Sun Dec 6 18:36:45 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 06 Dec 2009 17:36:45 -0000 Subject: [Python-checkins] r76688 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Sun Dec 6 18:36:44 2009 New Revision: 76688 Log: Blocked revisions 76551,76600 via svnmerge ........ r76551 | vinay.sajip | 2009-11-27 08:03:36 -0600 (Fri, 27 Nov 2009) | 1 line Issue #7403: Fixed possible race condition in lock creation. ........ r76600 | raymond.hettinger | 2009-11-30 13:44:40 -0600 (Mon, 30 Nov 2009) | 3 lines Issue 7410: deepcopy of itertools.count resets the count ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Dec 6 18:37:48 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 06 Dec 2009 17:37:48 -0000 Subject: [Python-checkins] r76689 - python/trunk/Parser/tokenizer.c Message-ID: Author: benjamin.peterson Date: Sun Dec 6 18:37:48 2009 New Revision: 76689 Log: rewrite translate_newlines for clarity Modified: python/trunk/Parser/tokenizer.c Modified: python/trunk/Parser/tokenizer.c ============================================================================== --- python/trunk/Parser/tokenizer.c (original) +++ python/trunk/Parser/tokenizer.c Sun Dec 6 18:37:48 2009 @@ -591,20 +591,20 @@ static char * translate_newlines(const char *s, int exec_input, struct tok_state *tok) { - int skip_next_lf = 0, length = strlen(s), final_length; + int skip_next_lf = 0, needed_length = strlen(s) + 2, final_length; char *buf, *current; - char c; - buf = PyMem_MALLOC(length + 2); + char c = '\0'; + buf = PyMem_MALLOC(needed_length); if (buf == NULL) { tok->done = E_NOMEM; return NULL; } - for (current = buf; (c = *s++);) { + for (current = buf; *s; s++, current++) { + c = *s; if (skip_next_lf) { skip_next_lf = 0; if (c == '\n') { - c = *s; - s++; + c = *++s; if (!c) break; } @@ -614,19 +614,18 @@ c = '\n'; } *current = c; - current++; } - /* If this is exec input, add a newline to the end of the file if + /* If this is exec input, add a newline to the end of the string if there isn't one already. */ - if (exec_input && *current != '\n') { + if (exec_input && c != '\n') { *current = '\n'; current++; } *current = '\0'; - final_length = current - buf; - if (final_length < length && final_length) + final_length = current - buf + 1; + if (final_length < needed_length && final_length) /* should never fail */ - buf = PyMem_REALLOC(buf, final_length + 1); + buf = PyMem_REALLOC(buf, final_length); return buf; } From python-checkins at python.org Sun Dec 6 18:57:11 2009 From: python-checkins at python.org (vinay.sajip) Date: Sun, 06 Dec 2009 17:57:11 -0000 Subject: [Python-checkins] r76690 - in python: branches/py3k/Lib/logging/handlers.py branches/py3k/Misc/NEWS trunk/Lib/logging/handlers.py trunk/Misc/NEWS Message-ID: Author: vinay.sajip Date: Sun Dec 6 18:57:11 2009 New Revision: 76690 Log: logging: Added optional 'secure' parameter to SMTPHandler. Modified: python/branches/py3k/Lib/logging/handlers.py python/branches/py3k/Misc/NEWS python/trunk/Lib/logging/handlers.py python/trunk/Misc/NEWS Modified: python/branches/py3k/Lib/logging/handlers.py ============================================================================== --- python/branches/py3k/Lib/logging/handlers.py (original) +++ python/branches/py3k/Lib/logging/handlers.py Sun Dec 6 18:57:11 2009 @@ -803,7 +803,8 @@ """ A handler class which sends an SMTP email for each logging event. """ - def __init__(self, mailhost, fromaddr, toaddrs, subject, credentials=None): + def __init__(self, mailhost, fromaddr, toaddrs, subject, + credentials=None, secure=False): """ Initialize the handler. @@ -811,7 +812,9 @@ line of the email. To specify a non-standard SMTP port, use the (host, port) tuple format for the mailhost argument. To specify authentication credentials, supply a (username, password) tuple - for the credentials argument. + for the credentials argument. To specify the use of a secure + protocol (TLS), pass in True for the secure argument. This will + only be used when authentication credentials are supplied. """ logging.Handler.__init__(self) if isinstance(mailhost, tuple): @@ -827,6 +830,7 @@ toaddrs = [toaddrs] self.toaddrs = toaddrs self.subject = subject + self.secure = secure def getSubject(self, record): """ @@ -878,6 +882,10 @@ self.getSubject(record), formatdate(), msg) if self.username: + if self.secure: + smtp.ehlo() + smtp.starttls() + smtp.ehlo() smtp.login(self.username, self.password) smtp.sendmail(self.fromaddr, self.toaddrs, msg) smtp.quit() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Dec 6 18:57:11 2009 @@ -154,6 +154,9 @@ Library ------- +- logging: Added optional `secure` parameter to SMTPHandler, to enable use of + TLS with authentication credentials. + - Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is generated in Distutils. Patch by Stephen Emslie. Modified: python/trunk/Lib/logging/handlers.py ============================================================================== --- python/trunk/Lib/logging/handlers.py (original) +++ python/trunk/Lib/logging/handlers.py Sun Dec 6 18:57:11 2009 @@ -809,7 +809,8 @@ """ A handler class which sends an SMTP email for each logging event. """ - def __init__(self, mailhost, fromaddr, toaddrs, subject, credentials=None): + def __init__(self, mailhost, fromaddr, toaddrs, subject, + credentials=None, secure=False): """ Initialize the handler. @@ -817,7 +818,9 @@ line of the email. To specify a non-standard SMTP port, use the (host, port) tuple format for the mailhost argument. To specify authentication credentials, supply a (username, password) tuple - for the credentials argument. + for the credentials argument. To specify the use of a secure + protocol (TLS), pass in True for the secure argument. This will + only be used when authentication credentials are supplied. """ logging.Handler.__init__(self) if isinstance(mailhost, tuple): @@ -833,6 +836,7 @@ toaddrs = [toaddrs] self.toaddrs = toaddrs self.subject = subject + self.secure = secure def getSubject(self, record): """ @@ -884,6 +888,10 @@ self.getSubject(record), formatdate(), msg) if self.username: + if self.secure: + smtp.ehlo() + smtp.starttls() + smtp.ehlo() smtp.login(self.username, self.password) smtp.sendmail(self.fromaddr, self.toaddrs, msg) smtp.quit() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 6 18:57:11 2009 @@ -507,6 +507,9 @@ Library ------- +- logging: Added optional `secure` parameter to SMTPHandler, to enable use of + TLS with authentication credentials. + - Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is generated in Distutils. Patch by Stephen Emslie. From benjamin at python.org Sun Dec 6 19:00:21 2009 From: benjamin at python.org (Benjamin Peterson) Date: Sun, 6 Dec 2009 12:00:21 -0600 Subject: [Python-checkins] r76690 - in python: branches/py3k/Lib/logging/handlers.py branches/py3k/Misc/NEWS trunk/Lib/logging/handlers.py trunk/Misc/NEWS In-Reply-To: <4b1bf07f.1c67f10a.32b5.65c7SMTPIN_ADDED@mx.google.com> References: <4b1bf07f.1c67f10a.32b5.65c7SMTPIN_ADDED@mx.google.com> Message-ID: <1afaf6160912061000l1884e511p2c3792032690cd30@mail.gmail.com> 2009/12/6 vinay.sajip : > Author: vinay.sajip > Date: Sun Dec ?6 18:57:11 2009 > New Revision: 76690 > > Log: > logging: Added optional 'secure' parameter to SMTPHandler. > > Modified: > ? python/branches/py3k/Lib/logging/handlers.py > ? python/branches/py3k/Misc/NEWS > ? python/trunk/Lib/logging/handlers.py > ? python/trunk/Misc/NEWS Hi Vinay, Could you do your checkins first in the trunk and merge them to other branches with svnmerge.py please instead of altering all the branches at the same time? -- Regards, Benjamin From python-checkins at python.org Sun Dec 6 19:05:05 2009 From: python-checkins at python.org (vinay.sajip) Date: Sun, 06 Dec 2009 18:05:05 -0000 Subject: [Python-checkins] r76691 - in python: branches/py3k/Lib/logging/handlers.py trunk/Lib/logging/handlers.py Message-ID: Author: vinay.sajip Date: Sun Dec 6 19:05:04 2009 New Revision: 76691 Log: logging: Improved support for SMTP over TLS. Modified: python/branches/py3k/Lib/logging/handlers.py python/trunk/Lib/logging/handlers.py Modified: python/branches/py3k/Lib/logging/handlers.py ============================================================================== --- python/branches/py3k/Lib/logging/handlers.py (original) +++ python/branches/py3k/Lib/logging/handlers.py Sun Dec 6 19:05:04 2009 @@ -804,7 +804,7 @@ A handler class which sends an SMTP email for each logging event. """ def __init__(self, mailhost, fromaddr, toaddrs, subject, - credentials=None, secure=False): + credentials=None, secure=None): """ Initialize the handler. @@ -812,9 +812,12 @@ line of the email. To specify a non-standard SMTP port, use the (host, port) tuple format for the mailhost argument. To specify authentication credentials, supply a (username, password) tuple - for the credentials argument. To specify the use of a secure - protocol (TLS), pass in True for the secure argument. This will - only be used when authentication credentials are supplied. + for the credentials argument. To specify the use of a secure + protocol (TLS), pass in a tuple for the secure argument. This will + only be used when authentication credentials are supplied. The tuple + will be either an empty tuple, or a single-value tuple with the name + of a keyfile, or a 2-value tuple with the names of the keyfile and + certificate file. (This tuple is passed to the `starttls` method). """ logging.Handler.__init__(self) if isinstance(mailhost, tuple): @@ -882,9 +885,9 @@ self.getSubject(record), formatdate(), msg) if self.username: - if self.secure: + if self.secure is not None: smtp.ehlo() - smtp.starttls() + smtp.starttls(*self.secure) smtp.ehlo() smtp.login(self.username, self.password) smtp.sendmail(self.fromaddr, self.toaddrs, msg) Modified: python/trunk/Lib/logging/handlers.py ============================================================================== --- python/trunk/Lib/logging/handlers.py (original) +++ python/trunk/Lib/logging/handlers.py Sun Dec 6 19:05:04 2009 @@ -810,7 +810,7 @@ A handler class which sends an SMTP email for each logging event. """ def __init__(self, mailhost, fromaddr, toaddrs, subject, - credentials=None, secure=False): + credentials=None, secure=None): """ Initialize the handler. @@ -819,8 +819,11 @@ (host, port) tuple format for the mailhost argument. To specify authentication credentials, supply a (username, password) tuple for the credentials argument. To specify the use of a secure - protocol (TLS), pass in True for the secure argument. This will - only be used when authentication credentials are supplied. + protocol (TLS), pass in a tuple for the secure argument. This will + only be used when authentication credentials are supplied. The tuple + will be either an empty tuple, or a single-value tuple with the name + of a keyfile, or a 2-value tuple with the names of the keyfile and + certificate file. (This tuple is passed to the `starttls` method). """ logging.Handler.__init__(self) if isinstance(mailhost, tuple): @@ -888,9 +891,9 @@ self.getSubject(record), formatdate(), msg) if self.username: - if self.secure: + if self.secure is not None: smtp.ehlo() - smtp.starttls() + smtp.starttls(*self.secure) smtp.ehlo() smtp.login(self.username, self.password) smtp.sendmail(self.fromaddr, self.toaddrs, msg) From python-checkins at python.org Sun Dec 6 19:27:29 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 06 Dec 2009 18:27:29 -0000 Subject: [Python-checkins] r76692 - python/trunk/Tools/msi/uuids.py Message-ID: Author: martin.v.loewis Date: Sun Dec 6 19:27:29 2009 New Revision: 76692 Log: Add UUIDs for 2.7. Drop UUIDs for 2.4. Modified: python/trunk/Tools/msi/uuids.py Modified: python/trunk/Tools/msi/uuids.py ============================================================================== --- python/trunk/Tools/msi/uuids.py (original) +++ python/trunk/Tools/msi/uuids.py Sun Dec 6 19:27:29 2009 @@ -7,23 +7,6 @@ # generated. For official releases, we record the product codes, # so people can refer to them. product_codes = { - '2.4.101': '{0e9b4d8e-6cda-446e-a208-7b92f3ddffa0}', # 2.4a1, released as a snapshot - '2.4.102': '{1b998745-4901-4edb-bc52-213689e1b922}', # 2.4a2 - '2.4.103': '{33fc8bd2-1e8f-4add-a40a-ade2728d5942}', # 2.4a3 - '2.4.111': '{51a7e2a8-2025-4ef0-86ff-e6aab742d1fa}', # 2.4b1 - '2.4.112': '{4a5e7c1d-c659-4fe3-b8c9-7c65bd9c95a5}', # 2.4b2 - '2.4.121': '{75508821-a8e9-40a8-95bd-dbe6033ddbea}', # 2.4c1 - '2.4.122': '{83a9118b-4bdd-473b-afc3-bcb142feca9e}', # 2.4c2 - '2.4.150': '{82d9302e-f209-4805-b548-52087047483a}', # 2.4.0 - '2.4.1121':'{be027411-8e6b-4440-a29b-b07df0690230}', # 2.4.1c1 - '2.4.1122':'{02818752-48bf-4074-a281-7a4114c4f1b1}', # 2.4.1c2 - '2.4.1150':'{4d4f5346-7e4a-40b5-9387-fdb6181357fc}', # 2.4.1 - '2.4.2121':'{5ef9d6b6-df78-45d2-ab09-14786a3c5a99}', # 2.4.2c1 - '2.4.2150':'{b191e49c-ea23-43b2-b28a-14e0784069b8}', # 2.4.2 - '2.4.3121':'{f669ed4d-1dce-41c4-9617-d985397187a1}', # 2.4.3c1 - '2.4.3150':'{75e71add-042c-4f30-bfac-a9ec42351313}', # 2.4.3 - '2.4.4121':'{cd2862db-22a4-4688-8772-85407ea21550}', # 2.4.4c1 - '2.4.4150':'{60e2c8c9-6cf3-4b1a-9618-e304946c94e6}', # 2.4.4 '2.5.101': '{bc14ce3e-5e72-4a64-ac1f-bf59a571898c}', # 2.5a1 '2.5.102': '{5eed51c1-8e9d-4071-94c5-b40de5d49ba5}', # 2.5a2 '2.5.103': '{73dcd966-ffec-415f-bb39-8342c1f47017}', # 2.5a3 @@ -50,4 +33,13 @@ '2.6.1150':'{9cc89170-000b-457d-91f1-53691f85b223}', # 2.6.1 '2.6.2121':'{adac412b-b209-4c15-b6ab-dca1b6e47144}', # 2.6.2c1 '2.6.2150':'{24aab420-4e30-4496-9739-3e216f3de6ae}', # 2.6.2 + '2.7.101': '{eca1bbef-432c-49ae-a667-c213cc7bbf22}', # 2.7a1 + '2.7.102': '{21ce16ed-73c4-460d-9b11-522f417b2090}', # 2.7a2 + '2.7.103': '{6e7dbd55-ba4a-48ac-a688-6c75db4d7500}', # 2.7a3 + '2.7.104': '{ee774ba3-74a5-48d9-b425-b35a287260c8}', # 2.7a4 + '2.7.111': '{9cfd9ec7-a9c7-4980-a1c6-054fc6493eb3}', # 2.7b1 + '2.7.112': '{9a72faf6-c304-4165-8595-9291ff30cac6}', # 2.7b2 + '2.7.121': '{f530c94a-dd53-4de9-948e-b632b9cb48d2}', # 2.7c1 + '2.7.122': '{f80905d2-dd8d-4b8e-8a40-c23c93dca07d}', # 2.7c2 + '2.7.150': '{20c31435-2a0a-4580-be8b-ac06fc243ca4}', # 2.7.0 } From python-checkins at python.org Sun Dec 6 19:34:15 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 06 Dec 2009 18:34:15 -0000 Subject: [Python-checkins] r76693 - in python/branches/py3k: Tools/msi/uuids.py Message-ID: Author: martin.v.loewis Date: Sun Dec 6 19:34:14 2009 New Revision: 76693 Log: Merged revisions 76692 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76692 | martin.v.loewis | 2009-12-06 19:27:29 +0100 (So, 06 Dez 2009) | 2 lines Add UUIDs for 2.7. Drop UUIDs for 2.4. ........ Modified: python/branches/py3k/ (props changed) 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 Sun Dec 6 19:34:14 2009 @@ -7,23 +7,6 @@ # generated. For official releases, we record the product codes, # so people can refer to them. product_codes = { - '2.4.101': '{0e9b4d8e-6cda-446e-a208-7b92f3ddffa0}', # 2.4a1, released as a snapshot - '2.4.102': '{1b998745-4901-4edb-bc52-213689e1b922}', # 2.4a2 - '2.4.103': '{33fc8bd2-1e8f-4add-a40a-ade2728d5942}', # 2.4a3 - '2.4.111': '{51a7e2a8-2025-4ef0-86ff-e6aab742d1fa}', # 2.4b1 - '2.4.112': '{4a5e7c1d-c659-4fe3-b8c9-7c65bd9c95a5}', # 2.4b2 - '2.4.121': '{75508821-a8e9-40a8-95bd-dbe6033ddbea}', # 2.4c1 - '2.4.122': '{83a9118b-4bdd-473b-afc3-bcb142feca9e}', # 2.4c2 - '2.4.150': '{82d9302e-f209-4805-b548-52087047483a}', # 2.4.0 - '2.4.1121':'{be027411-8e6b-4440-a29b-b07df0690230}', # 2.4.1c1 - '2.4.1122':'{02818752-48bf-4074-a281-7a4114c4f1b1}', # 2.4.1c2 - '2.4.1150':'{4d4f5346-7e4a-40b5-9387-fdb6181357fc}', # 2.4.1 - '2.4.2121':'{5ef9d6b6-df78-45d2-ab09-14786a3c5a99}', # 2.4.2c1 - '2.4.2150':'{b191e49c-ea23-43b2-b28a-14e0784069b8}', # 2.4.2 - '2.4.3121':'{f669ed4d-1dce-41c4-9617-d985397187a1}', # 2.4.3c1 - '2.4.3150':'{75e71add-042c-4f30-bfac-a9ec42351313}', # 2.4.3 - '2.4.4121':'{cd2862db-22a4-4688-8772-85407ea21550}', # 2.4.4c1 - '2.4.4150':'{60e2c8c9-6cf3-4b1a-9618-e304946c94e6}', # 2.4.4 '2.5.101': '{bc14ce3e-5e72-4a64-ac1f-bf59a571898c}', # 2.5a1 '2.5.102': '{5eed51c1-8e9d-4071-94c5-b40de5d49ba5}', # 2.5a2 '2.5.103': '{73dcd966-ffec-415f-bb39-8342c1f47017}', # 2.5a3 @@ -50,6 +33,15 @@ '2.6.1150':'{9cc89170-000b-457d-91f1-53691f85b223}', # 2.6.1 '2.6.2121':'{adac412b-b209-4c15-b6ab-dca1b6e47144}', # 2.6.2c1 '2.6.2150':'{24aab420-4e30-4496-9739-3e216f3de6ae}', # 2.6.2 + '2.7.101': '{eca1bbef-432c-49ae-a667-c213cc7bbf22}', # 2.7a1 + '2.7.102': '{21ce16ed-73c4-460d-9b11-522f417b2090}', # 2.7a2 + '2.7.103': '{6e7dbd55-ba4a-48ac-a688-6c75db4d7500}', # 2.7a3 + '2.7.104': '{ee774ba3-74a5-48d9-b425-b35a287260c8}', # 2.7a4 + '2.7.111': '{9cfd9ec7-a9c7-4980-a1c6-054fc6493eb3}', # 2.7b1 + '2.7.112': '{9a72faf6-c304-4165-8595-9291ff30cac6}', # 2.7b2 + '2.7.121': '{f530c94a-dd53-4de9-948e-b632b9cb48d2}', # 2.7c1 + '2.7.122': '{f80905d2-dd8d-4b8e-8a40-c23c93dca07d}', # 2.7c2 + '2.7.150': '{20c31435-2a0a-4580-be8b-ac06fc243ca4}', # 2.7.0 '3.0.101': '{8554263a-3242-4857-9359-aa87bc2c58c2}', # 3.0a1 '3.0.102': '{692d6e2c-f0ac-40b8-a133-7191aeeb67f9}', # 3.0a2 '3.0.103': '{49cb2995-751a-4753-be7a-d0b1bb585e06}', # 3.0a3 From python-checkins at python.org Sun Dec 6 19:49:48 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 06 Dec 2009 18:49:48 -0000 Subject: [Python-checkins] r76694 - python/branches/pep-0383/py3k Message-ID: Author: martin.v.loewis Date: Sun Dec 6 19:49:48 2009 New Revision: 76694 Log: Create branch for PEP 384. Added: python/branches/pep-0383/py3k/ - copied from r76693, /python/branches/py3k/ From python-checkins at python.org Sun Dec 6 19:55:38 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 06 Dec 2009 18:55:38 -0000 Subject: [Python-checkins] r76695 - python/branches/pep-0383/py3k Message-ID: Author: martin.v.loewis Date: Sun Dec 6 19:55:38 2009 New Revision: 76695 Log: Remove bogus copy. Removed: python/branches/pep-0383/py3k/ From python-checkins at python.org Sun Dec 6 19:56:03 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 06 Dec 2009 18:56:03 -0000 Subject: [Python-checkins] r76696 - python/branches/pep-0384 Message-ID: Author: martin.v.loewis Date: Sun Dec 6 19:56:02 2009 New Revision: 76696 Log: Create branch for PEP 384. Added: python/branches/pep-0384/ - copied from r76695, /python/branches/py3k/ From python-checkins at python.org Sun Dec 6 22:24:30 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 06 Dec 2009 21:24:30 -0000 Subject: [Python-checkins] r76697 - python/trunk/Lib/test/test_parser.py Message-ID: Author: benjamin.peterson Date: Sun Dec 6 22:24:30 2009 New Revision: 76697 Log: fix test_parser and tokenizer tweak Modified: python/trunk/Lib/test/test_parser.py Modified: python/trunk/Lib/test/test_parser.py ============================================================================== --- python/trunk/Lib/test/test_parser.py (original) +++ python/trunk/Lib/test/test_parser.py Sun Dec 6 22:24:30 2009 @@ -214,7 +214,7 @@ def test_position(self): # An absolutely minimal test of position information. Better # tests would be a big project. - code = "def f(x):\n return x + 1\n" + code = "def f(x):\n return x + 1" st1 = parser.suite(code) st2 = st1.totuple(line_info=1, col_info=1) @@ -243,9 +243,9 @@ (14, '+', 2, 13), (2, '1', 2, 15), (4, '', 2, 16), - (6, '', 3, -1), - (4, '', 3, -1), - (0, '', 3, -1)], + (6, '', 2, -1), + (4, '', 2, -1), + (0, '', 2, -1)], terminals) From python-checkins at python.org Sun Dec 6 22:28:46 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 06 Dec 2009 21:28:46 -0000 Subject: [Python-checkins] r76697 - svn:log Message-ID: Author: benjamin.peterson Revision: 76697 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -fix test_parser and tokenizer tweak \ No newline at end of file +fix test_parser from tokenizer tweak From solipsis at pitrou.net Mon Dec 7 00:47:05 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 7 Dec 2009 00:47:05 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76693): sum=12 Message-ID: <20091206234705.D68A717759@ns6635.ovh.net> py3k results for svn r76693 (hg cset c9097fe32141) -------------------------------------------------- test_urllib leaked [2, 8, 2] references, sum=12 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogNhyM8z', '-x', 'test_httpservers'] From python-checkins at python.org Mon Dec 7 20:34:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 07 Dec 2009 19:34:59 -0000 Subject: [Python-checkins] r76698 - python/branches/py3k/Objects/longobject.c Message-ID: Author: mark.dickinson Date: Mon Dec 7 20:34:59 2009 New Revision: 76698 Log: Fix error message, for consistency with messages for % and //, and for consistency with trunk 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 Dec 7 20:34:59 2009 @@ -3231,7 +3231,7 @@ if (bd == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, - "int division or modulo by zero"); + "integer division or modulo by zero"); return NULL; } From python-checkins at python.org Mon Dec 7 20:35:31 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 07 Dec 2009 19:35:31 -0000 Subject: [Python-checkins] r76699 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Mon Dec 7 20:35:31 2009 New Revision: 76699 Log: Blocked revisions 76698 via svnmerge ........ r76698 | mark.dickinson | 2009-12-07 19:34:59 +0000 (Mon, 07 Dec 2009) | 1 line Fix error message, for consistency with messages for % and //, and for consistency with trunk ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Dec 7 23:52:44 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 07 Dec 2009 22:52:44 -0000 Subject: [Python-checkins] r76700 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Mon Dec 7 23:52:43 2009 New Revision: 76700 Log: removed implementation details and more info on Requires-Dist vs Require Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Mon Dec 7 23:52:43 2009 @@ -26,9 +26,10 @@ `latest` one, regardless of the expected semantics. Distutils will soon extend its capabilities to allow distributions to express a -dependency on other distributions through the `Requires-Dist` metadata field +dependency on other distributions through the ``Requires-Dist`` metadata field (see PEP 345 [#pep345]_) and it will optionally allow to use that field to -restrict the dependency to a set of compatible versions. +restrict the dependency to a set of compatible versions. Notice that this field +is replacing ``Requires`` that was expressing dependencies on modules and packages. The ``Requires-Dist`` field will allow a distribution to define a dependency on another package and optionally restrict this dependency to a set of @@ -346,11 +347,6 @@ A class method called ``from_parts`` is available if you want to create an instance by providing the parts that composes the version. -Each part is a tuple and there are three parts: - -- the main version part -- the pre-release part - Examples :: >>> version = RationalVersion.from_parts((1, 0)) From solipsis at pitrou.net Tue Dec 8 00:47:45 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 8 Dec 2009 00:47:45 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76698): sum=16 Message-ID: <20091207234745.E824917759@ns6635.ovh.net> py3k results for svn r76698 (hg cset f9876174e3f0) -------------------------------------------------- test_urllib leaked [2, 8, 6] references, sum=16 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogTL8zFM', '-x', 'test_httpservers'] From python-checkins at python.org Tue Dec 8 03:37:05 2009 From: python-checkins at python.org (andrew.kuchling) Date: Tue, 08 Dec 2009 02:37:05 -0000 Subject: [Python-checkins] r76701 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: andrew.kuchling Date: Tue Dec 8 03:37:05 2009 New Revision: 76701 Log: Typo fix; grammar fix 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 Tue Dec 8 03:37:05 2009 @@ -70,7 +70,7 @@ * A version of the :mod:`io` library, rewritten in C for performance. * The ordered-dictionary type described in :ref:`pep-0372`. -* The new format specified described in :ref:`pep-0378`. +* The new format specifier described in :ref:`pep-0378`. * The :class:`memoryview` object. * A small subset of the :mod:`importlib` module `described below <#importlib-section>`__. @@ -515,7 +515,7 @@ more sensible for numeric types. (Changed by Mark Dickinson; :issue:`6857`.) * Distutils is being more actively developed, thanks to Tarek Ziade - has taken over maintenance of the package. A new + who has taken over maintenance of the package. A new :file:`setup.py` subcommand, ``check``, will check that the arguments being passed to the :func:`setup` function are complete and correct (:issue:`5732`). @@ -1076,5 +1076,5 @@ The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this -article: Hugh Secker-Walker. +article: Ryan Lovett, Hugh Secker-Walker. From python-checkins at python.org Tue Dec 8 09:56:49 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 08 Dec 2009 08:56:49 -0000 Subject: [Python-checkins] r76702 - in python/trunk: Doc/distutils/examples.rst Doc/whatsnew/2.7.rst Lib/distutils/dist.py Lib/distutils/tests/test_dist.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Tue Dec 8 09:56:49 2009 New Revision: 76702 Log: Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata so we can read back PKG-INFO files Modified: python/trunk/Doc/distutils/examples.rst python/trunk/Doc/whatsnew/2.7.rst python/trunk/Lib/distutils/dist.py python/trunk/Lib/distutils/tests/test_dist.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/distutils/examples.rst ============================================================================== --- python/trunk/Doc/distutils/examples.rst (original) +++ python/trunk/Doc/distutils/examples.rst Tue Dec 8 09:56:49 2009 @@ -285,6 +285,48 @@ warning: check: Title underline too short. (line 2) warning: check: Could not finish the parsing. +Reading the metadata +===================== + +The :func:`distutils.core.setup` function provides a command-line interface +that allows you to query the metadata fields of a project through the +`setup.py` script of a given project:: + + $ python setup.py --name + distribute + +This call reads the `name` metadata by running the +:func:`distutils.core.setup` function. Although, when a source or binary +distribution is created with Distutils, the metadata fields are written +in a static file called :file:`PKG-INFO`. When a Distutils-based project is +installed in Python, the :file:`PKG-INFO` file is copied alongside the modules +and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`, +where `NAME` is the name of the project, `VERSION` its version as defined +in the Metadata, and `pyX.X` the major and minor version of Python like +`2.7` or `3.2`. + +You can read back this static file, by using the +:class:`distutils.dist.DistributionMetadata` class and its +:func:`read_pkg_file` method:: + + >>> from distutils.dist import DistributionMetadata + >>> metadata = DistributionMetadata() + >>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info')) + >>> metadata.name + 'distribute' + >>> metadata.version + '0.6.8' + >>> metadata.description + 'Easily download, build, install, upgrade, and uninstall Python packages' + +Notice that the class can also be instanciated with a metadata file path to +loads its values:: + + >>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info' + >>> DistributionMetadata(pkg_info_path).name + 'distribute' + + .. % \section{Multiple extension modules} .. % \label{multiple-ext} Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Tue Dec 8 09:56:49 2009 @@ -539,6 +539,10 @@ process, but instead simply not install the failing extension. (Contributed by Georg Brandl; :issue:`5583`.) + Issue #7457: added a read_pkg_file method to.distutils.dist.DistributionMetadata + see file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata + (:issue:`7457`, added by Tarek). + * The :class:`Fraction` class now accepts two rational numbers as arguments to its constructor. (Implemented by Mark Dickinson; :issue:`5812`.) Modified: python/trunk/Lib/distutils/dist.py ============================================================================== --- python/trunk/Lib/distutils/dist.py (original) +++ python/trunk/Lib/distutils/dist.py Tue Dec 8 09:56:49 2009 @@ -7,6 +7,7 @@ __revision__ = "$Id$" import sys, os, re +import rfc822 try: import warnings @@ -1006,6 +1007,20 @@ # to self.metadata.get_XXX. The actual code is in the # DistributionMetadata class, below. +class _MetadataMessage(rfc822.Message): + + def read_field(self, name): + value = self[name] + if value == 'UNKNOWN': + return None + return value + + def getheaders(self, name, default): + values = rfc822.Message.getheaders(self, name) + if values == []: + return None + return values + class DistributionMetadata: """Dummy class to hold the distribution meta-data: name, version, author, and so forth. @@ -1021,25 +1036,67 @@ "provides", "requires", "obsoletes", ) - def __init__ (self): - self.name = None - self.version = None - self.author = None - self.author_email = None + def __init__(self, path=None): + if path is not None: + self.read_pkg_file(open(path)) + else: + self.name = None + self.version = None + self.author = None + self.author_email = None + self.maintainer = None + self.maintainer_email = None + self.url = None + self.license = None + self.description = None + self.long_description = None + self.keywords = None + self.platforms = None + self.classifiers = None + self.download_url = None + # PEP 314 + self.provides = None + self.requires = None + self.obsoletes = None + + def read_pkg_file(self, file): + """Reads the metadata values from a file object.""" + msg = _MetadataMessage(file) + metadata_version = msg['metadata-version'] + self.name = msg.read_field('name') + self.version = msg.read_field('version') + self.description = msg.read_field('summary') + # we are filling author only. + self.author = msg.read_field('author') self.maintainer = None + self.author_email = msg.read_field('author-email') self.maintainer_email = None - self.url = None - self.license = None - self.description = None - self.long_description = None - self.keywords = None - self.platforms = None - self.classifiers = None - self.download_url = None - # PEP 314 - self.provides = None - self.requires = None - self.obsoletes = None + self.url = msg.read_field('home-page') + self.license = msg.read_field('license') + + if 'download-url' in msg: + self.download_url = msg.read_field('download-url') + else: + self.download_url = None + + self.long_description = msg.read_field('description') + self.description = msg.read_field('summary') + + if 'keywords' in msg: + self.keywords = msg.read_field('keywords').split(',') + + self.platforms = msg.getheaders('platform', None) + self.classifiers = msg.getheaders('classifier', None) + + # PEP 314 - these fields only exist in 1.1 + if metadata_version == '1.1': + self.requires = msg.getheaders('requires', None) + self.provides = msg.getheaders('provides', None) + self.obsoletes = msg.getheaders('obsoletes', None) + else: + self.requires = None + self.provides = None + self.obsoletes = None def write_pkg_info(self, base_dir): """Write the PKG-INFO file into the release tree. Modified: python/trunk/Lib/distutils/tests/test_dist.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_dist.py (original) +++ python/trunk/Lib/distutils/tests/test_dist.py Tue Dec 8 09:56:49 2009 @@ -8,10 +8,9 @@ import warnings import textwrap -from distutils.dist import Distribution, fix_help_options +from distutils.dist import Distribution, fix_help_options, DistributionMetadata from distutils.cmd import Command import distutils.dist - from test.test_support import TESTFN, captured_stdout from distutils.tests import support @@ -239,6 +238,7 @@ # make sure --no-user-cfg disables the user cfg file self.assertEquals(len(all_files)-1, len(files)) + class MetadataTestCase(support.TempdirManager, support.EnvironGuard, unittest.TestCase): @@ -397,6 +397,33 @@ meta = meta.replace('\n' + 8 * ' ', '\n') self.assertTrue(long_desc in meta) + def test_read_metadata(self): + attrs = {"name": "package", + "version": "1.0", + "long_description": "desc", + "description": "xxx", + "download_url": "http://example.com", + "keywords": ['one', 'two'], + "requires": ['foo']} + + dist = Distribution(attrs) + metadata = dist.metadata + + # write it then reloads it + PKG_INFO = StringIO.StringIO() + metadata.write_pkg_file(PKG_INFO) + PKG_INFO.seek(0) + metadata.read_pkg_file(PKG_INFO) + + self.assertEquals(metadata.name, "package") + self.assertEquals(metadata.version, "1.0") + self.assertEquals(metadata.description, "xxx") + self.assertEquals(metadata.download_url, 'http://example.com') + self.assertEquals(metadata.keywords, ['one', 'two']) + self.assertEquals(metadata.platforms, ['UNKNOWN']) + self.assertEquals(metadata.obsoletes, None) + self.assertEquals(metadata.requires, ['foo']) + def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(DistributionTestCase)) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Dec 8 09:56:49 2009 @@ -15,6 +15,8 @@ Library ------- +- Issue #7457: added a read_pkg_file method to + distutils.dist.DistributionMetadata. What's New in Python 2.7 alpha 1 ================================ From python-checkins at python.org Tue Dec 8 09:58:10 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 08 Dec 2009 08:58:10 -0000 Subject: [Python-checkins] r76703 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Tue Dec 8 09:58:10 2009 New Revision: 76703 Log: Blocked revisions 76702 via svnmerge ........ r76702 | tarek.ziade | 2009-12-08 09:56:49 +0100 (Tue, 08 Dec 2009) | 1 line Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata so we can read back PKG-INFO files ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Dec 8 10:39:51 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 08 Dec 2009 09:39:51 -0000 Subject: [Python-checkins] r76704 - python/trunk/Lib/distutils/dist.py Message-ID: Author: tarek.ziade Date: Tue Dec 8 10:39:51 2009 New Revision: 76704 Log: removed the usage of rfc822 in favor of email.message.Message Modified: python/trunk/Lib/distutils/dist.py Modified: python/trunk/Lib/distutils/dist.py ============================================================================== --- python/trunk/Lib/distutils/dist.py (original) +++ python/trunk/Lib/distutils/dist.py Tue Dec 8 10:39:51 2009 @@ -7,7 +7,7 @@ __revision__ = "$Id$" import sys, os, re -import rfc822 +from email import message_from_file try: import warnings @@ -1007,20 +1007,6 @@ # to self.metadata.get_XXX. The actual code is in the # DistributionMetadata class, below. -class _MetadataMessage(rfc822.Message): - - def read_field(self, name): - value = self[name] - if value == 'UNKNOWN': - return None - return value - - def getheaders(self, name, default): - values = rfc822.Message.getheaders(self, name) - if values == []: - return None - return values - class DistributionMetadata: """Dummy class to hold the distribution meta-data: name, version, author, and so forth. @@ -1061,38 +1047,51 @@ def read_pkg_file(self, file): """Reads the metadata values from a file object.""" - msg = _MetadataMessage(file) + msg = message_from_file(file) + + def _read_field(name): + value = msg[name] + if value == 'UNKNOWN': + return None + return value + + def _read_list(name): + values = msg.get_all(name, None) + if values == []: + return None + return values + metadata_version = msg['metadata-version'] - self.name = msg.read_field('name') - self.version = msg.read_field('version') - self.description = msg.read_field('summary') + self.name = _read_field('name') + self.version = _read_field('version') + self.description = _read_field('summary') # we are filling author only. - self.author = msg.read_field('author') + self.author = _read_field('author') self.maintainer = None - self.author_email = msg.read_field('author-email') + self.author_email = _read_field('author-email') self.maintainer_email = None - self.url = msg.read_field('home-page') - self.license = msg.read_field('license') + self.url = _read_field('home-page') + self.license = _read_field('license') if 'download-url' in msg: - self.download_url = msg.read_field('download-url') + self.download_url = _read_field('download-url') else: self.download_url = None - self.long_description = msg.read_field('description') - self.description = msg.read_field('summary') + self.long_description = _read_field('description') + self.description = _read_field('summary') if 'keywords' in msg: - self.keywords = msg.read_field('keywords').split(',') + self.keywords = _read_field('keywords').split(',') - self.platforms = msg.getheaders('platform', None) - self.classifiers = msg.getheaders('classifier', None) + self.platforms = _read_list('platform') + self.classifiers = _read_list('classifier') # PEP 314 - these fields only exist in 1.1 if metadata_version == '1.1': - self.requires = msg.getheaders('requires', None) - self.provides = msg.getheaders('provides', None) - self.obsoletes = msg.getheaders('obsoletes', None) + self.requires = _read_list('requires') + self.provides = _read_list('provides') + self.obsoletes = _read_list('obsoletes') else: self.requires = None self.provides = None From python-checkins at python.org Tue Dec 8 10:40:27 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 08 Dec 2009 09:40:27 -0000 Subject: [Python-checkins] r76705 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Tue Dec 8 10:40:27 2009 New Revision: 76705 Log: Blocked revisions 76704 via svnmerge ........ r76704 | tarek.ziade | 2009-12-08 10:39:51 +0100 (Tue, 08 Dec 2009) | 1 line removed the usage of rfc822 in favor of email.message.Message ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Dec 8 10:45:26 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 08 Dec 2009 09:45:26 -0000 Subject: [Python-checkins] r76706 - in python/branches/py3k: Doc/distutils/examples.rst Doc/whatsnew/2.7.rst Lib/distutils/dist.py Lib/distutils/tests/test_dist.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Tue Dec 8 10:45:25 2009 New Revision: 76706 Log: Merged revisions 76702,76704 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76702 | tarek.ziade | 2009-12-08 09:56:49 +0100 (Tue, 08 Dec 2009) | 1 line Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata so we can read back PKG-INFO files ........ r76704 | tarek.ziade | 2009-12-08 10:39:51 +0100 (Tue, 08 Dec 2009) | 1 line removed the usage of rfc822 in favor of email.message.Message ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/distutils/examples.rst python/branches/py3k/Doc/whatsnew/2.7.rst python/branches/py3k/Lib/distutils/dist.py python/branches/py3k/Lib/distutils/tests/test_dist.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/distutils/examples.rst ============================================================================== --- python/branches/py3k/Doc/distutils/examples.rst (original) +++ python/branches/py3k/Doc/distutils/examples.rst Tue Dec 8 10:45:25 2009 @@ -285,6 +285,48 @@ warning: check: Title underline too short. (line 2) warning: check: Could not finish the parsing. +Reading the metadata +===================== + +The :func:`distutils.core.setup` function provides a command-line interface +that allows you to query the metadata fields of a project through the +`setup.py` script of a given project:: + + $ python setup.py --name + distribute + +This call reads the `name` metadata by running the +:func:`distutils.core.setup` function. Although, when a source or binary +distribution is created with Distutils, the metadata fields are written +in a static file called :file:`PKG-INFO`. When a Distutils-based project is +installed in Python, the :file:`PKG-INFO` file is copied alongside the modules +and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`, +where `NAME` is the name of the project, `VERSION` its version as defined +in the Metadata, and `pyX.X` the major and minor version of Python like +`2.7` or `3.2`. + +You can read back this static file, by using the +:class:`distutils.dist.DistributionMetadata` class and its +:func:`read_pkg_file` method:: + + >>> from distutils.dist import DistributionMetadata + >>> metadata = DistributionMetadata() + >>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info')) + >>> metadata.name + 'distribute' + >>> metadata.version + '0.6.8' + >>> metadata.description + 'Easily download, build, install, upgrade, and uninstall Python packages' + +Notice that the class can also be instanciated with a metadata file path to +loads its values:: + + >>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info' + >>> DistributionMetadata(pkg_info_path).name + 'distribute' + + .. % \section{Multiple extension modules} .. % \label{multiple-ext} 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 Tue Dec 8 10:45:25 2009 @@ -539,6 +539,10 @@ process, but instead simply not install the failing extension. (Contributed by Georg Brandl; :issue:`5583`.) + Issue #7457: added a read_pkg_file method to.distutils.dist.DistributionMetadata + see file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata + (:issue:`7457`, added by Tarek). + * The :class:`Fraction` class now accepts two rational numbers as arguments to its constructor. (Implemented by Mark Dickinson; :issue:`5812`.) Modified: python/branches/py3k/Lib/distutils/dist.py ============================================================================== --- python/branches/py3k/Lib/distutils/dist.py (original) +++ python/branches/py3k/Lib/distutils/dist.py Tue Dec 8 10:45:25 2009 @@ -7,6 +7,7 @@ __revision__ = "$Id$" import sys, os, re +from email import message_from_file try: import warnings @@ -1014,25 +1015,80 @@ "provides", "requires", "obsoletes", ) - def __init__ (self): - self.name = None - self.version = None - self.author = None - self.author_email = None + def __init__(self, path=None): + if path is not None: + self.read_pkg_file(open(path)) + else: + self.name = None + self.version = None + self.author = None + self.author_email = None + self.maintainer = None + self.maintainer_email = None + self.url = None + self.license = None + self.description = None + self.long_description = None + self.keywords = None + self.platforms = None + self.classifiers = None + self.download_url = None + # PEP 314 + self.provides = None + self.requires = None + self.obsoletes = None + + def read_pkg_file(self, file): + """Reads the metadata values from a file object.""" + msg = message_from_file(file) + + def _read_field(name): + value = msg[name] + if value == 'UNKNOWN': + return None + return value + + def _read_list(name): + values = msg.get_all(name, None) + if values == []: + return None + return values + + metadata_version = msg['metadata-version'] + self.name = _read_field('name') + self.version = _read_field('version') + self.description = _read_field('summary') + # we are filling author only. + self.author = _read_field('author') self.maintainer = None + self.author_email = _read_field('author-email') self.maintainer_email = None - self.url = None - self.license = None - self.description = None - self.long_description = None - self.keywords = None - self.platforms = None - self.classifiers = None - self.download_url = None - # PEP 314 - self.provides = None - self.requires = None - self.obsoletes = None + self.url = _read_field('home-page') + self.license = _read_field('license') + + if 'download-url' in msg: + self.download_url = _read_field('download-url') + else: + self.download_url = None + + self.long_description = _read_field('description') + self.description = _read_field('summary') + + if 'keywords' in msg: + self.keywords = _read_field('keywords').split(',') + + self.platforms = _read_list('platform') + self.classifiers = _read_list('classifier') + + # PEP 314 - these fields only exist in 1.1 + if metadata_version == '1.1': + self.requires = _read_list('requires') + self.provides = _read_list('provides') + self.obsoletes = _read_list('obsoletes') + else: + self.requires = None + self.provides = None + self.obsoletes = None def write_pkg_info(self, base_dir): """Write the PKG-INFO file into the release tree. Modified: python/branches/py3k/Lib/distutils/tests/test_dist.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_dist.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_dist.py Tue Dec 8 10:45:25 2009 @@ -7,7 +7,7 @@ import warnings import textwrap -from distutils.dist import Distribution, fix_help_options +from distutils.dist import Distribution, fix_help_options, DistributionMetadata from distutils.cmd import Command import distutils.dist @@ -369,6 +369,33 @@ meta = meta.replace('\n' + 8 * ' ', '\n') self.assertTrue(long_desc in meta) + def test_read_metadata(self): + attrs = {"name": "package", + "version": "1.0", + "long_description": "desc", + "description": "xxx", + "download_url": "http://example.com", + "keywords": ['one', 'two'], + "requires": ['foo']} + + dist = Distribution(attrs) + metadata = dist.metadata + + # write it then reloads it + PKG_INFO = io.StringIO() + metadata.write_pkg_file(PKG_INFO) + PKG_INFO.seek(0) + metadata.read_pkg_file(PKG_INFO) + + self.assertEquals(metadata.name, "package") + self.assertEquals(metadata.version, "1.0") + self.assertEquals(metadata.description, "xxx") + self.assertEquals(metadata.download_url, 'http://example.com') + self.assertEquals(metadata.keywords, ['one', 'two']) + self.assertEquals(metadata.platforms, ['UNKNOWN']) + self.assertEquals(metadata.obsoletes, None) + self.assertEquals(metadata.requires, ['foo']) + def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(DistributionTestCase)) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Dec 8 10:45:25 2009 @@ -154,6 +154,9 @@ Library ------- +- Issue #7457: added a read_pkg_file method to + distutils.dist.DistributionMetadata. + - logging: Added optional `secure` parameter to SMTPHandler, to enable use of TLS with authentication credentials. From python-checkins at python.org Tue Dec 8 11:03:09 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 08 Dec 2009 10:03:09 -0000 Subject: [Python-checkins] r76707 - python/branches/release31-maint Message-ID: Author: tarek.ziade Date: Tue Dec 8 11:03:09 2009 New Revision: 76707 Log: Blocked revisions 76706 via svnmerge ................ r76706 | tarek.ziade | 2009-12-08 10:45:25 +0100 (Tue, 08 Dec 2009) | 13 lines Merged revisions 76702,76704 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76702 | tarek.ziade | 2009-12-08 09:56:49 +0100 (Tue, 08 Dec 2009) | 1 line Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata so we can read back PKG-INFO files ........ r76704 | tarek.ziade | 2009-12-08 10:39:51 +0100 (Tue, 08 Dec 2009) | 1 line removed the usage of rfc822 in favor of email.message.Message ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Tue Dec 8 16:40:51 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 15:40:51 -0000 Subject: [Python-checkins] r76708 - in python/trunk: Lib/json/tests/test_speedups.py Misc/NEWS Modules/_json.c Message-ID: Author: antoine.pitrou Date: Tue Dec 8 16:40:51 2009 New Revision: 76708 Log: Issue #6986: Fix crash in the JSON C accelerator when called with the wrong parameter types. Patch by Victor Stinner. Modified: python/trunk/Lib/json/tests/test_speedups.py python/trunk/Misc/NEWS python/trunk/Modules/_json.c Modified: python/trunk/Lib/json/tests/test_speedups.py ============================================================================== --- python/trunk/Lib/json/tests/test_speedups.py (original) +++ python/trunk/Lib/json/tests/test_speedups.py Tue Dec 8 16:40:51 2009 @@ -1,8 +1,7 @@ import decimal from unittest import TestCase -from json import decoder -from json import encoder +from json import decoder, encoder, scanner class TestSpeedups(TestCase): def test_scanstring(self): @@ -13,3 +12,13 @@ self.assertEquals(encoder.encode_basestring_ascii.__module__, "_json") self.assertTrue(encoder.encode_basestring_ascii is encoder.c_encode_basestring_ascii) + +class TestDecode(TestCase): + def test_make_scanner(self): + self.assertRaises(AttributeError, scanner.c_make_scanner, 1) + + def test_make_encoder(self): + self.assertRaises(TypeError, encoder.c_make_encoder, + None, + "\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75", + None) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Dec 8 16:40:51 2009 @@ -509,6 +509,9 @@ Library ------- +- Issue #6986: Fix crash in the JSON C accelerator when called with the + wrong parameter types. Patch by Victor Stinner. + - logging: Added optional `secure` parameter to SMTPHandler, to enable use of TLS with authentication credentials. Modified: python/trunk/Modules/_json.c ============================================================================== --- python/trunk/Modules/_json.c (original) +++ python/trunk/Modules/_json.c Tue Dec 8 16:40:51 2009 @@ -1731,6 +1731,8 @@ /* PyString_AS_STRING is used on encoding */ s->encoding = PyObject_GetAttrString(ctx, "encoding"); + if (s->encoding == NULL) + goto bail; if (s->encoding == Py_None) { Py_DECREF(Py_None); s->encoding = PyString_InternFromString(DEFAULT_ENCODING); @@ -1847,15 +1849,28 @@ static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL}; PyEncoderObject *s; - PyObject *allow_nan; + PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; + PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan; assert(PyEncoder_Check(self)); s = (PyEncoderObject *)self; if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist, - &s->markers, &s->defaultfn, &s->encoder, &s->indent, &s->key_separator, &s->item_separator, &s->sort_keys, &s->skipkeys, &allow_nan)) + &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator, + &sort_keys, &skipkeys, &allow_nan)) return -1; + s->markers = markers; + s->defaultfn = defaultfn; + s->encoder = encoder; + s->indent = indent; + s->key_separator = key_separator; + s->item_separator = item_separator; + s->sort_keys = sort_keys; + s->skipkeys = skipkeys; + s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); + s->allow_nan = PyObject_IsTrue(allow_nan); + Py_INCREF(s->markers); Py_INCREF(s->defaultfn); Py_INCREF(s->encoder); @@ -1864,8 +1879,6 @@ Py_INCREF(s->item_separator); Py_INCREF(s->sort_keys); Py_INCREF(s->skipkeys); - s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); - s->allow_nan = PyObject_IsTrue(allow_nan); return 0; } From python-checkins at python.org Tue Dec 8 16:41:50 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 15:41:50 -0000 Subject: [Python-checkins] r76709 - python/branches/release26-maint Message-ID: Author: antoine.pitrou Date: Tue Dec 8 16:41:50 2009 New Revision: 76709 Log: Blocked revisions 76708 via svnmerge ........ r76708 | antoine.pitrou | 2009-12-08 16:40:51 +0100 (mar., 08 d?c. 2009) | 4 lines Issue #6986: Fix crash in the JSON C accelerator when called with the wrong parameter types. Patch by Victor Stinner. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Dec 8 16:57:31 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 15:57:31 -0000 Subject: [Python-checkins] r76710 - in python/branches/py3k: Lib/json/tests/test_speedups.py Misc/NEWS Modules/_json.c Message-ID: Author: antoine.pitrou Date: Tue Dec 8 16:57:31 2009 New Revision: 76710 Log: Merged revisions 76708 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76708 | antoine.pitrou | 2009-12-08 16:40:51 +0100 (mar., 08 d?c. 2009) | 4 lines Issue #6986: Fix crash in the JSON C accelerator when called with the wrong parameter types. Patch by Victor Stinner. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/json/tests/test_speedups.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_json.c Modified: python/branches/py3k/Lib/json/tests/test_speedups.py ============================================================================== --- python/branches/py3k/Lib/json/tests/test_speedups.py (original) +++ python/branches/py3k/Lib/json/tests/test_speedups.py Tue Dec 8 16:57:31 2009 @@ -1,8 +1,7 @@ import decimal from unittest import TestCase -from json import decoder -from json import encoder +from json import decoder, encoder, scanner class TestSpeedups(TestCase): def test_scanstring(self): @@ -13,3 +12,13 @@ self.assertEquals(encoder.encode_basestring_ascii.__module__, "_json") self.assertTrue(encoder.encode_basestring_ascii is encoder.c_encode_basestring_ascii) + +class TestDecode(TestCase): + def test_make_scanner(self): + self.assertRaises(AttributeError, scanner.c_make_scanner, 1) + + def test_make_encoder(self): + self.assertRaises(TypeError, encoder.c_make_encoder, + (True, False), + b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75", + None) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Dec 8 16:57:31 2009 @@ -154,6 +154,9 @@ Library ------- +- Issue #6986: Fix crash in the JSON C accelerator when called with the + wrong parameter types. Patch by Victor Stinner. + - Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata. Modified: python/branches/py3k/Modules/_json.c ============================================================================== --- python/branches/py3k/Modules/_json.c (original) +++ python/branches/py3k/Modules/_json.c Tue Dec 8 16:57:31 2009 @@ -1123,15 +1123,28 @@ static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL}; PyEncoderObject *s; - PyObject *allow_nan; + PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; + PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan; assert(PyEncoder_Check(self)); s = (PyEncoderObject *)self; if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist, - &s->markers, &s->defaultfn, &s->encoder, &s->indent, &s->key_separator, &s->item_separator, &s->sort_keys, &s->skipkeys, &allow_nan)) + &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator, + &sort_keys, &skipkeys, &allow_nan)) return -1; + s->markers = markers; + s->defaultfn = defaultfn; + s->encoder = encoder; + s->indent = indent; + s->key_separator = key_separator; + s->item_separator = item_separator; + s->sort_keys = sort_keys; + s->skipkeys = skipkeys; + s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); + s->allow_nan = PyObject_IsTrue(allow_nan); + Py_INCREF(s->markers); Py_INCREF(s->defaultfn); Py_INCREF(s->encoder); @@ -1140,8 +1153,6 @@ Py_INCREF(s->item_separator); Py_INCREF(s->sort_keys); Py_INCREF(s->skipkeys); - s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); - s->allow_nan = PyObject_IsTrue(allow_nan); return 0; } From python-checkins at python.org Tue Dec 8 17:00:04 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 16:00:04 -0000 Subject: [Python-checkins] r76711 - in python/branches/release31-maint: Lib/json/tests/test_speedups.py Misc/NEWS Modules/_json.c Message-ID: Author: antoine.pitrou Date: Tue Dec 8 17:00:03 2009 New Revision: 76711 Log: Merged revisions 76710 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76710 | antoine.pitrou | 2009-12-08 16:57:31 +0100 (mar., 08 d?c. 2009) | 10 lines Merged revisions 76708 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76708 | antoine.pitrou | 2009-12-08 16:40:51 +0100 (mar., 08 d?c. 2009) | 4 lines Issue #6986: Fix crash in the JSON C accelerator when called with the wrong parameter types. Patch by Victor Stinner. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/json/tests/test_speedups.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/_json.c Modified: python/branches/release31-maint/Lib/json/tests/test_speedups.py ============================================================================== --- python/branches/release31-maint/Lib/json/tests/test_speedups.py (original) +++ python/branches/release31-maint/Lib/json/tests/test_speedups.py Tue Dec 8 17:00:03 2009 @@ -1,8 +1,7 @@ import decimal from unittest import TestCase -from json import decoder -from json import encoder +from json import decoder, encoder, scanner class TestSpeedups(TestCase): def test_scanstring(self): @@ -13,3 +12,13 @@ self.assertEquals(encoder.encode_basestring_ascii.__module__, "_json") self.assertTrue(encoder.encode_basestring_ascii is encoder.c_encode_basestring_ascii) + +class TestDecode(TestCase): + def test_make_scanner(self): + self.assertRaises(AttributeError, scanner.c_make_scanner, 1) + + def test_make_encoder(self): + self.assertRaises(TypeError, encoder.c_make_encoder, + (True, False), + b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75", + None) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Tue Dec 8 17:00:03 2009 @@ -55,6 +55,9 @@ Library ------- +- Issue #6986: Fix crash in the JSON C accelerator when called with the + wrong parameter types. Patch by Victor Stinner. + - Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is generated in Distutils. Patch by Stephen Emslie. Modified: python/branches/release31-maint/Modules/_json.c ============================================================================== --- python/branches/release31-maint/Modules/_json.c (original) +++ python/branches/release31-maint/Modules/_json.c Tue Dec 8 17:00:03 2009 @@ -1123,15 +1123,28 @@ static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL}; PyEncoderObject *s; - PyObject *allow_nan; + PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; + PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan; assert(PyEncoder_Check(self)); s = (PyEncoderObject *)self; if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist, - &s->markers, &s->defaultfn, &s->encoder, &s->indent, &s->key_separator, &s->item_separator, &s->sort_keys, &s->skipkeys, &allow_nan)) + &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator, + &sort_keys, &skipkeys, &allow_nan)) return -1; + s->markers = markers; + s->defaultfn = defaultfn; + s->encoder = encoder; + s->indent = indent; + s->key_separator = key_separator; + s->item_separator = item_separator; + s->sort_keys = sort_keys; + s->skipkeys = skipkeys; + s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); + s->allow_nan = PyObject_IsTrue(allow_nan); + Py_INCREF(s->markers); Py_INCREF(s->defaultfn); Py_INCREF(s->encoder); @@ -1140,8 +1153,6 @@ Py_INCREF(s->item_separator); Py_INCREF(s->sort_keys); Py_INCREF(s->skipkeys); - s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); - s->allow_nan = PyObject_IsTrue(allow_nan); return 0; } From python-checkins at python.org Tue Dec 8 17:32:53 2009 From: python-checkins at python.org (ronald.oussoren) Date: Tue, 08 Dec 2009 16:32:53 -0000 Subject: [Python-checkins] r76712 - python/trunk/Include/pymacconfig.h Message-ID: Author: ronald.oussoren Date: Tue Dec 8 17:32:52 2009 New Revision: 76712 Log: Fix for issue 7452: HAVE_GCC_ASM_FOR_X87 gets set when doing a universal build on an i386 based machine, but should only be active when compiling the x86 part of the universal binary. Modified: python/trunk/Include/pymacconfig.h Modified: python/trunk/Include/pymacconfig.h ============================================================================== --- python/trunk/Include/pymacconfig.h (original) +++ python/trunk/Include/pymacconfig.h Tue Dec 8 17:32:52 2009 @@ -22,6 +22,7 @@ # undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 # undef DOUBLE_IS_BIG_ENDIAN_IEEE754 # undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +# undef HAVE_GCC_ASM_FOR_X87 # undef VA_LIST_IS_ARRAY # if defined(__LP64__) && defined(__x86_64__) @@ -79,6 +80,10 @@ #define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #endif /* __BIG_ENDIAN */ +#ifdef __i386__ +# define HAVE_GCC_ASM_FOR_X87 +#endif + /* * The definition in pyconfig.h is only valid on the OS release * where configure ran on and not necessarily for all systems where From python-checkins at python.org Tue Dec 8 17:35:28 2009 From: python-checkins at python.org (ronald.oussoren) Date: Tue, 08 Dec 2009 16:35:28 -0000 Subject: [Python-checkins] r76713 - in python/branches/py3k: Include/pymacconfig.h Message-ID: Author: ronald.oussoren Date: Tue Dec 8 17:35:28 2009 New Revision: 76713 Log: Merged revisions 76712 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76712 | ronald.oussoren | 2009-12-08 17:32:52 +0100 (Tue, 08 Dec 2009) | 4 lines Fix for issue 7452: HAVE_GCC_ASM_FOR_X87 gets set when doing a universal build on an i386 based machine, but should only be active when compiling the x86 part of the universal binary. ........ 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 Tue Dec 8 17:35:28 2009 @@ -22,8 +22,6 @@ # 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 @@ -82,6 +80,10 @@ #define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #endif /* __BIG_ENDIAN */ +#ifdef __i386__ +# define HAVE_GCC_ASM_FOR_X87 +#endif + /* * The definition in pyconfig.h is only valid on the OS release * where configure ran on and not necessarily for all systems where From python-checkins at python.org Tue Dec 8 17:36:47 2009 From: python-checkins at python.org (ronald.oussoren) Date: Tue, 08 Dec 2009 16:36:47 -0000 Subject: [Python-checkins] r76714 - in python/branches/release31-maint: Include/pymacconfig.h Message-ID: Author: ronald.oussoren Date: Tue Dec 8 17:36:47 2009 New Revision: 76714 Log: Merged revisions 76713 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76713 | ronald.oussoren | 2009-12-08 17:35:28 +0100 (Tue, 08 Dec 2009) | 11 lines Merged revisions 76712 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76712 | ronald.oussoren | 2009-12-08 17:32:52 +0100 (Tue, 08 Dec 2009) | 4 lines Fix for issue 7452: HAVE_GCC_ASM_FOR_X87 gets set when doing a universal build on an i386 based machine, but should only be active when compiling the x86 part of the universal binary. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Include/pymacconfig.h Modified: python/branches/release31-maint/Include/pymacconfig.h ============================================================================== --- python/branches/release31-maint/Include/pymacconfig.h (original) +++ python/branches/release31-maint/Include/pymacconfig.h Tue Dec 8 17:36:47 2009 @@ -20,8 +20,6 @@ # 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 @@ -76,6 +74,10 @@ #define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #endif /* __BIG_ENDIAN */ +#ifdef __i386__ +# define HAVE_GCC_ASM_FOR_X87 +#endif + /* * The definition in pyconfig.h is only valid on the OS release * where configure ran on and not necessarily for all systems where From python-checkins at python.org Tue Dec 8 17:39:37 2009 From: python-checkins at python.org (ronald.oussoren) Date: Tue, 08 Dec 2009 16:39:37 -0000 Subject: [Python-checkins] r76715 - in python/branches/release26-maint/Mac/Resources/app/Resources/English.lproj/Documentation: ide index.html Message-ID: Author: ronald.oussoren Date: Tue Dec 8 17:39:36 2009 New Revision: 76715 Log: Remove documentation for the no longer existing 'Python IDE' from the Python.app bundle on OSX. This fixes Issue7437, the documentation contained filenames that broke the installer on OSX 10.3. Removed: python/branches/release26-maint/Mac/Resources/app/Resources/English.lproj/Documentation/ide/ Modified: python/branches/release26-maint/Mac/Resources/app/Resources/English.lproj/Documentation/index.html Modified: python/branches/release26-maint/Mac/Resources/app/Resources/English.lproj/Documentation/index.html ============================================================================== --- python/branches/release26-maint/Mac/Resources/app/Resources/English.lproj/Documentation/index.html (original) +++ python/branches/release26-maint/Mac/Resources/app/Resources/English.lproj/Documentation/index.html Tue Dec 8 17:39:36 2009 @@ -22,9 +22,6 @@
    • What is MacPython?
    • -
    • MacPython - Integrated Development Environment Introduction -
    • Python Language and runtime documentation
    • Running Python scripts from the Finder From python-checkins at python.org Tue Dec 8 20:25:52 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 19:25:52 -0000 Subject: [Python-checkins] r76716 - in python/trunk: Lib/test/script_helper.py Misc/ACKS Message-ID: Author: antoine.pitrou Date: Tue Dec 8 20:25:51 2009 New Revision: 76716 Log: Fix the transient refleaks in test_zipimport_support. Diagnosis and original patch by Florent Xicluna (flox). Modified: python/trunk/Lib/test/script_helper.py python/trunk/Misc/ACKS Modified: python/trunk/Lib/test/script_helper.py ============================================================================== --- python/trunk/Lib/test/script_helper.py (original) +++ python/trunk/Lib/test/script_helper.py Tue Dec 8 20:25:51 2009 @@ -30,7 +30,8 @@ data = p.stdout.read() p.stdout.close() # try to cleanup the child so we don't appear to leak when running - # with regrtest -R. This should be a no-op on Windows. + # with regrtest -R. + p.wait() subprocess._cleanup() return data Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Tue Dec 8 20:25:51 2009 @@ -819,6 +819,7 @@ Thomas Wouters Heiko Wundram Doug Wyatt +Florent Xicluna Ka-Ping Yee Bob Yodlowski Danny Yoo From python-checkins at python.org Tue Dec 8 20:27:24 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 19:27:24 -0000 Subject: [Python-checkins] r76717 - in python/branches/py3k: Lib/test/script_helper.py Misc/ACKS Message-ID: Author: antoine.pitrou Date: Tue Dec 8 20:27:24 2009 New Revision: 76717 Log: Merged revisions 76716 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76716 | antoine.pitrou | 2009-12-08 20:25:51 +0100 (mar., 08 d?c. 2009) | 4 lines Fix the transient refleaks in test_zipimport_support. Diagnosis and original patch by Florent Xicluna (flox). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/script_helper.py python/branches/py3k/Misc/ACKS Modified: python/branches/py3k/Lib/test/script_helper.py ============================================================================== --- python/branches/py3k/Lib/test/script_helper.py (original) +++ python/branches/py3k/Lib/test/script_helper.py Tue Dec 8 20:27:24 2009 @@ -30,7 +30,8 @@ data = p.stdout.read() p.stdout.close() # try to cleanup the child so we don't appear to leak when running - # with regrtest -R. This should be a no-op on Windows. + # with regrtest -R. + p.wait() subprocess._cleanup() return data Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Tue Dec 8 20:27:24 2009 @@ -832,6 +832,7 @@ Thomas Wouters Heiko Wundram Doug Wyatt +Florent Xicluna Ka-Ping Yee Bob Yodlowski Danny Yoo From python-checkins at python.org Tue Dec 8 20:35:13 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 19:35:13 -0000 Subject: [Python-checkins] r76718 - python/trunk/Lib/urllib.py Message-ID: Author: antoine.pitrou Date: Tue Dec 8 20:35:12 2009 New Revision: 76718 Log: Fix transient refleaks in test_urllib. Thanks to Florent Xicluna. Modified: python/trunk/Lib/urllib.py Modified: python/trunk/Lib/urllib.py ============================================================================== --- python/trunk/Lib/urllib.py (original) +++ python/trunk/Lib/urllib.py Tue Dec 8 20:35:12 2009 @@ -95,6 +95,8 @@ def urlcleanup(): if _urlopener: _urlopener.cleanup() + _safemaps.clear() + ftpcache.clear() # check for SSL try: From python-checkins at python.org Tue Dec 8 20:38:17 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 19:38:17 -0000 Subject: [Python-checkins] r76719 - in python/branches/py3k: Lib/urllib/parse.py Message-ID: Author: antoine.pitrou Date: Tue Dec 8 20:38:17 2009 New Revision: 76719 Log: Merged revisions 76718 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76718 | antoine.pitrou | 2009-12-08 20:35:12 +0100 (mar., 08 d?c. 2009) | 3 lines Fix transient refleaks in test_urllib. Thanks to Florent Xicluna. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/urllib/parse.py Modified: python/branches/py3k/Lib/urllib/parse.py ============================================================================== --- python/branches/py3k/Lib/urllib/parse.py (original) +++ python/branches/py3k/Lib/urllib/parse.py Tue Dec 8 20:38:17 2009 @@ -41,8 +41,9 @@ _parse_cache = {} def clear_cache(): - """Clear the parse cache.""" + """Clear the parse cache and the quoters cache.""" _parse_cache.clear() + _safe_quoters.clear() class ResultMixin(object): From python-checkins at python.org Tue Dec 8 20:46:38 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 19:46:38 -0000 Subject: [Python-checkins] r76720 - python/trunk/Lib/test/test_pipes.py Message-ID: Author: antoine.pitrou Date: Tue Dec 8 20:46:38 2009 New Revision: 76720 Log: Make test_pipes a little bit more robust. Modified: python/trunk/Lib/test/test_pipes.py Modified: python/trunk/Lib/test/test_pipes.py ============================================================================== --- python/trunk/Lib/test/test_pipes.py (original) +++ python/trunk/Lib/test/test_pipes.py Tue Dec 8 20:46:38 2009 @@ -2,7 +2,7 @@ import os import string import unittest -from test.test_support import TESTFN, run_unittest, unlink +from test.test_support import TESTFN, run_unittest, unlink, reap_children if os.name != 'posix': raise unittest.SkipTest('pipes module only works on posix') @@ -36,7 +36,8 @@ file(TESTFN, 'w').write('hello world #2') t = pipes.Template() t.append(s_command + ' < $IN', pipes.FILEIN_STDOUT) - self.assertEqual(t.open(TESTFN, 'r').read(), 'HELLO WORLD #2') + with t.open(TESTFN, 'r') as f: + self.assertEqual(f.read(), 'HELLO WORLD #2') def testEmptyPipeline1(self): # copy through empty pipe @@ -52,7 +53,8 @@ d = 'empty pipeline test READ' file(TESTFN, 'w').write(d) t=pipes.Template() - self.assertEqual(t.open(TESTFN, 'r').read(), d) + with t.open(TESTFN, 'r') as f: + self.assertEqual(f.read(), d) def testEmptyPipeline3(self): # write through empty pipe @@ -185,6 +187,7 @@ def test_main(): run_unittest(SimplePipeTests) + reap_children() if __name__ == "__main__": test_main() From python-checkins at python.org Tue Dec 8 20:53:24 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 08 Dec 2009 19:53:24 -0000 Subject: [Python-checkins] r76721 - in python/branches/py3k: Lib/test/test_pipes.py Message-ID: Author: antoine.pitrou Date: Tue Dec 8 20:53:23 2009 New Revision: 76721 Log: Merged revisions 76720 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76720 | antoine.pitrou | 2009-12-08 20:46:38 +0100 (mar., 08 d?c. 2009) | 3 lines Make test_pipes a little bit more robust. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_pipes.py Modified: python/branches/py3k/Lib/test/test_pipes.py ============================================================================== --- python/branches/py3k/Lib/test/test_pipes.py (original) +++ python/branches/py3k/Lib/test/test_pipes.py Tue Dec 8 20:53:23 2009 @@ -2,7 +2,7 @@ import os import string import unittest -from test.support import TESTFN, run_unittest, unlink +from test.support import TESTFN, run_unittest, unlink, reap_children if os.name != 'posix': raise unittest.SkipTest('pipes module only works on posix') @@ -36,7 +36,11 @@ open(TESTFN, 'w').write('hello world #2') t = pipes.Template() t.append(s_command + ' < $IN', pipes.FILEIN_STDOUT) - self.assertEqual(t.open(TESTFN, 'r').read(), 'HELLO WORLD #2') + f = t.open(TESTFN, 'r') + try: + self.assertEqual(f.read(), 'HELLO WORLD #2') + finally: + f.close() def testEmptyPipeline1(self): # copy through empty pipe @@ -52,7 +56,11 @@ d = 'empty pipeline test READ' open(TESTFN, 'w').write(d) t=pipes.Template() - self.assertEqual(t.open(TESTFN, 'r').read(), d) + f = t.open(TESTFN, 'r') + try: + self.assertEqual(f.read(), d) + finally: + f.close() def testEmptyPipeline3(self): # write through empty pipe @@ -185,6 +193,7 @@ def test_main(): run_unittest(SimplePipeTests) + reap_children() if __name__ == "__main__": test_main() From python-checkins at python.org Wed Dec 9 00:12:59 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 08 Dec 2009 23:12:59 -0000 Subject: [Python-checkins] r76722 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Wed Dec 9 00:12:59 2009 New Revision: 76722 Log: copy editing Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Wed Dec 9 00:12:59 2009 @@ -21,13 +21,13 @@ In Python there are no real restriction yet on how a project should manage its versions, and how they should be incremented. -Distutile provides a `version` distribution meta-data field but it is freeform and +Distutils provides a `version` distribution meta-data field but it is freeform and current users, such as PyPI usually consider the latest version pushed as the `latest` one, regardless of the expected semantics. Distutils will soon extend its capabilities to allow distributions to express a dependency on other distributions through the ``Requires-Dist`` metadata field -(see PEP 345 [#pep345]_) and it will optionally allow to use that field to +(see PEP 345 [#pep345]_) and it will optionally allow use of that field to restrict the dependency to a set of compatible versions. Notice that this field is replacing ``Requires`` that was expressing dependencies on modules and packages. @@ -37,8 +37,8 @@ Requires-Dist: zope.interface (>3.5.0) -This means that the distribution requires ``zope.interface``, as long as its -version is superior to ``3.5.0``. +This means that the distribution requires ``zope.interface`` with a version +greater than ``3.5.0``. This also means that Python projects will need to follow the same convention as the tool that will be used to install them, so they are able to compare @@ -55,10 +55,10 @@ Requisites and current status ============================= -It is not in the scope of this PEP to come with an universal versioning schema, -intented to support many or all existing versioning schemas. There will always -be competing grammars, either mandated by distro or project policies or by -historical reasons and we cannot expect that to change. +It is not in the scope of this PEP to provide a universal versioning schema intended +to support many or all existing versioning schemas. There will always be competing +grammars, either mandated by distro or project policies or by historical +reasons and we cannot expect that to change. The proposed schema should be able to express the usual versioning semantics, so it's possible to parse any alternative versioning schema and transform it From solipsis at pitrou.net Wed Dec 9 00:47:07 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 9 Dec 2009 00:47:07 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76721): sum=0 Message-ID: <20091208234707.C280317759@ns6635.ovh.net> py3k results for svn r76721 (hg cset b9fa36676ccb) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogXgUVd6', '-x', 'test_httpservers'] From python-checkins at python.org Wed Dec 9 01:01:27 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 09 Dec 2009 00:01:27 -0000 Subject: [Python-checkins] r76723 - in python/branches/py3k/Lib: os.py test/test_popen.py Message-ID: Author: antoine.pitrou Date: Wed Dec 9 01:01:27 2009 New Revision: 76723 Log: Issue #7461: objects returned by os.popen() should support the context manager protocol Modified: python/branches/py3k/Lib/os.py python/branches/py3k/Lib/test/test_popen.py Modified: python/branches/py3k/Lib/os.py ============================================================================== --- python/branches/py3k/Lib/os.py (original) +++ python/branches/py3k/Lib/os.py Wed Dec 9 01:01:27 2009 @@ -650,6 +650,10 @@ return returncode else: return returncode << 8 # Shift left to match old behavior + def __enter__(self): + return self + def __exit__(self, *args): + self.close() def __getattr__(self, name): return getattr(self._stream, name) def __iter__(self): Modified: python/branches/py3k/Lib/test/test_popen.py ============================================================================== --- python/branches/py3k/Lib/test/test_popen.py (original) +++ python/branches/py3k/Lib/test/test_popen.py Wed Dec 9 01:01:27 2009 @@ -49,6 +49,14 @@ else: self.assertEqual(os.popen("exit 42").close(), 42 << 8) + def test_contextmanager(self): + with os.popen("echo hello") as f: + self.assertEqual(f.read(), "hello\n") + + def test_iterating(self): + with os.popen("echo hello") as f: + self.assertEqual(list(f), ["hello\n"]) + def test_main(): support.run_unittest(PopenTest) From python-checkins at python.org Wed Dec 9 01:03:16 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 09 Dec 2009 00:03:16 -0000 Subject: [Python-checkins] r76724 - in python/branches/release31-maint: Lib/os.py Lib/test/test_popen.py Message-ID: Author: antoine.pitrou Date: Wed Dec 9 01:03:16 2009 New Revision: 76724 Log: Merged revisions 76723 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76723 | antoine.pitrou | 2009-12-09 01:01:27 +0100 (mer., 09 d?c. 2009) | 3 lines Issue #7461: objects returned by os.popen() should support the context manager protocol ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/os.py python/branches/release31-maint/Lib/test/test_popen.py Modified: python/branches/release31-maint/Lib/os.py ============================================================================== --- python/branches/release31-maint/Lib/os.py (original) +++ python/branches/release31-maint/Lib/os.py Wed Dec 9 01:03:16 2009 @@ -650,6 +650,10 @@ return returncode else: return returncode << 8 # Shift left to match old behavior + def __enter__(self): + return self + def __exit__(self, *args): + self.close() def __getattr__(self, name): return getattr(self._stream, name) def __iter__(self): Modified: python/branches/release31-maint/Lib/test/test_popen.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_popen.py (original) +++ python/branches/release31-maint/Lib/test/test_popen.py Wed Dec 9 01:03:16 2009 @@ -49,6 +49,14 @@ else: self.assertEqual(os.popen("exit 42").close(), 42 << 8) + def test_contextmanager(self): + with os.popen("echo hello") as f: + self.assertEqual(f.read(), "hello\n") + + def test_iterating(self): + with os.popen("echo hello") as f: + self.assertEqual(list(f), ["hello\n"]) + def test_main(): support.run_unittest(PopenTest) From python-checkins at python.org Wed Dec 9 02:48:31 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 09 Dec 2009 01:48:31 -0000 Subject: [Python-checkins] r76725 - python/branches/py3k/Doc/library/importlib.rst Message-ID: Author: brett.cannon Date: Wed Dec 9 02:48:31 2009 New Revision: 76725 Log: Clarify the intention of raising ImportError for importlib.abc.PyLoader.(source|bytecode)_path. 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 Dec 9 02:48:31 2009 @@ -230,7 +230,7 @@ An abstract method that returns the path to the source code for a module. Should return :keyword:`None` if there is no source code or - raise :exc:`ImportError` if the module cannot be found. + raise :exc:`ImportError` if the module cannot be handled by the loader. .. method:: get_filename(fullname) @@ -282,7 +282,8 @@ An abstract method which returns the path to the bytecode for the specified module, if it exists. It returns :keyword:`None` if no bytecode exists (yet). - Raises :exc:`ImportError` if the module is not found. + Raises :exc:`ImportError` if the module cannot be handled by the + loader. .. method:: get_filename(fullname) From python-checkins at python.org Wed Dec 9 16:15:32 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 09 Dec 2009 15:15:32 -0000 Subject: [Python-checkins] r76726 - in python/trunk: Lib/imaplib.py Lib/test/test_imaplib.py Misc/NEWS Message-ID: Author: r.david.murray Date: Wed Dec 9 16:15:31 2009 New Revision: 76726 Log: Issue 5949: fixed IMAP4_SSL hang when the IMAP server response is missing proper end-of-line termination. Patch and tests by Scott Dial. The new tests include a test harness which will make it easier to add additional tests. Modified: python/trunk/Lib/imaplib.py python/trunk/Lib/test/test_imaplib.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/imaplib.py ============================================================================== --- python/trunk/Lib/imaplib.py (original) +++ python/trunk/Lib/imaplib.py Wed Dec 9 16:15:31 2009 @@ -1001,6 +1001,8 @@ raise self.abort('socket error: EOF') # Protocol mandates all lines terminated by CRLF + if not line.endswith('\r\n'): + raise self.abort('socket error: unterminated line') line = line[:-2] if __debug__: @@ -1167,7 +1169,7 @@ while 1: char = self.sslobj.read(1) line.append(char) - if char == "\n": return ''.join(line) + if char in ("\n", ""): return ''.join(line) def send(self, data): Modified: python/trunk/Lib/test/test_imaplib.py ============================================================================== --- python/trunk/Lib/test/test_imaplib.py (original) +++ python/trunk/Lib/test/test_imaplib.py Wed Dec 9 16:15:31 2009 @@ -1,11 +1,27 @@ +from test import test_support as support +# If we end up with a significant number of tests that don't require +# threading, this test module should be split. Right now we skip +# them all if we don't have threading. +threading = support.import_module('threading') + +from contextlib import contextmanager import imaplib +import os.path +import select +import socket +import SocketServer +import ssl +import sys import time -from test import test_support +from test_support import reap_threads, verbose import unittest +CERTFILE = None + class TestImaplib(unittest.TestCase): + def test_that_Time2Internaldate_returns_a_result(self): # We can check only that it successfully produces a result, # not the correctness of the result itself, since the result @@ -17,9 +33,153 @@ imaplib.Time2Internaldate(t) +class SecureTCPServer(SocketServer.TCPServer): + + def get_request(self): + newsocket, fromaddr = self.socket.accept() + connstream = ssl.wrap_socket(newsocket, + server_side=True, + certfile=CERTFILE) + return connstream, fromaddr + + +class SimpleIMAPHandler(SocketServer.StreamRequestHandler): + + timeout = 1 + + def _send(self, message): + if verbose: print "SENT:", message.strip() + self.wfile.write(message) + + def handle(self): + # Send a welcome message. + self._send('* OK IMAP4rev1\r\n') + while 1: + # Gather up input until we receive a line terminator or we timeout. + # Accumulate read(1) because it's simpler to handle the differences + # between naked sockets and SSL sockets. + line = '' + while 1: + try: + part = self.rfile.read(1) + if part == '': + # Naked sockets return empty strings.. + return + line += part + except IOError: + # ..but SSLSockets throw exceptions. + return + if line.endswith('\r\n'): + break + + if verbose: print 'GOT:', line.strip() + splitline = line.split() + tag = splitline[0] + cmd = splitline[1] + args = splitline[2:] + + if hasattr(self, 'cmd_%s' % (cmd,)): + getattr(self, 'cmd_%s' % (cmd,))(tag, args) + else: + self._send('%s BAD %s unknown\r\n' % (tag, cmd)) + + def cmd_CAPABILITY(self, tag, args): + self._send('* CAPABILITY IMAP4rev1\r\n') + self._send('%s OK CAPABILITY completed\r\n' % (tag,)) + + +class BaseThreadedNetworkedTests(unittest.TestCase): + + def make_server(self, addr, hdlr): + + class MyServer(self.server_class): + def handle_error(self, request, client_address): + self.close_request(request) + self.server_close() + raise + + if verbose: print "creating server" + server = MyServer(addr, hdlr) + self.assertEquals(server.server_address, server.socket.getsockname()) + + if verbose: + print "server created" + print "ADDR =", addr + print "CLASS =", self.server_class + print "HDLR =", server.RequestHandlerClass + + t = threading.Thread( + name='%s serving' % self.server_class, + target=server.serve_forever, + # Short poll interval to make the test finish quickly. + # Time between requests is short enough that we won't wake + # up spuriously too many times. + kwargs={'poll_interval':0.01}) + t.daemon = True # In case this function raises. + t.start() + if verbose: print "server running" + return server, t + + def reap_server(self, server, thread): + if verbose: print "waiting for server" + server.shutdown() + thread.join() + if verbose: print "done" + + @contextmanager + def reaped_server(self, hdlr): + server, thread = self.make_server((support.HOST, 0), hdlr) + try: + yield server + finally: + self.reap_server(server, thread) + + @reap_threads + def test_connect(self): + with self.reaped_server(SimpleIMAPHandler) as server: + client = self.imap_class(*server.server_address) + client.shutdown() + + @reap_threads + def test_issue5949(self): + + class EOFHandler(SocketServer.StreamRequestHandler): + def handle(self): + # EOF without sending a complete welcome message. + self.wfile.write('* OK') + + with self.reaped_server(EOFHandler) as server: + self.assertRaises(imaplib.IMAP4.abort, + self.imap_class, *server.server_address) + + +class ThreadedNetworkedTests(BaseThreadedNetworkedTests): + + server_class = SocketServer.TCPServer + imap_class = imaplib.IMAP4 + + +class ThreadedNetworkedTestsSSL(BaseThreadedNetworkedTests): + + server_class = SecureTCPServer + imap_class = imaplib.IMAP4_SSL + + def test_main(): - test_support.run_unittest(TestImaplib) + + tests = [TestImaplib] + + if support.is_resource_enabled('network'): + global CERTFILE + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, + "keycert.pem") + if not os.path.exists(CERTFILE): + raise support.TestFailed("Can't read certificate files!") + tests.extend([ThreadedNetworkedTests, ThreadedNetworkedTestsSSL]) + + support.run_unittest(*tests) if __name__ == "__main__": - unittest.main() + support.use_resources = ['network'] + test_main() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Dec 9 16:15:31 2009 @@ -15,9 +15,13 @@ Library ------- +- Issue #5949: fixed IMAP4_SSL hang when the IMAP server response is + missing proper end-of-line termination. + - Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata. + What's New in Python 2.7 alpha 1 ================================ From python-checkins at python.org Wed Dec 9 17:41:39 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 09 Dec 2009 16:41:39 -0000 Subject: [Python-checkins] r76727 - python/trunk/Lib/test/test_imaplib.py Message-ID: Author: r.david.murray Date: Wed Dec 9 17:41:39 2009 New Revision: 76727 Log: Skip new imaplib SSL tests if ssl is not available. Modified: python/trunk/Lib/test/test_imaplib.py Modified: python/trunk/Lib/test/test_imaplib.py ============================================================================== --- python/trunk/Lib/test/test_imaplib.py (original) +++ python/trunk/Lib/test/test_imaplib.py Wed Dec 9 17:41:39 2009 @@ -10,13 +10,17 @@ import select import socket import SocketServer -import ssl import sys import time from test_support import reap_threads, verbose import unittest +try: + import ssl +except ImportError: + ssl = None + CERTFILE = None @@ -33,14 +37,25 @@ imaplib.Time2Internaldate(t) -class SecureTCPServer(SocketServer.TCPServer): +if ssl: + + class SecureTCPServer(SocketServer.TCPServer): + + def get_request(self): + newsocket, fromaddr = self.socket.accept() + connstream = ssl.wrap_socket(newsocket, + server_side=True, + certfile=CERTFILE) + return connstream, fromaddr + + IMAP4_SSL = imaplib.IMAP4_SSL + +else: + + class SecureTCPServer: + pass - def get_request(self): - newsocket, fromaddr = self.socket.accept() - connstream = ssl.wrap_socket(newsocket, - server_side=True, - certfile=CERTFILE) - return connstream, fromaddr + IMAP4_SSL = None class SimpleIMAPHandler(SocketServer.StreamRequestHandler): @@ -159,10 +174,11 @@ imap_class = imaplib.IMAP4 + at unittest.skipUnless(ssl, "SSL not available") class ThreadedNetworkedTestsSSL(BaseThreadedNetworkedTests): server_class = SecureTCPServer - imap_class = imaplib.IMAP4_SSL + imap_class = IMAP4_SSL def test_main(): @@ -170,11 +186,12 @@ tests = [TestImaplib] if support.is_resource_enabled('network'): - global CERTFILE - CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, - "keycert.pem") - if not os.path.exists(CERTFILE): - raise support.TestFailed("Can't read certificate files!") + if ssl: + global CERTFILE + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, + "keycert.pem") + if not os.path.exists(CERTFILE): + raise support.TestFailed("Can't read certificate files!") tests.extend([ThreadedNetworkedTests, ThreadedNetworkedTestsSSL]) support.run_unittest(*tests) From solipsis at pitrou.net Thu Dec 10 00:47:39 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 10 Dec 2009 00:47:39 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76725): sum=0 Message-ID: <20091209234739.897D717759@ns6635.ovh.net> py3k results for svn r76725 (hg cset 3eee2f180680) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogh1YnOA', '-x', 'test_httpservers'] From python-checkins at python.org Thu Dec 10 01:24:21 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 10 Dec 2009 00:24:21 -0000 Subject: [Python-checkins] r76728 - python/branches/py3k/Doc/library/importlib.rst Message-ID: Author: brett.cannon Date: Thu Dec 10 01:24:21 2009 New Revision: 76728 Log: Wording clarification. 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 Dec 10 01:24:21 2009 @@ -229,8 +229,9 @@ .. method:: source_path(fullname) An abstract method that returns the path to the source code for a - module. Should return :keyword:`None` if there is no source code or - raise :exc:`ImportError` if the module cannot be handled by the loader. + module. Should return :keyword:`None` if there is no source code. + Raises :exc:`ImportError` if the loader knows it cannot handle the + module. .. method:: get_filename(fullname) @@ -282,8 +283,8 @@ An abstract method which returns the path to the bytecode for the specified module, if it exists. It returns :keyword:`None` if no bytecode exists (yet). - Raises :exc:`ImportError` if the module cannot be handled by the - loader. + Raises :exc:`ImportError` if the loader knows it cannot handle the + module. .. method:: get_filename(fullname) From python-checkins at python.org Thu Dec 10 01:47:21 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 10 Dec 2009 00:47:21 -0000 Subject: [Python-checkins] r76729 - in python/branches/py3k: Doc/library/collections.rst Lib/test/test_deque.py Misc/NEWS Modules/_collectionsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Dec 10 01:47:21 2009 New Revision: 76729 Log: Add a reverse() method to collections.deque(). Modified: python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Lib/test/test_deque.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_collectionsmodule.c Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Thu Dec 10 01:47:21 2009 @@ -357,6 +357,11 @@ Removed the first occurrence of *value*. If not found, raises a :exc:`ValueError`. + .. method:: reverse() + + Reverse the elements of the deque in-place and then return ``None``. + + .. versionadded:: 3.2 .. method:: rotate(n) Modified: python/branches/py3k/Lib/test/test_deque.py ============================================================================== --- python/branches/py3k/Lib/test/test_deque.py (original) +++ python/branches/py3k/Lib/test/test_deque.py Thu Dec 10 01:47:21 2009 @@ -193,6 +193,18 @@ self.assertTrue(val not in d) self.assertEqual(len(d), 0) + def test_reverse(self): + n = 500 # O(n**2) test, don't make this too big + data = [random.random() for i in range(n)] + for i in range(n): + d = deque(data[:i]) + r = d.reverse() + self.assertEqual(list(d), list(reversed(data[:i]))) + self.assert_(r is None) + d.reverse() + self.assertEqual(list(d), data[:i]) + self.assertRaises(TypeError, d.reverse, 1) # Arity is zero + def test_rotate(self): s = tuple('abcde') n = len(s) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 10 01:47:21 2009 @@ -154,6 +154,8 @@ Library ------- +- Add a reverse() method to collections.deque(). + - Issue #6986: Fix crash in the JSON C accelerator when called with the wrong parameter types. Patch by Victor Stinner. Modified: python/branches/py3k/Modules/_collectionsmodule.c ============================================================================== --- python/branches/py3k/Modules/_collectionsmodule.c (original) +++ python/branches/py3k/Modules/_collectionsmodule.c Thu Dec 10 01:47:21 2009 @@ -427,6 +427,48 @@ PyDoc_STRVAR(rotate_doc, "Rotate the deque n steps to the right (default n=1). If n is negative, rotates left."); +static PyObject * +deque_reverse(dequeobject *deque, PyObject *unused) +{ + block *leftblock = deque->leftblock; + block *rightblock = deque->rightblock; + Py_ssize_t leftindex = deque->leftindex; + Py_ssize_t rightindex = deque->rightindex; + Py_ssize_t n = (deque->len)/2; + Py_ssize_t i; + PyObject *tmp; + + for (i=0 ; idata[leftindex]; + leftblock->data[leftindex] = rightblock->data[rightindex]; + rightblock->data[rightindex] = tmp; + + /* Advance left block/index pair */ + leftindex++; + if (leftindex == BLOCKLEN) { + assert (leftblock->rightlink != NULL); + leftblock = leftblock->rightlink; + leftindex = 0; + } + + /* Step backwards with the right block/index pair */ + rightindex--; + if (rightindex == -1) { + assert (rightblock->leftlink != NULL); + rightblock = rightblock->leftlink; + rightindex = BLOCKLEN - 1; + } + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(reverse_doc, +"D.reverse() -- reverse *IN PLACE*"); + static Py_ssize_t deque_len(dequeobject *deque) { @@ -865,6 +907,8 @@ METH_O, remove_doc}, {"__reversed__", (PyCFunction)deque_reviter, METH_NOARGS, reversed_doc}, + {"reverse", (PyCFunction)deque_reverse, + METH_NOARGS, reverse_doc}, {"rotate", (PyCFunction)deque_rotate, METH_VARARGS, rotate_doc}, {NULL, NULL} /* sentinel */ From python-checkins at python.org Thu Dec 10 03:08:07 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 10 Dec 2009 02:08:07 -0000 Subject: [Python-checkins] r76730 - in python/branches/py3k: Lib/imaplib.py Lib/test/test_imaplib.py Misc/NEWS Message-ID: Author: r.david.murray Date: Thu Dec 10 03:08:06 2009 New Revision: 76730 Log: Merged revisions 76726-76727 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk The merge adds a test with an invalid rather than a missing line end, since the py3K code passed the original issue 5949 test. New test also by Scott Dial. ........ r76726 | r.david.murray | 2009-12-09 10:15:31 -0500 (Wed, 09 Dec 2009) | 6 lines Issue 5949: fixed IMAP4_SSL hang when the IMAP server response is missing proper end-of-line termination. Patch and tests by Scott Dial. The new tests include a test harness which will make it easier to add additional tests. ........ r76727 | r.david.murray | 2009-12-09 11:41:39 -0500 (Wed, 09 Dec 2009) | 2 lines Skip new imaplib SSL tests if ssl is not available. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/imaplib.py python/branches/py3k/Lib/test/test_imaplib.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/imaplib.py ============================================================================== --- python/branches/py3k/Lib/imaplib.py (original) +++ python/branches/py3k/Lib/imaplib.py Thu Dec 10 03:08:06 2009 @@ -1023,6 +1023,8 @@ raise self.abort('socket error: EOF') # Protocol mandates all lines terminated by CRLF + if not line.endswith(b'\r\n'): + raise self.abort('socket error: unterminated line') line = line[:-2] if __debug__: Modified: python/branches/py3k/Lib/test/test_imaplib.py ============================================================================== --- python/branches/py3k/Lib/test/test_imaplib.py (original) +++ python/branches/py3k/Lib/test/test_imaplib.py Thu Dec 10 03:08:06 2009 @@ -1,11 +1,31 @@ +from test import support +# If we end up with a significant number of tests that don't require +# threading, this test module should be split. Right now we skip +# them all if we don't have threading. +threading = support.import_module('threading') + +from contextlib import contextmanager import imaplib +import os.path +import select +import socket +import socketserver +import sys import time -from test import support +from test.support import reap_threads, verbose import unittest +try: + import ssl +except ImportError: + ssl = None + +CERTFILE = None + class TestImaplib(unittest.TestCase): + def test_that_Time2Internaldate_returns_a_result(self): # We can check only that it successfully produces a result, # not the correctness of the result itself, since the result @@ -17,9 +37,180 @@ imaplib.Time2Internaldate(t) +if ssl: + + class SecureTCPServer(socketserver.TCPServer): + + def get_request(self): + newsocket, fromaddr = self.socket.accept() + connstream = ssl.wrap_socket(newsocket, + server_side=True, + certfile=CERTFILE) + return connstream, fromaddr + + IMAP4_SSL = imaplib.IMAP4_SSL + +else: + + class SecureTCPServer: + pass + + IMAP4_SSL = None + + +class SimpleIMAPHandler(socketserver.StreamRequestHandler): + + timeout = 1 + + def _send(self, message): + if verbose: print("SENT:", message.strip()) + self.wfile.write(message) + + def handle(self): + # Send a welcome message. + self._send(b'* OK IMAP4rev1\r\n') + while 1: + # Gather up input until we receive a line terminator or we timeout. + # Accumulate read(1) because it's simpler to handle the differences + # between naked sockets and SSL sockets. + line = b'' + while 1: + try: + part = self.rfile.read(1) + if part == b'': + # Naked sockets return empty strings.. + return + line += part + except IOError: + # ..but SSLSockets throw exceptions. + return + if line.endswith(b'\r\n'): + break + + if verbose: print('GOT:', line.strip()) + splitline = line.split() + tag = splitline[0].decode('ASCII') + cmd = splitline[1].decode('ASCII') + args = splitline[2:] + + if hasattr(self, 'cmd_'+cmd): + getattr(self, 'cmd_'+cmd)(tag, args) + else: + self._send('{} BAD {} unknown\r\n'.format(tag, cmd).encode('ASCII')) + + def cmd_CAPABILITY(self, tag, args): + self._send(b'* CAPABILITY IMAP4rev1\r\n') + self._send('{} OK CAPABILITY completed\r\n'.format(tag).encode('ASCII')) + + +class BaseThreadedNetworkedTests(unittest.TestCase): + + def make_server(self, addr, hdlr): + + class MyServer(self.server_class): + def handle_error(self, request, client_address): + self.close_request(request) + self.server_close() + raise + + if verbose: print("creating server") + server = MyServer(addr, hdlr) + self.assertEquals(server.server_address, server.socket.getsockname()) + + if verbose: + print("server created") + print("ADDR =", addr) + print("CLASS =", self.server_class) + print("HDLR =", server.RequestHandlerClass) + + t = threading.Thread( + name='%s serving' % self.server_class, + target=server.serve_forever, + # Short poll interval to make the test finish quickly. + # Time between requests is short enough that we won't wake + # up spuriously too many times. + kwargs={'poll_interval':0.01}) + t.daemon = True # In case this function raises. + t.start() + if verbose: print("server running") + return server, t + + def reap_server(self, server, thread): + if verbose: print("waiting for server") + server.shutdown() + thread.join() + if verbose: print("done") + + @contextmanager + def reaped_server(self, hdlr): + server, thread = self.make_server((support.HOST, 0), hdlr) + try: + yield server + finally: + self.reap_server(server, thread) + + @reap_threads + def test_connect(self): + with self.reaped_server(SimpleIMAPHandler) as server: + client = self.imap_class(*server.server_address) + client.shutdown() + + @reap_threads + def test_issue5949(self): + + class EOFHandler(socketserver.StreamRequestHandler): + def handle(self): + # EOF without sending a complete welcome message. + self.wfile.write(b'* OK') + + with self.reaped_server(EOFHandler) as server: + self.assertRaises(imaplib.IMAP4.abort, + self.imap_class, *server.server_address) + + @reap_threads + def test_line_termination(self): + + class BadNewlineHandler(SimpleIMAPHandler): + + def cmd_CAPABILITY(self, tag, args): + self._send(b'* CAPABILITY IMAP4rev1 AUTH\n') + self._send('{} OK CAPABILITY completed\r\n'.format(tag).encode('ASCII')) + + with self.reaped_server(BadNewlineHandler) as server: + self.assertRaises(imaplib.IMAP4.abort, + self.imap_class, *server.server_address) + + + +class ThreadedNetworkedTests(BaseThreadedNetworkedTests): + + server_class = socketserver.TCPServer + imap_class = imaplib.IMAP4 + + + at unittest.skipUnless(ssl, "SSL not available") +class ThreadedNetworkedTestsSSL(BaseThreadedNetworkedTests): + + server_class = SecureTCPServer + imap_class = IMAP4_SSL + + def test_main(): - support.run_unittest(TestImaplib) + + tests = [TestImaplib] + + if support.is_resource_enabled('network'): + if ssl: + global CERTFILE + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, + "keycert.pem") + if not os.path.exists(CERTFILE): + raise support.TestFailed("Can't read certificate files!") + tests.extend([ThreadedNetworkedTests, ThreadedNetworkedTestsSSL]) + + support.run_unittest(*tests) if __name__ == "__main__": - unittest.main() + support.use_resources = ['network'] + test_main() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 10 03:08:06 2009 @@ -154,6 +154,9 @@ Library ------- +- Issue #5949: added check for correct lineends in input from IMAP server + in imaplib. + - Add a reverse() method to collections.deque(). - Issue #6986: Fix crash in the JSON C accelerator when called with the From python-checkins at python.org Thu Dec 10 03:09:08 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 10 Dec 2009 02:09:08 -0000 Subject: [Python-checkins] r76731 - python/branches/py3k/Python/import.c Message-ID: Author: benjamin.peterson Date: Thu Dec 10 03:09:08 2009 New Revision: 76731 Log: remove magic number bumping from the 2.x -U option #7459 Modified: python/branches/py3k/Python/import.c Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Thu Dec 10 03:09:08 2009 @@ -78,24 +78,23 @@ 3040 (added signature annotations) 3050 (print becomes a function) 3060 (PEP 3115 metaclass syntax) - 3070 (PEP 3109 raise changes) - 3080 (PEP 3137 make __file__ and __name__ unicode) - 3090 (kill str8 interning) - 3100 (merge from 2.6a0, see 62151) - 3102 (__file__ points to source file) - Python 3.0a4: 3110 (WITH_CLEANUP optimization). - Python 3.0a5: 3130 (lexical exception stacking, including POP_EXCEPT) - Python 3.1a0: 3140 (optimize list, set and dict comprehensions: + 3061 (string literals become unicode) + 3071 (PEP 3109 raise changes) + 3081 (PEP 3137 make __file__ and __name__ unicode) + 3091 (kill str8 interning) + 3101 (merge from 2.6a0, see 62151) + 3103 (__file__ points to source file) + Python 3.0a4: 3111 (WITH_CLEANUP optimization). + Python 3.0a5: 3131 (lexical exception stacking, including POP_EXCEPT) + Python 3.1a0: 3141 (optimize list, set and dict comprehensions: change LIST_APPEND and SET_ADD, add MAP_ADD) - Python 3.1a0: 3150 (optimize conditional branches: + Python 3.1a0: 3151 (optimize conditional branches: introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) Python 3.2a0: 3160 (add SETUP_WITH) */ #define MAGIC (3160 | ((long)'\r'<<16) | ((long)'\n'<<24)) -/* Magic word as global; note that _PyImport_Init() can change the - value of this global to accommodate for alterations of how the - compiler works which are enabled by command line switches. */ +/* Magic word as global */ static long pyc_magic = MAGIC; /* See _PyImport_FixupExtension() below */ @@ -161,13 +160,6 @@ filetab->suffix = ".pyo"; } } - - { - /* Fix the pyc_magic so that byte compiled code created - using the all-Unicode method doesn't interfere with - code created in normal operation mode. */ - pyc_magic = MAGIC + 1; - } } void From python-checkins at python.org Thu Dec 10 04:03:03 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 10 Dec 2009 03:03:03 -0000 Subject: [Python-checkins] r76732 - in python/branches/py3k: Lib/test/test_deque.py Misc/NEWS Modules/_collectionsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Dec 10 04:03:02 2009 New Revision: 76732 Log: Fix variants of deque.extend: d.extend(d) d+=d d.extendleft(d) Modified: python/branches/py3k/Lib/test/test_deque.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_collectionsmodule.c Modified: python/branches/py3k/Lib/test/test_deque.py ============================================================================== --- python/branches/py3k/Lib/test/test_deque.py (original) +++ python/branches/py3k/Lib/test/test_deque.py Thu Dec 10 04:03:02 2009 @@ -136,12 +136,23 @@ self.assertRaises(TypeError, d.extend, 1) d.extend('bcd') self.assertEqual(list(d), list('abcd')) + d.extend(d) + self.assertEqual(list(d), list('abcdabcd')) + + def test_iadd(self): + d = deque('a') + d += 'bcd' + self.assertEqual(list(d), list('abcd')) + d += d + self.assertEqual(list(d), list('abcdabcd')) def test_extendleft(self): d = deque('a') self.assertRaises(TypeError, d.extendleft, 1) d.extendleft('bcd') self.assertEqual(list(d), list(reversed('abcd'))) + d.extendleft(d) + self.assertEqual(list(d), list('abcddcba')) d = deque() d.extendleft(range(1000)) self.assertEqual(list(d), list(reversed(range(1000)))) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 10 04:03:02 2009 @@ -159,6 +159,8 @@ - Add a reverse() method to collections.deque(). +- Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d + - Issue #6986: Fix crash in the JSON C accelerator when called with the wrong parameter types. Patch by Victor Stinner. Modified: python/branches/py3k/Modules/_collectionsmodule.c ============================================================================== --- python/branches/py3k/Modules/_collectionsmodule.c (original) +++ python/branches/py3k/Modules/_collectionsmodule.c Thu Dec 10 04:03:02 2009 @@ -298,6 +298,17 @@ { PyObject *it, *item; + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extend(deque, s); + Py_DECREF(s); + return result; + } + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -339,6 +350,17 @@ { PyObject *it, *item; + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extendleft(deque, s); + Py_DECREF(s); + return result; + } + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -375,6 +397,19 @@ PyDoc_STRVAR(extendleft_doc, "Extend the left side of the deque with elements from the iterable"); +static PyObject * +deque_inplace_concat(dequeobject *deque, PyObject *other) +{ + PyObject *result; + + result = deque_extend(deque, other); + if (result == NULL) + return result; + Py_DECREF(result); + Py_INCREF(deque); + return (PyObject *)deque; +} + static int _deque_rotate(dequeobject *deque, Py_ssize_t n) { @@ -875,6 +910,11 @@ (ssizeargfunc)deque_item, /* sq_item */ 0, /* sq_slice */ (ssizeobjargproc)deque_ass_item, /* sq_ass_item */ + 0, /* sq_ass_slice */ + 0, /* sq_contains */ + (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ + }; /* deque object ********************************************************/ From python-checkins at python.org Thu Dec 10 04:37:59 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 10 Dec 2009 03:37:59 -0000 Subject: [Python-checkins] r76733 - python/trunk/Objects/abstract.c Message-ID: Author: benjamin.peterson Date: Thu Dec 10 04:37:59 2009 New Revision: 76733 Log: substitute PyDict_Check() for PyObject_IsInstance Modified: python/trunk/Objects/abstract.c Modified: python/trunk/Objects/abstract.c ============================================================================== --- python/trunk/Objects/abstract.c (original) +++ python/trunk/Objects/abstract.c Thu Dec 10 04:37:59 2009 @@ -1810,7 +1810,7 @@ { if (s && PyInstance_Check(s)) return PyObject_HasAttrString(s, "__getitem__"); - if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type)) + if (PyDict_Check(s)) return 0; return s != NULL && s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL; From brett at python.org Thu Dec 10 06:26:10 2009 From: brett at python.org (Brett Cannon) Date: Wed, 9 Dec 2009 21:26:10 -0800 Subject: [Python-checkins] r76733 - python/trunk/Objects/abstract.c In-Reply-To: <4b206d32.1a67f10a.34fa.ffffa0dbSMTPIN_ADDED@mx.google.com> References: <4b206d32.1a67f10a.34fa.ffffa0dbSMTPIN_ADDED@mx.google.com> Message-ID: Why the change? This tie into abc stuff somehow? On Wed, Dec 9, 2009 at 19:38, benjamin.peterson wrote: > Author: benjamin.peterson > Date: Thu Dec 10 04:37:59 2009 > New Revision: 76733 > > Log: > substitute PyDict_Check() for PyObject_IsInstance > > Modified: > python/trunk/Objects/abstract.c > > Modified: python/trunk/Objects/abstract.c > > ============================================================================== > --- python/trunk/Objects/abstract.c (original) > +++ python/trunk/Objects/abstract.c Thu Dec 10 04:37:59 2009 > @@ -1810,7 +1810,7 @@ > { > if (s && PyInstance_Check(s)) > return PyObject_HasAttrString(s, "__getitem__"); > - if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type)) > + if (PyDict_Check(s)) > return 0; > return s != NULL && s->ob_type->tp_as_sequence && > s->ob_type->tp_as_sequence->sq_item != NULL; > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > -------------- next part -------------- An HTML attachment was scrubbed... URL: From python-checkins at python.org Thu Dec 10 06:36:12 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 10 Dec 2009 05:36:12 -0000 Subject: [Python-checkins] r76734 - in python/branches/release31-maint: Lib/test/test_deque.py Misc/NEWS Modules/_collectionsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Dec 10 06:36:11 2009 New Revision: 76734 Log: Fix variants of deque.extend: d.extend(d) d+=d d.extendleft(d) Modified: python/branches/release31-maint/Lib/test/test_deque.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/_collectionsmodule.c Modified: python/branches/release31-maint/Lib/test/test_deque.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_deque.py (original) +++ python/branches/release31-maint/Lib/test/test_deque.py Thu Dec 10 06:36:11 2009 @@ -136,12 +136,23 @@ self.assertRaises(TypeError, d.extend, 1) d.extend('bcd') self.assertEqual(list(d), list('abcd')) + d.extend(d) + self.assertEqual(list(d), list('abcdabcd')) + + def test_iadd(self): + d = deque('a') + d += 'bcd' + self.assertEqual(list(d), list('abcd')) + d += d + self.assertEqual(list(d), list('abcdabcd')) def test_extendleft(self): d = deque('a') self.assertRaises(TypeError, d.extendleft, 1) d.extendleft('bcd') self.assertEqual(list(d), list(reversed('abcd'))) + d.extendleft(d) + self.assertEqual(list(d), list('abcddcba')) d = deque() d.extendleft(range(1000)) self.assertEqual(list(d), list(reversed(range(1000)))) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Dec 10 06:36:11 2009 @@ -55,6 +55,8 @@ Library ------- +- Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d + - Issue #6986: Fix crash in the JSON C accelerator when called with the wrong parameter types. Patch by Victor Stinner. Modified: python/branches/release31-maint/Modules/_collectionsmodule.c ============================================================================== --- python/branches/release31-maint/Modules/_collectionsmodule.c (original) +++ python/branches/release31-maint/Modules/_collectionsmodule.c Thu Dec 10 06:36:11 2009 @@ -298,6 +298,17 @@ { PyObject *it, *item; + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extend(deque, s); + Py_DECREF(s); + return result; + } + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -339,6 +350,17 @@ { PyObject *it, *item; + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extendleft(deque, s); + Py_DECREF(s); + return result; + } + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -375,6 +397,19 @@ PyDoc_STRVAR(extendleft_doc, "Extend the left side of the deque with elements from the iterable"); +static PyObject * +deque_inplace_concat(dequeobject *deque, PyObject *other) +{ + PyObject *result; + + result = deque_extend(deque, other); + if (result == NULL) + return result; + Py_DECREF(result); + Py_INCREF(deque); + return (PyObject *)deque; +} + static int _deque_rotate(dequeobject *deque, Py_ssize_t n) { @@ -833,6 +868,11 @@ (ssizeargfunc)deque_item, /* sq_item */ 0, /* sq_slice */ (ssizeobjargproc)deque_ass_item, /* sq_ass_item */ + 0, /* sq_ass_slice */ + 0, /* sq_contains */ + (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ + }; /* deque object ********************************************************/ From python-checkins at python.org Thu Dec 10 06:56:50 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 10 Dec 2009 05:56:50 -0000 Subject: [Python-checkins] r76735 - in python/branches/release26-maint: Lib/test/test_deque.py Misc/NEWS Modules/_collectionsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Dec 10 06:56:49 2009 New Revision: 76735 Log: Fix variants of deque.extend: d.extend(d) d+=d d.extendleft(d) Modified: python/branches/release26-maint/Lib/test/test_deque.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/_collectionsmodule.c Modified: python/branches/release26-maint/Lib/test/test_deque.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_deque.py (original) +++ python/branches/release26-maint/Lib/test/test_deque.py Thu Dec 10 06:56:49 2009 @@ -109,12 +109,23 @@ self.assertRaises(TypeError, d.extend, 1) d.extend('bcd') self.assertEqual(list(d), list('abcd')) + d.extend(d) + self.assertEqual(list(d), list('abcdabcd')) + + def test_iadd(self): + d = deque('a') + d += 'bcd' + self.assertEqual(list(d), list('abcd')) + d += d + self.assertEqual(list(d), list('abcdabcd')) def test_extendleft(self): d = deque('a') self.assertRaises(TypeError, d.extendleft, 1) d.extendleft('bcd') self.assertEqual(list(d), list(reversed('abcd'))) + d.extendleft(d) + self.assertEqual(list(d), list('abcddcba')) d = deque() d.extendleft(range(1000)) self.assertEqual(list(d), list(reversed(range(1000)))) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Dec 10 06:56:49 2009 @@ -33,6 +33,8 @@ Library ------- +- Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d + - Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is generated in Distutils. Patch by Stephen Emslie. Modified: python/branches/release26-maint/Modules/_collectionsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/_collectionsmodule.c (original) +++ python/branches/release26-maint/Modules/_collectionsmodule.c Thu Dec 10 06:56:49 2009 @@ -281,6 +281,17 @@ { PyObject *it, *item; + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extend(deque, s); + Py_DECREF(s); + return result; + } + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -319,6 +330,17 @@ { PyObject *it, *item; + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extendleft(deque, s); + Py_DECREF(s); + return result; + } + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -352,6 +374,19 @@ PyDoc_STRVAR(extendleft_doc, "Extend the left side of the deque with elements from the iterable"); +static PyObject * +deque_inplace_concat(dequeobject *deque, PyObject *other) +{ + PyObject *result; + + result = deque_extend(deque, other); + if (result == NULL) + return result; + Py_DECREF(result); + Py_INCREF(deque); + return (PyObject *)deque; +} + static int _deque_rotate(dequeobject *deque, Py_ssize_t n) { @@ -854,6 +889,11 @@ (ssizeargfunc)deque_item, /* sq_item */ 0, /* sq_slice */ (ssizeobjargproc)deque_ass_item, /* sq_ass_item */ + 0, /* sq_ass_slice */ + 0, /* sq_contains */ + (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ + }; /* deque object ********************************************************/ From python-checkins at python.org Thu Dec 10 07:00:33 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 10 Dec 2009 06:00:33 -0000 Subject: [Python-checkins] r76736 - in python/trunk: Lib/test/test_deque.py Misc/NEWS Modules/_collectionsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Dec 10 07:00:33 2009 New Revision: 76736 Log: Fix variants of deque.extend: d.extend(d) d+=d d.extendleft(d) Modified: python/trunk/Lib/test/test_deque.py python/trunk/Misc/NEWS python/trunk/Modules/_collectionsmodule.c Modified: python/trunk/Lib/test/test_deque.py ============================================================================== --- python/trunk/Lib/test/test_deque.py (original) +++ python/trunk/Lib/test/test_deque.py Thu Dec 10 07:00:33 2009 @@ -136,12 +136,23 @@ self.assertRaises(TypeError, d.extend, 1) d.extend('bcd') self.assertEqual(list(d), list('abcd')) + d.extend(d) + self.assertEqual(list(d), list('abcdabcd')) + + def test_iadd(self): + d = deque('a') + d += 'bcd' + self.assertEqual(list(d), list('abcd')) + d += d + self.assertEqual(list(d), list('abcdabcd')) def test_extendleft(self): d = deque('a') self.assertRaises(TypeError, d.extendleft, 1) d.extendleft('bcd') self.assertEqual(list(d), list(reversed('abcd'))) + d.extendleft(d) + self.assertEqual(list(d), list('abcddcba')) d = deque() d.extendleft(range(1000)) self.assertEqual(list(d), list(reversed(range(1000)))) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Dec 10 07:00:33 2009 @@ -513,6 +513,8 @@ Library ------- +- Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d + - Issue #6986: Fix crash in the JSON C accelerator when called with the wrong parameter types. Patch by Victor Stinner. Modified: python/trunk/Modules/_collectionsmodule.c ============================================================================== --- python/trunk/Modules/_collectionsmodule.c (original) +++ python/trunk/Modules/_collectionsmodule.c Thu Dec 10 07:00:33 2009 @@ -298,6 +298,17 @@ { PyObject *it, *item; + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extend(deque, s); + Py_DECREF(s); + return result; + } + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -339,6 +350,17 @@ { PyObject *it, *item; + /* Handle case where id(deque) == id(iterable) */ + if ((PyObject *)deque == iterable) { + PyObject *result; + PyObject *s = PySequence_List(iterable); + if (s == NULL) + return NULL; + result = deque_extendleft(deque, s); + Py_DECREF(s); + return result; + } + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -375,6 +397,19 @@ PyDoc_STRVAR(extendleft_doc, "Extend the left side of the deque with elements from the iterable"); +static PyObject * +deque_inplace_concat(dequeobject *deque, PyObject *other) +{ + PyObject *result; + + result = deque_extend(deque, other); + if (result == NULL) + return result; + Py_DECREF(result); + Py_INCREF(deque); + return (PyObject *)deque; +} + static int _deque_rotate(dequeobject *deque, Py_ssize_t n) { @@ -891,6 +926,11 @@ (ssizeargfunc)deque_item, /* sq_item */ 0, /* sq_slice */ (ssizeobjargproc)deque_ass_item, /* sq_ass_item */ + 0, /* sq_ass_slice */ + 0, /* sq_contains */ + (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ + }; /* deque object ********************************************************/ From python-checkins at python.org Thu Dec 10 07:42:54 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 10 Dec 2009 06:42:54 -0000 Subject: [Python-checkins] r76737 - in python/trunk: Doc/library/collections.rst Lib/test/test_deque.py Misc/NEWS Modules/_collectionsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Dec 10 07:42:54 2009 New Revision: 76737 Log: Add a reverse() method to collections.deque(). Modified: python/trunk/Doc/library/collections.rst python/trunk/Lib/test/test_deque.py python/trunk/Misc/NEWS python/trunk/Modules/_collectionsmodule.c Modified: python/trunk/Doc/library/collections.rst ============================================================================== --- python/trunk/Doc/library/collections.rst (original) +++ python/trunk/Doc/library/collections.rst Thu Dec 10 07:42:54 2009 @@ -379,6 +379,11 @@ .. versionadded:: 2.5 + .. method:: reverse() + + Reverse the elements of the deque in-place and then return ``None``. + + .. versionadded:: 2.7 .. method:: rotate(n) Modified: python/trunk/Lib/test/test_deque.py ============================================================================== --- python/trunk/Lib/test/test_deque.py (original) +++ python/trunk/Lib/test/test_deque.py Thu Dec 10 07:42:54 2009 @@ -204,6 +204,18 @@ self.assertTrue(val not in d) self.assertEqual(len(d), 0) + def test_reverse(self): + n = 500 # O(n**2) test, don't make this too big + data = [random.random() for i in range(n)] + for i in range(n): + d = deque(data[:i]) + r = d.reverse() + self.assertEqual(list(d), list(reversed(data[:i]))) + self.assert_(r is None) + d.reverse() + self.assertEqual(list(d), data[:i]) + self.assertRaises(TypeError, d.reverse, 1) # Arity is zero + def test_rotate(self): s = tuple('abcde') n = len(s) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Dec 10 07:42:54 2009 @@ -513,6 +513,8 @@ Library ------- +- Add a reverse() method to collections.deque(). + - Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d - Issue #6986: Fix crash in the JSON C accelerator when called with the Modified: python/trunk/Modules/_collectionsmodule.c ============================================================================== --- python/trunk/Modules/_collectionsmodule.c (original) +++ python/trunk/Modules/_collectionsmodule.c Thu Dec 10 07:42:54 2009 @@ -462,6 +462,48 @@ PyDoc_STRVAR(rotate_doc, "Rotate the deque n steps to the right (default n=1). If n is negative, rotates left."); +static PyObject * +deque_reverse(dequeobject *deque, PyObject *unused) +{ + block *leftblock = deque->leftblock; + block *rightblock = deque->rightblock; + Py_ssize_t leftindex = deque->leftindex; + Py_ssize_t rightindex = deque->rightindex; + Py_ssize_t n = (deque->len)/2; + Py_ssize_t i; + PyObject *tmp; + + for (i=0 ; idata[leftindex]; + leftblock->data[leftindex] = rightblock->data[rightindex]; + rightblock->data[rightindex] = tmp; + + /* Advance left block/index pair */ + leftindex++; + if (leftindex == BLOCKLEN) { + assert (leftblock->rightlink != NULL); + leftblock = leftblock->rightlink; + leftindex = 0; + } + + /* Step backwards with the right block/index pair */ + rightindex--; + if (rightindex == -1) { + assert (rightblock->leftlink != NULL); + rightblock = rightblock->leftlink; + rightindex = BLOCKLEN - 1; + } + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(reverse_doc, +"D.reverse() -- reverse *IN PLACE*"); + static Py_ssize_t deque_len(dequeobject *deque) { @@ -963,6 +1005,8 @@ METH_O, remove_doc}, {"__reversed__", (PyCFunction)deque_reviter, METH_NOARGS, reversed_doc}, + {"reverse", (PyCFunction)deque_reverse, + METH_NOARGS, reverse_doc}, {"rotate", (PyCFunction)deque_rotate, METH_VARARGS, rotate_doc}, {NULL, NULL} /* sentinel */ From python-checkins at python.org Thu Dec 10 11:27:10 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 10 Dec 2009 10:27:10 -0000 Subject: [Python-checkins] r76738 - python/trunk/Lib/distutils/sysconfig.py Message-ID: Author: ronald.oussoren Date: Thu Dec 10 11:27:09 2009 New Revision: 76738 Log: Fix an issue with the detection of a non-existing SDK on OSX. Without this patch it wasn't possible after all to compile extensions on OSX 10.6 with the binary installer unless the user had installed the (non-default) 10.4u SDK. Modified: python/trunk/Lib/distutils/sysconfig.py Modified: python/trunk/Lib/distutils/sysconfig.py ============================================================================== --- python/trunk/Lib/distutils/sysconfig.py (original) +++ python/trunk/Lib/distutils/sysconfig.py Thu Dec 10 11:27:09 2009 @@ -563,7 +563,7 @@ # are in CFLAGS or LDFLAGS and remove them if they are. # This is needed when building extensions on a 10.3 system # using a universal build of python. - for key in ('LDFLAGS', 'BASECFLAGS', + for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED', # a number of derived variables. These need to be # patched up as well. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): @@ -582,7 +582,7 @@ if 'ARCHFLAGS' in os.environ: arch = os.environ['ARCHFLAGS'] - for key in ('LDFLAGS', 'BASECFLAGS', + for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED', # a number of derived variables. These need to be # patched up as well. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): @@ -606,7 +606,7 @@ if m is not None: sdk = m.group(1) if not os.path.exists(sdk): - for key in ('LDFLAGS', 'BASECFLAGS', + for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED', # a number of derived variables. These need to be # patched up as well. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): From python-checkins at python.org Thu Dec 10 11:29:05 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 10 Dec 2009 10:29:05 -0000 Subject: [Python-checkins] r76739 - in python/branches/release26-maint: Lib/distutils/sysconfig.py Misc/NEWS Message-ID: Author: ronald.oussoren Date: Thu Dec 10 11:29:05 2009 New Revision: 76739 Log: Merged revisions 76738 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76738 | ronald.oussoren | 2009-12-10 11:27:09 +0100 (Thu, 10 Dec 2009) | 6 lines Fix an issue with the detection of a non-existing SDK on OSX. Without this patch it wasn't possible after all to compile extensions on OSX 10.6 with the binary installer unless the user had installed the (non-default) 10.4u SDK. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/sysconfig.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/distutils/sysconfig.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/sysconfig.py (original) +++ python/branches/release26-maint/Lib/distutils/sysconfig.py Thu Dec 10 11:29:05 2009 @@ -537,7 +537,7 @@ # are in CFLAGS or LDFLAGS and remove them if they are. # This is needed when building extensions on a 10.3 system # using a universal build of python. - for key in ('LDFLAGS', 'BASECFLAGS', + for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED', # a number of derived variables. These need to be # patched up as well. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): @@ -556,7 +556,7 @@ if 'ARCHFLAGS' in os.environ: arch = os.environ['ARCHFLAGS'] - for key in ('LDFLAGS', 'BASECFLAGS', + for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED', # a number of derived variables. These need to be # patched up as well. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): @@ -580,7 +580,7 @@ if m is not None: sdk = m.group(1) if not os.path.exists(sdk): - for key in ('LDFLAGS', 'BASECFLAGS', + for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED', # a number of derived variables. These need to be # patched up as well. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Dec 10 11:29:05 2009 @@ -103,6 +103,10 @@ compiles correctly under gcc on x86-64. This fixes a reported problem with the --with-tsc build on x86-64. +- Ensure that it possible to build extensions for the default + binary distribution on OSX 10.6 even when the user does not + have the 10.4u SDK installed. + Tests ----- From python-checkins at python.org Thu Dec 10 11:36:32 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 10 Dec 2009 10:36:32 -0000 Subject: [Python-checkins] r76740 - python/trunk/Include/pymem.h Message-ID: Author: mark.dickinson Date: Thu Dec 10 11:36:32 2009 New Revision: 76740 Log: Replace the size check for PyMem_MALLOC and PyMem_REALLOC with an almost equivalent[*] check that doesn't produce compiler warnings about a 'x < 0' check on an unsigned type. [*] it's equivalent for inputs of type size_t or Py_ssize_t, or any smaller unsigned or signed integer type. Modified: python/trunk/Include/pymem.h Modified: python/trunk/Include/pymem.h ============================================================================== --- python/trunk/Include/pymem.h (original) +++ python/trunk/Include/pymem.h Thu Dec 10 11:36:32 2009 @@ -71,9 +71,9 @@ pymalloc. To solve these problems, allocate an extra byte. */ /* Returns NULL to indicate error if a negative size or size larger than Py_ssize_t can represent is supplied. Helps prevents security holes. */ -#define PyMem_MALLOC(n) (((n) < 0 || (n) > PY_SSIZE_T_MAX) ? NULL \ +#define PyMem_MALLOC(n) ((size_t)(n) > (size_t)PY_SSIZE_T_MAX ? NULL \ : malloc((n) ? (n) : 1)) -#define PyMem_REALLOC(p, n) (((n) < 0 || (n) > PY_SSIZE_T_MAX) ? NULL \ +#define PyMem_REALLOC(p, n) ((size_t)(n) > (size_t)PY_SSIZE_T_MAX ? NULL \ : realloc((p), (n) ? (n) : 1)) #define PyMem_FREE free From python-checkins at python.org Thu Dec 10 11:39:08 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 10 Dec 2009 10:39:08 -0000 Subject: [Python-checkins] r76741 - in python/branches/py3k: Include/pymem.h Message-ID: Author: mark.dickinson Date: Thu Dec 10 11:39:08 2009 New Revision: 76741 Log: Merged revisions 76740 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76740 | mark.dickinson | 2009-12-10 10:36:32 +0000 (Thu, 10 Dec 2009) | 8 lines Replace the size check for PyMem_MALLOC and PyMem_REALLOC with an almost equivalent[*] check that doesn't produce compiler warnings about a 'x < 0' check on an unsigned type. [*] it's equivalent for inputs of type size_t or Py_ssize_t, or any smaller unsigned or signed integer type. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/pymem.h Modified: python/branches/py3k/Include/pymem.h ============================================================================== --- python/branches/py3k/Include/pymem.h (original) +++ python/branches/py3k/Include/pymem.h Thu Dec 10 11:39:08 2009 @@ -71,9 +71,9 @@ pymalloc. To solve these problems, allocate an extra byte. */ /* Returns NULL to indicate error if a negative size or size larger than Py_ssize_t can represent is supplied. Helps prevents security holes. */ -#define PyMem_MALLOC(n) (((n) < 0 || (n) > PY_SSIZE_T_MAX) ? NULL \ +#define PyMem_MALLOC(n) ((size_t)(n) > (size_t)PY_SSIZE_T_MAX ? NULL \ : malloc((n) ? (n) : 1)) -#define PyMem_REALLOC(p, n) (((n) < 0 || (n) > PY_SSIZE_T_MAX) ? NULL \ +#define PyMem_REALLOC(p, n) ((size_t)(n) > (size_t)PY_SSIZE_T_MAX ? NULL \ : realloc((p), (n) ? (n) : 1)) #define PyMem_FREE free From python-checkins at python.org Thu Dec 10 11:39:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 10 Dec 2009 10:39:49 -0000 Subject: [Python-checkins] r76742 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Thu Dec 10 11:39:49 2009 New Revision: 76742 Log: Blocked revisions 76740 via svnmerge ........ r76740 | mark.dickinson | 2009-12-10 10:36:32 +0000 (Thu, 10 Dec 2009) | 8 lines Replace the size check for PyMem_MALLOC and PyMem_REALLOC with an almost equivalent[*] check that doesn't produce compiler warnings about a 'x < 0' check on an unsigned type. [*] it's equivalent for inputs of type size_t or Py_ssize_t, or any smaller unsigned or signed integer type. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Dec 10 11:40:17 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 10 Dec 2009 10:40:17 -0000 Subject: [Python-checkins] r76743 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Thu Dec 10 11:40:16 2009 New Revision: 76743 Log: Blocked revisions 76741 via svnmerge ................ r76741 | mark.dickinson | 2009-12-10 10:39:08 +0000 (Thu, 10 Dec 2009) | 14 lines Merged revisions 76740 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76740 | mark.dickinson | 2009-12-10 10:36:32 +0000 (Thu, 10 Dec 2009) | 8 lines Replace the size check for PyMem_MALLOC and PyMem_REALLOC with an almost equivalent[*] check that doesn't produce compiler warnings about a 'x < 0' check on an unsigned type. [*] it's equivalent for inputs of type size_t or Py_ssize_t, or any smaller unsigned or signed integer type. ........ ................ Modified: python/branches/release31-maint/ (props changed) From benjamin at python.org Thu Dec 10 13:45:29 2009 From: benjamin at python.org (Benjamin Peterson) Date: Thu, 10 Dec 2009 06:45:29 -0600 Subject: [Python-checkins] r76733 - python/trunk/Objects/abstract.c In-Reply-To: References: <4b206d32.1a67f10a.34fa.ffffa0dbSMTPIN_ADDED@mx.google.com> Message-ID: <1afaf6160912100445m65f0f2cfw8ad89cf7a0ecde7d@mail.gmail.com> 2009/12/9 Brett Cannon : > Why the change? This tie into abc stuff somehow? No, it's clearer (where else is PyObject_IsInstance(x, PyDict_Type) in the source?), and avoids the problem of having isinstance fail. -- Regards, Benjamin From python-checkins at python.org Thu Dec 10 14:14:25 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 13:14:25 -0000 Subject: [Python-checkins] r76744 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Thu Dec 10 14:14:25 2009 New Revision: 76744 Log: copy editing + more details (python-dev feedback) Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Thu Dec 10 14:14:25 2009 @@ -18,7 +18,7 @@ Motivation ========== -In Python there are no real restriction yet on how a project should manage its +In Python there are no real restrictions yet on how a project should manage its versions, and how they should be incremented. Distutils provides a `version` distribution meta-data field but it is freeform and @@ -47,18 +47,18 @@ That is why this PEP proposes, for the sake of interoperability, a standard schema to express version information and its comparison semantics. -Furthermore, this will make OS packagers work easier when repackaging standards -compliant distributions, as of now it can be difficult to decide how two +Furthermore, this will make OS packagers' work easier when repackaging standards +compliant distributions, because as of now it can be difficult to decide how two distribution versions compare. Requisites and current status ============================= -It is not in the scope of this PEP to provide a universal versioning schema intended -to support many or all existing versioning schemas. There will always be competing -grammars, either mandated by distro or project policies or by historical -reasons and we cannot expect that to change. +It is not in the scope of this PEP to provide a universal versioning schema +intended to support all or even most of existing versioning schemas. There +will always be competing grammars, either mandated by distro or project +policies or by historical reasons that we cannot expect to change. The proposed schema should be able to express the usual versioning semantics, so it's possible to parse any alternative versioning schema and transform it @@ -73,7 +73,7 @@ Projects have very different versioning needs, but the following are widely considered important semantics: -1. there should be possible to express more than one versioning level +1. it should be possible to express more than one versioning level (usually this is expressed as major and minor revision and, sometimes, also a micro revision). 2. most projects need special meaning versions for "pre-releases" (such as @@ -138,8 +138,8 @@ >>> v1 > v2 False -The problem with this is that while it allows expressing requisite any -nesting level it doesn't allow to express special meaning versions +The problem with this is that while it allows expressing any +nesting level it doesn't allow giving special meaning to versions (pre and post-releases as well as development versions), as expressed in requisites 2, 3 and 4. @@ -193,14 +193,15 @@ elements to make it usable, such as development releases or post-release tags, as expressed in requisites 3 and 4. -Also, notice that Distutils version classes are not really used in the community. +Also, note that Distutils version classes have beed present since years +but are not really used in the community. Setuptools ---------- Setuptools provides another version comparison tool [#setuptools-version]_ -which does not enforce any rule for the version, but try to provide a better +which does not enforce any rules for the version, but try to provide a better algorithm to convert the strings to sortable keys, with a ``parse_version`` function. @@ -262,7 +263,7 @@ a particular package was using and to provide tools on top of PyPI. Distutils classes are not really used in Python projects, but the -Setuptools function is quite spread because it's used by tools like +Setuptools function is quite widespread because it's used by tools like `easy_install` [#ezinstall]_, `pip` [#pip]_ or `zc.buildout` [#zc.buildout]_ to install dependencies of a given project. @@ -288,7 +289,19 @@ The pseudo-format supported is:: - N.N[.N]+[abc]N[.N]+[.postN+][.devN+] + N.N[.N]+[{abc}N[.N]+][.postN][.devN] + +The real regular expression is:: + + expr = r"""^ + (?P\d+\.\d+) # minimum 'N.N' + (?P(?:\.\d+)*) # any number of extra '.N' segments + (?: + (?P[abc]) # 'a'=alpha, 'b'=beta, 'c'=release candidate + (?P\d+(?:\.\d+)*) + )? + (?P(\.post(?P\d+))?(\.dev(?P\d+))?)? + $""" Some examples probably make it clearer:: @@ -310,13 +323,13 @@ True The trailing ``.dev123`` is for pre-releases. The ``.post123`` is for -post-releases -- which apparently is used by a number of projects out there +post-releases -- which apparently are used by a number of projects out there (e.g. Twisted [#twisted]_). For example *after* a ``1.2.0`` release there might be a ``1.2.0-r678`` release. We used ``post`` instead of ``r`` because the ``r`` is ambiguous as to whether it indicates a pre- or post-release. Last, ``.post456.dev34`` indicates a dev marker for a post release, that sorts -before a ``.post345`` marker. This can be used to do development versions +before a ``.post456`` marker. This can be used to do development versions of post releases. ``verlib`` provides a ``RationalVersion`` class and a From python-checkins at python.org Thu Dec 10 14:32:27 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 13:32:27 -0000 Subject: [Python-checkins] r76745 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Thu Dec 10 14:32:27 2009 New Revision: 76745 Log: typo Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Thu Dec 10 14:32:27 2009 @@ -193,7 +193,7 @@ elements to make it usable, such as development releases or post-release tags, as expressed in requisites 3 and 4. -Also, note that Distutils version classes have beed present since years +Also, note that Distutils version classes have been present since years but are not really used in the community. From python-checkins at python.org Thu Dec 10 16:29:04 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 15:29:04 -0000 Subject: [Python-checkins] r76746 - in python/trunk/Lib/distutils: dep_util.py tests/test_dep_util.py Message-ID: Author: tarek.ziade Date: Thu Dec 10 16:29:03 2009 New Revision: 76746 Log: added test coverage for distutils.dep_util, and cleaned up the module Added: python/trunk/Lib/distutils/tests/test_dep_util.py Modified: python/trunk/Lib/distutils/dep_util.py Modified: python/trunk/Lib/distutils/dep_util.py ============================================================================== --- python/trunk/Lib/distutils/dep_util.py (original) +++ python/trunk/Lib/distutils/dep_util.py Thu Dec 10 16:29:03 2009 @@ -9,29 +9,27 @@ import os from distutils.errors import DistutilsFileError +def newer(source, target): + """Tells if the target is newer than the source. -def newer (source, target): - """Return true if 'source' exists and is more recently modified than - 'target', or if 'source' exists and 'target' doesn't. Return false if - both exist and 'target' is the same age or younger than 'source'. - Raise DistutilsFileError if 'source' does not exist. + Return true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. + + Return false if both exist and 'target' is the same age or younger + than 'source'. Raise DistutilsFileError if 'source' does not exist. + + Note that this test is not very accurate: files created in the same second + will have the same "age". """ if not os.path.exists(source): - raise DistutilsFileError, ("file '%s' does not exist" % - os.path.abspath(source)) + raise DistutilsFileError("file '%s' does not exist" % + os.path.abspath(source)) if not os.path.exists(target): - return 1 - - from stat import ST_MTIME - mtime1 = os.stat(source)[ST_MTIME] - mtime2 = os.stat(target)[ST_MTIME] - - return mtime1 > mtime2 - -# newer () + return True + return os.stat(source).st_mtime > os.stat(target).st_mtime -def newer_pairwise (sources, targets): +def newer_pairwise(sources, targets): """Walk two filename lists in parallel, testing if each source is newer than its corresponding target. Return a pair of lists (sources, targets) where source is newer than target, according to the semantics @@ -43,19 +41,18 @@ # build a pair of lists (sources, targets) where source is newer n_sources = [] n_targets = [] - for i in range(len(sources)): - if newer(sources[i], targets[i]): - n_sources.append(sources[i]) - n_targets.append(targets[i]) + for source, target in zip(sources, targets): + if newer(source, target): + n_sources.append(source) + n_targets.append(target) - return (n_sources, n_targets) + return n_sources, n_targets -# newer_pairwise () - - -def newer_group (sources, target, missing='error'): +def newer_group(sources, target, missing='error'): """Return true if 'target' is out-of-date with respect to any file - listed in 'sources'. In other words, if 'target' exists and is newer + listed in 'sources'. + + In other words, if 'target' exists and is newer than every file in 'sources', return false; otherwise return true. 'missing' controls what we do when a source file is missing; the default ("error") is to blow up with an OSError from inside 'stat()'; @@ -68,14 +65,14 @@ """ # If the target doesn't even exist, then it's definitely out-of-date. if not os.path.exists(target): - return 1 + return True # Otherwise we have to find out the hard way: if *any* source file # is more recent than 'target', then 'target' is out-of-date and # we can immediately return true. If we fall through to the end # of the loop, then 'target' is up-to-date and we return false. - from stat import ST_MTIME - target_mtime = os.stat(target)[ST_MTIME] + target_mtime = os.stat(target).st_mtime + for source in sources: if not os.path.exists(source): if missing == 'error': # blow up when we stat() the file @@ -83,12 +80,9 @@ elif missing == 'ignore': # missing source dropped from continue # target's dependency list elif missing == 'newer': # missing source means target is - return 1 # out-of-date + return True # out-of-date - source_mtime = os.stat(source)[ST_MTIME] - if source_mtime > target_mtime: - return 1 - else: - return 0 + if os.stat(source).st_mtime > target_mtime: + return True -# newer_group () + return False Added: python/trunk/Lib/distutils/tests/test_dep_util.py ============================================================================== --- (empty file) +++ python/trunk/Lib/distutils/tests/test_dep_util.py Thu Dec 10 16:29:03 2009 @@ -0,0 +1,101 @@ +"""Tests for distutils.dep_util.""" +import unittest +import os +import time + +from distutils.dep_util import newer, newer_pairwise, newer_group +from distutils.errors import DistutilsFileError +from distutils.tests import support + +# XXX needs to be tuned for the various platforms +_ST_MIME_TIMER = 1 + +class DepUtilTestCase(support.TempdirManager, unittest.TestCase): + + def test_newer(self): + tmpdir = self.mkdtemp() + target = os.path.join(tmpdir, 'target') + source = os.path.join(tmpdir, 'source') + + # Raise DistutilsFileError if 'source' does not exist. + self.assertRaises(DistutilsFileError, newer, target, source) + + # Return true if 'source' exists and is more recently modified than + # 'target', or if 'source' exists and 'target' doesn't. + self.write_file(target) + self.assertTrue(newer(target, source)) + self.write_file(source, 'xox') + time.sleep(_ST_MIME_TIMER) # ensures ST_MTIME differs + self.write_file(target, 'xhx') + self.assertTrue(newer(target, source)) + + # Return false if both exist and 'target' is the same age or younger + # than 'source'. + self.write_file(source, 'xox'); self.write_file(target, 'xhx') + self.assertFalse(newer(target, source)) + self.write_file(target, 'xox') + time.sleep(_ST_MIME_TIMER) + self.write_file(source, 'xhx') + self.assertFalse(newer(target, source)) + + def test_newer_pairwise(self): + tmpdir = self.mkdtemp() + sources = os.path.join(tmpdir, 'sources') + targets = os.path.join(tmpdir, 'targets') + os.mkdir(sources) + os.mkdir(targets) + one = os.path.join(sources, 'one') + two = os.path.join(sources, 'two') + three = os.path.join(targets, 'three') + four = os.path.join(targets, 'four') + + self.write_file(one) + self.write_file(three) + self.write_file(four) + time.sleep(_ST_MIME_TIMER) + self.write_file(two) + + self.assertEquals(newer_pairwise([one, two], [three, four]), + ([two],[four])) + + def test_newer_group(self): + tmpdir = self.mkdtemp() + sources = os.path.join(tmpdir, 'sources') + os.mkdir(sources) + one = os.path.join(sources, 'one') + two = os.path.join(sources, 'two') + three = os.path.join(sources, 'three') + target = os.path.join(tmpdir, 'target') + + # return true if 'target' is out-of-date with respect to any file + # listed in 'sources'. + self.write_file(target) + time.sleep(_ST_MIME_TIMER) + self.write_file(one) + self.write_file(two) + self.write_file(three) + self.assertTrue(newer_group([one, two, three], target)) + + self.write_file(one) + self.write_file(three) + self.write_file(two) + time.sleep(0.1) + self.write_file(target) + self.assertFalse(newer_group([one, two, three], target)) + + # missing handling + os.remove(one) + self.assertRaises(OSError, newer_group, [one, two, three], target) + + self.assertFalse(newer_group([one, two, three], target, + missing='ignore')) + + self.assertTrue(newer_group([one, two, three], target, + missing='newer')) + + +def test_suite(): + return unittest.makeSuite(DepUtilTestCase) + +if __name__ == "__main__": + unittest.main(defaultTest="test_suite") From python-checkins at python.org Thu Dec 10 16:31:03 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 15:31:03 -0000 Subject: [Python-checkins] r76747 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Thu Dec 10 16:31:03 2009 New Revision: 76747 Log: Blocked revisions 76746 via svnmerge ........ r76746 | tarek.ziade | 2009-12-10 16:29:03 +0100 (Thu, 10 Dec 2009) | 1 line added test coverage for distutils.dep_util, and cleaned up the module ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Dec 10 16:35:35 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 15:35:35 -0000 Subject: [Python-checkins] r76748 - in python/branches/py3k: Lib/distutils/dep_util.py Lib/distutils/tests/test_dep_util.py Message-ID: Author: tarek.ziade Date: Thu Dec 10 16:35:35 2009 New Revision: 76748 Log: Merged revisions 76746 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76746 | tarek.ziade | 2009-12-10 16:29:03 +0100 (Thu, 10 Dec 2009) | 1 line added test coverage for distutils.dep_util, and cleaned up the module ........ Added: python/branches/py3k/Lib/distutils/tests/test_dep_util.py - copied unchanged from r76746, /python/trunk/Lib/distutils/tests/test_dep_util.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/dep_util.py Modified: python/branches/py3k/Lib/distutils/dep_util.py ============================================================================== --- python/branches/py3k/Lib/distutils/dep_util.py (original) +++ python/branches/py3k/Lib/distutils/dep_util.py Thu Dec 10 16:35:35 2009 @@ -9,29 +9,27 @@ import os from distutils.errors import DistutilsFileError +def newer(source, target): + """Tells if the target is newer than the source. -def newer (source, target): - """Return true if 'source' exists and is more recently modified than - 'target', or if 'source' exists and 'target' doesn't. Return false if - both exist and 'target' is the same age or younger than 'source'. - Raise DistutilsFileError if 'source' does not exist. + Return true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. + + Return false if both exist and 'target' is the same age or younger + than 'source'. Raise DistutilsFileError if 'source' does not exist. + + Note that this test is not very accurate: files created in the same second + will have the same "age". """ if not os.path.exists(source): raise DistutilsFileError("file '%s' does not exist" % os.path.abspath(source)) if not os.path.exists(target): - return 1 - - from stat import ST_MTIME - mtime1 = os.stat(source)[ST_MTIME] - mtime2 = os.stat(target)[ST_MTIME] - - return mtime1 > mtime2 - -# newer () + return True + return os.stat(source).st_mtime > os.stat(target).st_mtime -def newer_pairwise (sources, targets): +def newer_pairwise(sources, targets): """Walk two filename lists in parallel, testing if each source is newer than its corresponding target. Return a pair of lists (sources, targets) where source is newer than target, according to the semantics @@ -43,19 +41,18 @@ # build a pair of lists (sources, targets) where source is newer n_sources = [] n_targets = [] - for i in range(len(sources)): - if newer(sources[i], targets[i]): - n_sources.append(sources[i]) - n_targets.append(targets[i]) + for source, target in zip(sources, targets): + if newer(source, target): + n_sources.append(source) + n_targets.append(target) - return (n_sources, n_targets) + return n_sources, n_targets -# newer_pairwise () - - -def newer_group (sources, target, missing='error'): +def newer_group(sources, target, missing='error'): """Return true if 'target' is out-of-date with respect to any file - listed in 'sources'. In other words, if 'target' exists and is newer + listed in 'sources'. + + In other words, if 'target' exists and is newer than every file in 'sources', return false; otherwise return true. 'missing' controls what we do when a source file is missing; the default ("error") is to blow up with an OSError from inside 'stat()'; @@ -68,14 +65,14 @@ """ # If the target doesn't even exist, then it's definitely out-of-date. if not os.path.exists(target): - return 1 + return True # Otherwise we have to find out the hard way: if *any* source file # is more recent than 'target', then 'target' is out-of-date and # we can immediately return true. If we fall through to the end # of the loop, then 'target' is up-to-date and we return false. - from stat import ST_MTIME - target_mtime = os.stat(target)[ST_MTIME] + target_mtime = os.stat(target).st_mtime + for source in sources: if not os.path.exists(source): if missing == 'error': # blow up when we stat() the file @@ -83,12 +80,9 @@ elif missing == 'ignore': # missing source dropped from continue # target's dependency list elif missing == 'newer': # missing source means target is - return 1 # out-of-date + return True # out-of-date - source_mtime = os.stat(source)[ST_MTIME] - if source_mtime > target_mtime: - return 1 - else: - return 0 + if os.stat(source).st_mtime > target_mtime: + return True -# newer_group () + return False From python-checkins at python.org Thu Dec 10 16:36:17 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 15:36:17 -0000 Subject: [Python-checkins] r76749 - python/branches/release31-maint Message-ID: Author: tarek.ziade Date: Thu Dec 10 16:36:17 2009 New Revision: 76749 Log: Blocked revisions 76748 via svnmerge ................ r76748 | tarek.ziade | 2009-12-10 16:35:35 +0100 (Thu, 10 Dec 2009) | 9 lines Merged revisions 76746 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76746 | tarek.ziade | 2009-12-10 16:29:03 +0100 (Thu, 10 Dec 2009) | 1 line added test coverage for distutils.dep_util, and cleaned up the module ........ ................ Modified: python/branches/release31-maint/ (props changed) From guido at python.org Thu Dec 10 17:57:43 2009 From: guido at python.org (Guido van Rossum) Date: Thu, 10 Dec 2009 08:57:43 -0800 Subject: [Python-checkins] r76733 - python/trunk/Objects/abstract.c In-Reply-To: <1afaf6160912100445m65f0f2cfw8ad89cf7a0ecde7d@mail.gmail.com> References: <4b206d32.1a67f10a.34fa.ffffa0dbSMTPIN_ADDED@mx.google.com> <1afaf6160912100445m65f0f2cfw8ad89cf7a0ecde7d@mail.gmail.com> Message-ID: On Thu, Dec 10, 2009 at 4:45 AM, Benjamin Peterson wrote: > 2009/12/9 Brett Cannon : >> Why the change? This tie into abc stuff somehow? > > No, it's clearer (where else is PyObject_IsInstance(x, PyDict_Type) in > the source?), and avoids the problem of having isinstance fail. Yeah, but it is a semantic change, since objects that "virtually" inherit from dict (by overriding __instancecheck__) will now be treated differently. Though I'm not sure if it matters -- that requires more research than I have time for right now. -- --Guido van Rossum (python.org/~guido) From benjamin at python.org Thu Dec 10 19:37:35 2009 From: benjamin at python.org (Benjamin Peterson) Date: Thu, 10 Dec 2009 12:37:35 -0600 Subject: [Python-checkins] r76733 - python/trunk/Objects/abstract.c In-Reply-To: References: <4b206d32.1a67f10a.34fa.ffffa0dbSMTPIN_ADDED@mx.google.com> <1afaf6160912100445m65f0f2cfw8ad89cf7a0ecde7d@mail.gmail.com> Message-ID: <1afaf6160912101037k281f1ae1ja8c92afc8b38d32e@mail.gmail.com> 2009/12/10 Guido van Rossum : > On Thu, Dec 10, 2009 at 4:45 AM, Benjamin Peterson wrote: >> 2009/12/9 Brett Cannon : >>> Why the change? This tie into abc stuff somehow? >> >> No, it's clearer (where else is PyObject_IsInstance(x, PyDict_Type) in >> the source?), and avoids the problem of having isinstance fail. > > Yeah, but it is a semantic change, since objects that "virtually" > inherit from dict (by overriding __instancecheck__) will now be > treated differently. Though I'm not sure if it matters -- that > requires more research than I have time for right now. I believe the intention of the original commit (r54662) predates ABCs, so checking for a strict dictionary subclass is what is needed. -- Regards, Benjamin From python-checkins at python.org Thu Dec 10 20:29:54 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 19:29:54 -0000 Subject: [Python-checkins] r76750 - python/trunk/Lib/distutils/tests/test_dep_util.py Message-ID: Author: tarek.ziade Date: Thu Dec 10 20:29:53 2009 New Revision: 76750 Log: using an existing file to avoid dealing with a sleep to test file ages Modified: python/trunk/Lib/distutils/tests/test_dep_util.py Modified: python/trunk/Lib/distutils/tests/test_dep_util.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_dep_util.py (original) +++ python/trunk/Lib/distutils/tests/test_dep_util.py Thu Dec 10 20:29:53 2009 @@ -7,36 +7,26 @@ from distutils.errors import DistutilsFileError from distutils.tests import support -# XXX needs to be tuned for the various platforms -_ST_MIME_TIMER = 1 - class DepUtilTestCase(support.TempdirManager, unittest.TestCase): def test_newer(self): + tmpdir = self.mkdtemp() - target = os.path.join(tmpdir, 'target') - source = os.path.join(tmpdir, 'source') + new_file = os.path.join(tmpdir, 'new') + old_file = os.path.abspath(__file__) - # Raise DistutilsFileError if 'source' does not exist. - self.assertRaises(DistutilsFileError, newer, target, source) + # Raise DistutilsFileError if 'new_file' does not exist. + self.assertRaises(DistutilsFileError, newer, new_file, old_file) - # Return true if 'source' exists and is more recently modified than - # 'target', or if 'source' exists and 'target' doesn't. - self.write_file(target) - self.assertTrue(newer(target, source)) - self.write_file(source, 'xox') - time.sleep(_ST_MIME_TIMER) # ensures ST_MTIME differs - self.write_file(target, 'xhx') - self.assertTrue(newer(target, source)) - - # Return false if both exist and 'target' is the same age or younger - # than 'source'. - self.write_file(source, 'xox'); self.write_file(target, 'xhx') - self.assertFalse(newer(target, source)) - self.write_file(target, 'xox') - time.sleep(_ST_MIME_TIMER) - self.write_file(source, 'xhx') - self.assertFalse(newer(target, source)) + # Return true if 'new_file' exists and is more recently modified than + # 'old_file', or if 'new_file' exists and 'old_file' doesn't. + self.write_file(new_file) + self.assertTrue(newer(new_file, 'I_dont_exist')) + self.assertTrue(newer(new_file, old_file)) + + # Return false if both exist and 'old_file' is the same age or younger + # than 'new_file'. + self.assertFalse(newer(old_file, new_file)) def test_newer_pairwise(self): tmpdir = self.mkdtemp() @@ -46,17 +36,14 @@ os.mkdir(targets) one = os.path.join(sources, 'one') two = os.path.join(sources, 'two') - three = os.path.join(targets, 'three') + three = os.path.abspath(__file__) # I am the old file four = os.path.join(targets, 'four') - self.write_file(one) - self.write_file(three) - self.write_file(four) - time.sleep(_ST_MIME_TIMER) self.write_file(two) + self.write_file(four) self.assertEquals(newer_pairwise([one, two], [three, four]), - ([two],[four])) + ([one],[three])) def test_newer_group(self): tmpdir = self.mkdtemp() @@ -65,32 +52,24 @@ one = os.path.join(sources, 'one') two = os.path.join(sources, 'two') three = os.path.join(sources, 'three') - target = os.path.join(tmpdir, 'target') + old_file = os.path.abspath(__file__) - # return true if 'target' is out-of-date with respect to any file + # return true if 'old_file' is out-of-date with respect to any file # listed in 'sources'. - self.write_file(target) - time.sleep(_ST_MIME_TIMER) self.write_file(one) self.write_file(two) self.write_file(three) - self.assertTrue(newer_group([one, two, three], target)) - - self.write_file(one) - self.write_file(three) - self.write_file(two) - time.sleep(0.1) - self.write_file(target) - self.assertFalse(newer_group([one, two, three], target)) + self.assertTrue(newer_group([one, two, three], old_file)) + self.assertFalse(newer_group([one, two, old_file], three)) # missing handling os.remove(one) - self.assertRaises(OSError, newer_group, [one, two, three], target) + self.assertRaises(OSError, newer_group, [one, two, old_file], three) - self.assertFalse(newer_group([one, two, three], target, + self.assertFalse(newer_group([one, two, old_file], three, missing='ignore')) - self.assertTrue(newer_group([one, two, three], target, + self.assertTrue(newer_group([one, two, old_file], three, missing='newer')) From python-checkins at python.org Thu Dec 10 20:31:02 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 19:31:02 -0000 Subject: [Python-checkins] r76751 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Thu Dec 10 20:31:02 2009 New Revision: 76751 Log: Blocked revisions 76750 via svnmerge ........ r76750 | tarek.ziade | 2009-12-10 20:29:53 +0100 (Thu, 10 Dec 2009) | 1 line using an existing file to avoid dealing with a sleep to test file ages ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Dec 10 20:37:06 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 19:37:06 -0000 Subject: [Python-checkins] r76752 - in python/branches/py3k: Lib/distutils/tests/test_dep_util.py Message-ID: Author: tarek.ziade Date: Thu Dec 10 20:37:05 2009 New Revision: 76752 Log: Merged revisions 76750 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76750 | tarek.ziade | 2009-12-10 20:29:53 +0100 (Thu, 10 Dec 2009) | 1 line using an existing file to avoid dealing with a sleep to test file ages ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_dep_util.py Modified: python/branches/py3k/Lib/distutils/tests/test_dep_util.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_dep_util.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_dep_util.py Thu Dec 10 20:37:05 2009 @@ -7,36 +7,26 @@ from distutils.errors import DistutilsFileError from distutils.tests import support -# XXX needs to be tuned for the various platforms -_ST_MIME_TIMER = 1 - class DepUtilTestCase(support.TempdirManager, unittest.TestCase): def test_newer(self): + tmpdir = self.mkdtemp() - target = os.path.join(tmpdir, 'target') - source = os.path.join(tmpdir, 'source') + new_file = os.path.join(tmpdir, 'new') + old_file = os.path.abspath(__file__) - # Raise DistutilsFileError if 'source' does not exist. - self.assertRaises(DistutilsFileError, newer, target, source) + # Raise DistutilsFileError if 'new_file' does not exist. + self.assertRaises(DistutilsFileError, newer, new_file, old_file) - # Return true if 'source' exists and is more recently modified than - # 'target', or if 'source' exists and 'target' doesn't. - self.write_file(target) - self.assertTrue(newer(target, source)) - self.write_file(source, 'xox') - time.sleep(_ST_MIME_TIMER) # ensures ST_MTIME differs - self.write_file(target, 'xhx') - self.assertTrue(newer(target, source)) - - # Return false if both exist and 'target' is the same age or younger - # than 'source'. - self.write_file(source, 'xox'); self.write_file(target, 'xhx') - self.assertFalse(newer(target, source)) - self.write_file(target, 'xox') - time.sleep(_ST_MIME_TIMER) - self.write_file(source, 'xhx') - self.assertFalse(newer(target, source)) + # Return true if 'new_file' exists and is more recently modified than + # 'old_file', or if 'new_file' exists and 'old_file' doesn't. + self.write_file(new_file) + self.assertTrue(newer(new_file, 'I_dont_exist')) + self.assertTrue(newer(new_file, old_file)) + + # Return false if both exist and 'old_file' is the same age or younger + # than 'new_file'. + self.assertFalse(newer(old_file, new_file)) def test_newer_pairwise(self): tmpdir = self.mkdtemp() @@ -46,17 +36,14 @@ os.mkdir(targets) one = os.path.join(sources, 'one') two = os.path.join(sources, 'two') - three = os.path.join(targets, 'three') + three = os.path.abspath(__file__) # I am the old file four = os.path.join(targets, 'four') - self.write_file(one) - self.write_file(three) - self.write_file(four) - time.sleep(_ST_MIME_TIMER) self.write_file(two) + self.write_file(four) self.assertEquals(newer_pairwise([one, two], [three, four]), - ([two],[four])) + ([one],[three])) def test_newer_group(self): tmpdir = self.mkdtemp() @@ -65,32 +52,24 @@ one = os.path.join(sources, 'one') two = os.path.join(sources, 'two') three = os.path.join(sources, 'three') - target = os.path.join(tmpdir, 'target') + old_file = os.path.abspath(__file__) - # return true if 'target' is out-of-date with respect to any file + # return true if 'old_file' is out-of-date with respect to any file # listed in 'sources'. - self.write_file(target) - time.sleep(_ST_MIME_TIMER) self.write_file(one) self.write_file(two) self.write_file(three) - self.assertTrue(newer_group([one, two, three], target)) - - self.write_file(one) - self.write_file(three) - self.write_file(two) - time.sleep(0.1) - self.write_file(target) - self.assertFalse(newer_group([one, two, three], target)) + self.assertTrue(newer_group([one, two, three], old_file)) + self.assertFalse(newer_group([one, two, old_file], three)) # missing handling os.remove(one) - self.assertRaises(OSError, newer_group, [one, two, three], target) + self.assertRaises(OSError, newer_group, [one, two, old_file], three) - self.assertFalse(newer_group([one, two, three], target, + self.assertFalse(newer_group([one, two, old_file], three, missing='ignore')) - self.assertTrue(newer_group([one, two, three], target, + self.assertTrue(newer_group([one, two, old_file], three, missing='newer')) From python-checkins at python.org Thu Dec 10 20:38:28 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 10 Dec 2009 19:38:28 -0000 Subject: [Python-checkins] r76753 - python/branches/release31-maint Message-ID: Author: tarek.ziade Date: Thu Dec 10 20:38:28 2009 New Revision: 76753 Log: Blocked revisions 76752 via svnmerge ................ r76752 | tarek.ziade | 2009-12-10 20:37:05 +0100 (Thu, 10 Dec 2009) | 9 lines Merged revisions 76750 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76750 | tarek.ziade | 2009-12-10 20:29:53 +0100 (Thu, 10 Dec 2009) | 1 line using an existing file to avoid dealing with a sleep to test file ages ........ ................ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Fri Dec 11 00:47:50 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 11 Dec 2009 00:47:50 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76752): sum=0 Message-ID: <20091210234750.5BA7F17759@ns6635.ovh.net> py3k results for svn r76752 (hg cset 6a526c66a71e) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogMQ71hZ', '-x', 'test_httpservers'] From python-checkins at python.org Fri Dec 11 10:16:02 2009 From: python-checkins at python.org (vinay.sajip) Date: Fri, 11 Dec 2009 09:16:02 -0000 Subject: [Python-checkins] r76754 - in python: branches/py3k branches/release24-maint branches/release25-maint branches/release26-maint trunk/Lib/logging/__init__.py trunk/Misc/NEWS Message-ID: Author: vinay.sajip Date: Fri Dec 11 10:16:01 2009 New Revision: 76754 Log: Issue #7470: logging: fix bug in Unicode encoding fallback. Modified: python/branches/py3k/ (props changed) python/branches/release24-maint/ (props changed) python/branches/release25-maint/ (props changed) python/branches/release26-maint/ (props changed) 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 Fri Dec 11 10:16:01 2009 @@ -821,9 +821,9 @@ try: if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): - fs = fs.decode(stream.encoding) + ufs = fs.decode(stream.encoding) try: - stream.write(fs % msg) + stream.write(ufs % msg) except UnicodeEncodeError: #Printing to terminals sometimes fails. For example, #with an encoding of 'cp1251', the above write will @@ -831,7 +831,7 @@ #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)) + stream.write((ufs % msg).encode(stream.encoding)) else: stream.write(fs % msg) except UnicodeError: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Dec 11 10:16:01 2009 @@ -15,6 +15,8 @@ Library ------- +- Issue #7470: logging: fix bug in Unicode encoding fallback. + - Issue #5949: fixed IMAP4_SSL hang when the IMAP server response is missing proper end-of-line termination. From python-checkins at python.org Fri Dec 11 18:29:33 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Dec 2009 17:29:33 -0000 Subject: [Python-checkins] r76755 - in python/trunk: Doc/library/math.rst Lib/test/math_testcases.txt Lib/test/test_math.py Misc/NEWS Modules/mathmodule.c Message-ID: Author: mark.dickinson Date: Fri Dec 11 18:29:33 2009 New Revision: 76755 Log: Issue #3366: Add lgamma function to math module. Modified: python/trunk/Doc/library/math.rst python/trunk/Lib/test/math_testcases.txt python/trunk/Lib/test/test_math.py python/trunk/Misc/NEWS python/trunk/Modules/mathmodule.c Modified: python/trunk/Doc/library/math.rst ============================================================================== --- python/trunk/Doc/library/math.rst (original) +++ python/trunk/Doc/library/math.rst Fri Dec 11 18:29:33 2009 @@ -318,6 +318,14 @@ .. versionadded:: 2.7 +.. function:: lgamma(x) + + Return the natural logarithm of the absolute value of the Gamma + function at *x*. + + .. versionadded:: 2.7 + + Constants --------- Modified: python/trunk/Lib/test/math_testcases.txt ============================================================================== --- python/trunk/Lib/test/math_testcases.txt (original) +++ python/trunk/Lib/test/math_testcases.txt Fri Dec 11 18:29:33 2009 @@ -47,6 +47,111 @@ -- MPFR homepage at http://www.mpfr.org for more information about the -- MPFR project. +--------------------------------------------------------- +-- lgamma: log of absolute value of the gamma function -- +--------------------------------------------------------- + +-- special values +lgam0000 lgamma 0.0 -> inf divide-by-zero +lgam0001 lgamma -0.0 -> inf divide-by-zero +lgam0002 lgamma inf -> inf +lgam0003 lgamma -inf -> inf +lgam0004 lgamma nan -> nan + +-- negative integers +lgam0010 lgamma -1 -> inf divide-by-zero +lgam0011 lgamma -2 -> inf divide-by-zero +lgam0012 lgamma -1e16 -> inf divide-by-zero +lgam0013 lgamma -1e300 -> inf divide-by-zero +lgam0014 lgamma -1.79e308 -> inf divide-by-zero + +-- small positive integers give factorials +lgam0020 lgamma 1 -> 0.0 +lgam0021 lgamma 2 -> 0.0 +lgam0022 lgamma 3 -> 0.69314718055994529 +lgam0023 lgamma 4 -> 1.791759469228055 +lgam0024 lgamma 5 -> 3.1780538303479458 +lgam0025 lgamma 6 -> 4.7874917427820458 + +-- half integers +lgam0030 lgamma 0.5 -> 0.57236494292470008 +lgam0031 lgamma 1.5 -> -0.12078223763524522 +lgam0032 lgamma 2.5 -> 0.28468287047291918 +lgam0033 lgamma 3.5 -> 1.2009736023470743 +lgam0034 lgamma -0.5 -> 1.2655121234846454 +lgam0035 lgamma -1.5 -> 0.86004701537648098 +lgam0036 lgamma -2.5 -> -0.056243716497674054 +lgam0037 lgamma -3.5 -> -1.309006684993042 + +-- values near 0 +lgam0040 lgamma 0.1 -> 2.252712651734206 +lgam0041 lgamma 0.01 -> 4.5994798780420219 +lgam0042 lgamma 1e-8 -> 18.420680738180209 +lgam0043 lgamma 1e-16 -> 36.841361487904734 +lgam0044 lgamma 1e-30 -> 69.077552789821368 +lgam0045 lgamma 1e-160 -> 368.41361487904732 +lgam0046 lgamma 1e-308 -> 709.19620864216608 +lgam0047 lgamma 5.6e-309 -> 709.77602713741896 +lgam0048 lgamma 5.5e-309 -> 709.79404564292167 +lgam0049 lgamma 1e-309 -> 711.49879373516012 +lgam0050 lgamma 1e-323 -> 743.74692474082133 +lgam0051 lgamma 5e-324 -> 744.44007192138122 +lgam0060 lgamma -0.1 -> 2.3689613327287886 +lgam0061 lgamma -0.01 -> 4.6110249927528013 +lgam0062 lgamma -1e-8 -> 18.420680749724522 +lgam0063 lgamma -1e-16 -> 36.841361487904734 +lgam0064 lgamma -1e-30 -> 69.077552789821368 +lgam0065 lgamma -1e-160 -> 368.41361487904732 +lgam0066 lgamma -1e-308 -> 709.19620864216608 +lgam0067 lgamma -5.6e-309 -> 709.77602713741896 +lgam0068 lgamma -5.5e-309 -> 709.79404564292167 +lgam0069 lgamma -1e-309 -> 711.49879373516012 +lgam0070 lgamma -1e-323 -> 743.74692474082133 +lgam0071 lgamma -5e-324 -> 744.44007192138122 + +-- values near negative integers +lgam0080 lgamma -0.99999999999999989 -> 36.736800569677101 +lgam0081 lgamma -1.0000000000000002 -> 36.043653389117154 +lgam0082 lgamma -1.9999999999999998 -> 35.350506208557213 +lgam0083 lgamma -2.0000000000000004 -> 34.657359027997266 +lgam0084 lgamma -100.00000000000001 -> -331.85460524980607 +lgam0085 lgamma -99.999999999999986 -> -331.85460524980596 + +-- large inputs +lgam0100 lgamma 170 -> 701.43726380873704 +lgam0101 lgamma 171 -> 706.57306224578736 +lgam0102 lgamma 171.624 -> 709.78077443669895 +lgam0103 lgamma 171.625 -> 709.78591682948365 +lgam0104 lgamma 172 -> 711.71472580228999 +lgam0105 lgamma 2000 -> 13198.923448054265 +lgam0106 lgamma 2.55998332785163e305 -> 1.7976931348623099e+308 +lgam0107 lgamma 2.55998332785164e305 -> inf overflow +lgam0108 lgamma 1.7e308 -> inf overflow + +-- inputs for which gamma(x) is tiny +lgam0120 lgamma -100.5 -> -364.90096830942736 +lgam0121 lgamma -160.5 -> -656.88005261126432 +lgam0122 lgamma -170.5 -> -707.99843314507882 +lgam0123 lgamma -171.5 -> -713.14301641168481 +lgam0124 lgamma -176.5 -> -738.95247590846486 +lgam0125 lgamma -177.5 -> -744.13144651738037 +lgam0126 lgamma -178.5 -> -749.3160351186001 + +lgam0130 lgamma -1000.5 -> -5914.4377011168517 +lgam0131 lgamma -30000.5 -> -279278.6629959144 +lgam0132 lgamma -4503599627370495.5 -> -1.5782258434492883e+17 + +-- results close to 0: positive argument ... +lgam0150 lgamma 0.99999999999999989 -> 6.4083812134800075e-17 +lgam0151 lgamma 1.0000000000000002 -> -1.2816762426960008e-16 +lgam0152 lgamma 1.9999999999999998 -> -9.3876980655431170e-17 +lgam0153 lgamma 2.0000000000000004 -> 1.8775396131086244e-16 + +-- ... and negative argument +lgam0160 lgamma -2.7476826467 -> -5.2477408147689136e-11 +lgam0161 lgamma -2.457024738 -> 3.3464637541912932e-10 + + --------------------------- -- gamma: Gamma function -- --------------------------- Modified: python/trunk/Lib/test/test_math.py ============================================================================== --- python/trunk/Lib/test/test_math.py (original) +++ python/trunk/Lib/test/test_math.py Fri Dec 11 18:29:33 2009 @@ -48,6 +48,36 @@ n = ~(n+2**63) return n +def ulps_check(expected, got, ulps=20): + """Given non-NaN floats `expected` and `got`, + check that they're equal to within the given number of ulps. + + Returns None on success and an error message on failure.""" + + ulps_error = to_ulps(got) - to_ulps(expected) + if abs(ulps_error) <= ulps: + return None + return "error = {} ulps; permitted error = {} ulps".format(ulps_error, + ulps) + +def acc_check(expected, got, rel_err=2e-15, abs_err = 5e-323): + """Determine whether non-NaN floats a and b are equal to within a + (small) rounding error. The default values for rel_err and + abs_err are chosen to be suitable for platforms where a float is + represented by an IEEE 754 double. They allow an error of between + 9 and 19 ulps.""" + + # need to special case infinities, since inf - inf gives nan + if math.isinf(expected) and got == expected: + return None + + error = got - expected + + permitted_error = max(abs_err, rel_err * abs(expected)) + if abs(error) < permitted_error: + return None + return "error = {}; permitted error = {}".format(error, + permitted_error) def parse_mtestfile(fname): """Parse a file with test values @@ -952,13 +982,23 @@ except OverflowError: got = 'OverflowError' - diff_ulps = None + accuracy_failure = None if isinstance(got, float) and isinstance(expected, float): if math.isnan(expected) and math.isnan(got): continue if not math.isnan(expected) and not math.isnan(got): - diff_ulps = to_ulps(expected) - to_ulps(got) - if abs(diff_ulps) <= ALLOWED_ERROR: + # we use different closeness criteria for + # different functions. + if fn == 'gamma': + accuracy_failure = ulps_check(expected, got, 20) + elif fn == 'lgamma': + accuracy_failure = acc_check(expected, got, + rel_err = 5e-15, + abs_err = 5e-15) + else: + raise ValueError("don't know how to check accuracy " + "for this function") + if accuracy_failure is None: continue if isinstance(got, str) and isinstance(expected, str): @@ -966,8 +1006,8 @@ continue fail_msg = fail_fmt.format(id, fn, arg, expected, got) - if diff_ulps is not None: - fail_msg += ' ({} ulps)'.format(diff_ulps) + if accuracy_failure is not None: + fail_msg += ' ({})'.format(accuracy_failure) failures.append(fail_msg) if failures: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Dec 11 18:29:33 2009 @@ -1654,7 +1654,7 @@ - Issue #7078: Set struct.__doc__ from _struct.__doc__. -- Issue #3366: Add gamma function to math module. +- Issue #3366: Add gamma, lgamma functions to math module. - Issue #6823: Allow time.strftime() to accept a tuple with a isdst field outside of the range of [-1, 1] by normalizing the value to within that Modified: python/trunk/Modules/mathmodule.c ============================================================================== --- python/trunk/Modules/mathmodule.c (original) +++ python/trunk/Modules/mathmodule.c Fri Dec 11 18:29:33 2009 @@ -322,6 +322,60 @@ } /* + lgamma: natural log of the absolute value of the Gamma function. + For large arguments, Lanczos' formula works extremely well here. +*/ + +static double +m_lgamma(double x) +{ + double r, absx; + + /* special cases */ + if (!Py_IS_FINITE(x)) { + if (Py_IS_NAN(x)) + return x; /* lgamma(nan) = nan */ + else + return Py_HUGE_VAL; /* lgamma(+-inf) = +inf */ + } + + /* integer arguments */ + if (x == floor(x) && x <= 2.0) { + if (x <= 0.0) { + errno = EDOM; /* lgamma(n) = inf, divide-by-zero for */ + return Py_HUGE_VAL; /* integers n <= 0 */ + } + else { + return 0.0; /* lgamma(1) = lgamma(2) = 0.0 */ + } + } + + absx = fabs(x); + /* tiny arguments: lgamma(x) ~ -log(fabs(x)) for small x */ + if (absx < 1e-20) + return -log(absx); + + /* Lanczos' formula */ + if (x > 0.0) { + /* we could save a fraction of a ulp in accuracy by having a + second set of numerator coefficients for lanczos_sum that + absorbed the exp(-lanczos_g) term, and throwing out the + lanczos_g subtraction below; it's probably not worth it. */ + r = log(lanczos_sum(x)) - lanczos_g + + (x-0.5)*(log(x+lanczos_g-0.5)-1); + } + else { + r = log(pi) - log(fabs(sinpi(absx))) - log(absx) - + (log(lanczos_sum(absx)) - lanczos_g + + (absx-0.5)*(log(absx+lanczos_g-0.5)-1)); + } + if (Py_IS_INFINITY(r)) + errno = ERANGE; + return r; +} + + +/* wrapper for atan2 that deals directly with special cases before delegating to the platform libm for the remaining cases. This is necessary to get consistent behaviour across platforms. @@ -639,6 +693,8 @@ "This is the largest integral value <= x.") FUNC1A(gamma, m_tgamma, "gamma(x)\n\nGamma function at x.") +FUNC1A(lgamma, m_lgamma, + "lgamma(x)\n\nNatural logarithm of absolute value of Gamma function at x.") FUNC1(log1p, log1p, 1, "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n" "The result is computed in a way which is accurate for x near zero.") @@ -1375,6 +1431,7 @@ {"isinf", math_isinf, METH_O, math_isinf_doc}, {"isnan", math_isnan, METH_O, math_isnan_doc}, {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc}, + {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, {"log", math_log, METH_VARARGS, math_log_doc}, {"log1p", math_log1p, METH_O, math_log1p_doc}, {"log10", math_log10, METH_O, math_log10_doc}, From dickinsm at gmail.com Fri Dec 11 18:44:13 2009 From: dickinsm at gmail.com (Mark Dickinson) Date: Fri, 11 Dec 2009 17:44:13 +0000 Subject: [Python-checkins] r76754 - in python: branches/py3k branches/release24-maint branches/release25-maint branches/release26-maint trunk/Lib/logging/__init__.py trunk/Misc/NEWS In-Reply-To: <4b220dd9.1467f10a.4c22.6e68SMTPIN_ADDED@mx.google.com> References: <4b220dd9.1467f10a.4c22.6e68SMTPIN_ADDED@mx.google.com> Message-ID: <5c6f2a5d0912110944u526b2bc3o314bff74b8423bcc@mail.gmail.com> On Fri, Dec 11, 2009 at 9:16 AM, vinay.sajip wrote: > Author: vinay.sajip > Date: Fri Dec 11 10:16:01 2009 > New Revision: 76754 > > Log: > Issue #7470: logging: fix bug in Unicode encoding fallback. > > Modified: > ? python/branches/py3k/ ? (props changed) > ? python/branches/release24-maint/ ? (props changed) > ? python/branches/release25-maint/ ? (props changed) > ? python/branches/release26-maint/ ? (props changed) Vinay, did you intend to alter the svn properties on these branches, or can these changes be reverted? These property changes appear to be causing svnmerge (e.g., from trunk to py3k) to fail. > ? python/trunk/Lib/logging/__init__.py > ? python/trunk/Misc/NEWS From python-checkins at python.org Fri Dec 11 21:09:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Dec 2009 20:09:24 -0000 Subject: [Python-checkins] r76756 - in python/branches: py3k release24-maint release25-maint release26-maint Message-ID: Author: mark.dickinson Date: Fri Dec 11 21:09:24 2009 New Revision: 76756 Log: Restore the svn property changes in r76754 Modified: python/branches/py3k/ (props changed) python/branches/release24-maint/ (props changed) python/branches/release25-maint/ (props changed) python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Dec 11 21:17:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Dec 2009 20:17:18 -0000 Subject: [Python-checkins] r76757 - in python/branches/py3k: Doc/library/math.rst Lib/test/math_testcases.txt Lib/test/test_math.py Misc/NEWS Modules/mathmodule.c Message-ID: Author: mark.dickinson Date: Fri Dec 11 21:17:17 2009 New Revision: 76757 Log: Merged revisions 76755 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76755 | mark.dickinson | 2009-12-11 17:29:33 +0000 (Fri, 11 Dec 2009) | 2 lines Issue #3366: Add lgamma function to math module. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/math.rst python/branches/py3k/Lib/test/math_testcases.txt python/branches/py3k/Lib/test/test_math.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/mathmodule.c Modified: python/branches/py3k/Doc/library/math.rst ============================================================================== --- python/branches/py3k/Doc/library/math.rst (original) +++ python/branches/py3k/Doc/library/math.rst Fri Dec 11 21:17:17 2009 @@ -288,6 +288,14 @@ .. versionadded:: 3.2 +.. function:: lgamma(x) + + Return the natural logarithm of the absolute value of the Gamma + function at *x*. + + .. versionadded:: 2.7 + + Constants --------- Modified: python/branches/py3k/Lib/test/math_testcases.txt ============================================================================== --- python/branches/py3k/Lib/test/math_testcases.txt (original) +++ python/branches/py3k/Lib/test/math_testcases.txt Fri Dec 11 21:17:17 2009 @@ -47,6 +47,111 @@ -- MPFR homepage at http://www.mpfr.org for more information about the -- MPFR project. +--------------------------------------------------------- +-- lgamma: log of absolute value of the gamma function -- +--------------------------------------------------------- + +-- special values +lgam0000 lgamma 0.0 -> inf divide-by-zero +lgam0001 lgamma -0.0 -> inf divide-by-zero +lgam0002 lgamma inf -> inf +lgam0003 lgamma -inf -> inf +lgam0004 lgamma nan -> nan + +-- negative integers +lgam0010 lgamma -1 -> inf divide-by-zero +lgam0011 lgamma -2 -> inf divide-by-zero +lgam0012 lgamma -1e16 -> inf divide-by-zero +lgam0013 lgamma -1e300 -> inf divide-by-zero +lgam0014 lgamma -1.79e308 -> inf divide-by-zero + +-- small positive integers give factorials +lgam0020 lgamma 1 -> 0.0 +lgam0021 lgamma 2 -> 0.0 +lgam0022 lgamma 3 -> 0.69314718055994529 +lgam0023 lgamma 4 -> 1.791759469228055 +lgam0024 lgamma 5 -> 3.1780538303479458 +lgam0025 lgamma 6 -> 4.7874917427820458 + +-- half integers +lgam0030 lgamma 0.5 -> 0.57236494292470008 +lgam0031 lgamma 1.5 -> -0.12078223763524522 +lgam0032 lgamma 2.5 -> 0.28468287047291918 +lgam0033 lgamma 3.5 -> 1.2009736023470743 +lgam0034 lgamma -0.5 -> 1.2655121234846454 +lgam0035 lgamma -1.5 -> 0.86004701537648098 +lgam0036 lgamma -2.5 -> -0.056243716497674054 +lgam0037 lgamma -3.5 -> -1.309006684993042 + +-- values near 0 +lgam0040 lgamma 0.1 -> 2.252712651734206 +lgam0041 lgamma 0.01 -> 4.5994798780420219 +lgam0042 lgamma 1e-8 -> 18.420680738180209 +lgam0043 lgamma 1e-16 -> 36.841361487904734 +lgam0044 lgamma 1e-30 -> 69.077552789821368 +lgam0045 lgamma 1e-160 -> 368.41361487904732 +lgam0046 lgamma 1e-308 -> 709.19620864216608 +lgam0047 lgamma 5.6e-309 -> 709.77602713741896 +lgam0048 lgamma 5.5e-309 -> 709.79404564292167 +lgam0049 lgamma 1e-309 -> 711.49879373516012 +lgam0050 lgamma 1e-323 -> 743.74692474082133 +lgam0051 lgamma 5e-324 -> 744.44007192138122 +lgam0060 lgamma -0.1 -> 2.3689613327287886 +lgam0061 lgamma -0.01 -> 4.6110249927528013 +lgam0062 lgamma -1e-8 -> 18.420680749724522 +lgam0063 lgamma -1e-16 -> 36.841361487904734 +lgam0064 lgamma -1e-30 -> 69.077552789821368 +lgam0065 lgamma -1e-160 -> 368.41361487904732 +lgam0066 lgamma -1e-308 -> 709.19620864216608 +lgam0067 lgamma -5.6e-309 -> 709.77602713741896 +lgam0068 lgamma -5.5e-309 -> 709.79404564292167 +lgam0069 lgamma -1e-309 -> 711.49879373516012 +lgam0070 lgamma -1e-323 -> 743.74692474082133 +lgam0071 lgamma -5e-324 -> 744.44007192138122 + +-- values near negative integers +lgam0080 lgamma -0.99999999999999989 -> 36.736800569677101 +lgam0081 lgamma -1.0000000000000002 -> 36.043653389117154 +lgam0082 lgamma -1.9999999999999998 -> 35.350506208557213 +lgam0083 lgamma -2.0000000000000004 -> 34.657359027997266 +lgam0084 lgamma -100.00000000000001 -> -331.85460524980607 +lgam0085 lgamma -99.999999999999986 -> -331.85460524980596 + +-- large inputs +lgam0100 lgamma 170 -> 701.43726380873704 +lgam0101 lgamma 171 -> 706.57306224578736 +lgam0102 lgamma 171.624 -> 709.78077443669895 +lgam0103 lgamma 171.625 -> 709.78591682948365 +lgam0104 lgamma 172 -> 711.71472580228999 +lgam0105 lgamma 2000 -> 13198.923448054265 +lgam0106 lgamma 2.55998332785163e305 -> 1.7976931348623099e+308 +lgam0107 lgamma 2.55998332785164e305 -> inf overflow +lgam0108 lgamma 1.7e308 -> inf overflow + +-- inputs for which gamma(x) is tiny +lgam0120 lgamma -100.5 -> -364.90096830942736 +lgam0121 lgamma -160.5 -> -656.88005261126432 +lgam0122 lgamma -170.5 -> -707.99843314507882 +lgam0123 lgamma -171.5 -> -713.14301641168481 +lgam0124 lgamma -176.5 -> -738.95247590846486 +lgam0125 lgamma -177.5 -> -744.13144651738037 +lgam0126 lgamma -178.5 -> -749.3160351186001 + +lgam0130 lgamma -1000.5 -> -5914.4377011168517 +lgam0131 lgamma -30000.5 -> -279278.6629959144 +lgam0132 lgamma -4503599627370495.5 -> -1.5782258434492883e+17 + +-- results close to 0: positive argument ... +lgam0150 lgamma 0.99999999999999989 -> 6.4083812134800075e-17 +lgam0151 lgamma 1.0000000000000002 -> -1.2816762426960008e-16 +lgam0152 lgamma 1.9999999999999998 -> -9.3876980655431170e-17 +lgam0153 lgamma 2.0000000000000004 -> 1.8775396131086244e-16 + +-- ... and negative argument +lgam0160 lgamma -2.7476826467 -> -5.2477408147689136e-11 +lgam0161 lgamma -2.457024738 -> 3.3464637541912932e-10 + + --------------------------- -- gamma: Gamma function -- --------------------------- 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 Dec 11 21:17:17 2009 @@ -48,6 +48,36 @@ n = ~(n+2**63) return n +def ulps_check(expected, got, ulps=20): + """Given non-NaN floats `expected` and `got`, + check that they're equal to within the given number of ulps. + + Returns None on success and an error message on failure.""" + + ulps_error = to_ulps(got) - to_ulps(expected) + if abs(ulps_error) <= ulps: + return None + return "error = {} ulps; permitted error = {} ulps".format(ulps_error, + ulps) + +def acc_check(expected, got, rel_err=2e-15, abs_err = 5e-323): + """Determine whether non-NaN floats a and b are equal to within a + (small) rounding error. The default values for rel_err and + abs_err are chosen to be suitable for platforms where a float is + represented by an IEEE 754 double. They allow an error of between + 9 and 19 ulps.""" + + # need to special case infinities, since inf - inf gives nan + if math.isinf(expected) and got == expected: + return None + + error = got - expected + + permitted_error = max(abs_err, rel_err * abs(expected)) + if abs(error) < permitted_error: + return None + return "error = {}; permitted error = {}".format(error, + permitted_error) def parse_mtestfile(fname): """Parse a file with test values @@ -949,13 +979,23 @@ except OverflowError: got = 'OverflowError' - diff_ulps = None + accuracy_failure = None if isinstance(got, float) and isinstance(expected, float): if math.isnan(expected) and math.isnan(got): continue if not math.isnan(expected) and not math.isnan(got): - diff_ulps = to_ulps(expected) - to_ulps(got) - if abs(diff_ulps) <= ALLOWED_ERROR: + # we use different closeness criteria for + # different functions. + if fn == 'gamma': + accuracy_failure = ulps_check(expected, got, 20) + elif fn == 'lgamma': + accuracy_failure = acc_check(expected, got, + rel_err = 5e-15, + abs_err = 5e-15) + else: + raise ValueError("don't know how to check accuracy " + "for this function") + if accuracy_failure is None: continue if isinstance(got, str) and isinstance(expected, str): @@ -963,8 +1003,8 @@ continue fail_msg = fail_fmt.format(id, fn, arg, expected, got) - if diff_ulps is not None: - fail_msg += ' ({} ulps)'.format(diff_ulps) + if accuracy_failure is not None: + fail_msg += ' ({})'.format(accuracy_failure) failures.append(fail_msg) if failures: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Dec 11 21:17:17 2009 @@ -443,7 +443,7 @@ - Issue #7078: Set struct.__doc__ from _struct.__doc__. -- Issue #3366: Add gamma function to math module. +- Issue #3366: Add gamma, lgamma functions to math module. - Issue #6877: It is now possible to link the readline extension to the libedit readline emulation on OSX 10.5 or later. Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Fri Dec 11 21:17:17 2009 @@ -322,6 +322,60 @@ } /* + lgamma: natural log of the absolute value of the Gamma function. + For large arguments, Lanczos' formula works extremely well here. +*/ + +static double +m_lgamma(double x) +{ + double r, absx; + + /* special cases */ + if (!Py_IS_FINITE(x)) { + if (Py_IS_NAN(x)) + return x; /* lgamma(nan) = nan */ + else + return Py_HUGE_VAL; /* lgamma(+-inf) = +inf */ + } + + /* integer arguments */ + if (x == floor(x) && x <= 2.0) { + if (x <= 0.0) { + errno = EDOM; /* lgamma(n) = inf, divide-by-zero for */ + return Py_HUGE_VAL; /* integers n <= 0 */ + } + else { + return 0.0; /* lgamma(1) = lgamma(2) = 0.0 */ + } + } + + absx = fabs(x); + /* tiny arguments: lgamma(x) ~ -log(fabs(x)) for small x */ + if (absx < 1e-20) + return -log(absx); + + /* Lanczos' formula */ + if (x > 0.0) { + /* we could save a fraction of a ulp in accuracy by having a + second set of numerator coefficients for lanczos_sum that + absorbed the exp(-lanczos_g) term, and throwing out the + lanczos_g subtraction below; it's probably not worth it. */ + r = log(lanczos_sum(x)) - lanczos_g + + (x-0.5)*(log(x+lanczos_g-0.5)-1); + } + else { + r = log(pi) - log(fabs(sinpi(absx))) - log(absx) - + (log(lanczos_sum(absx)) - lanczos_g + + (absx-0.5)*(log(absx+lanczos_g-0.5)-1)); + } + if (Py_IS_INFINITY(r)) + errno = ERANGE; + return r; +} + + +/* wrapper for atan2 that deals directly with special cases before delegating to the platform libm for the remaining cases. This is necessary to get consistent behaviour across platforms. @@ -694,6 +748,8 @@ FUNC1A(gamma, m_tgamma, "gamma(x)\n\nGamma function at x.") +FUNC1A(lgamma, m_lgamma, + "lgamma(x)\n\nNatural logarithm of absolute value of Gamma function at x.") FUNC1(log1p, log1p, 1, "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n" "The result is computed in a way which is accurate for x near zero.") @@ -1448,6 +1504,7 @@ {"isinf", math_isinf, METH_O, math_isinf_doc}, {"isnan", math_isnan, METH_O, math_isnan_doc}, {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc}, + {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, {"log", math_log, METH_VARARGS, math_log_doc}, {"log1p", math_log1p, METH_O, math_log1p_doc}, {"log10", math_log10, METH_O, math_log10_doc}, From python-checkins at python.org Fri Dec 11 21:17:43 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Dec 2009 20:17:43 -0000 Subject: [Python-checkins] r76758 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Fri Dec 11 21:17:43 2009 New Revision: 76758 Log: Blocked revisions 76757 via svnmerge ................ r76757 | mark.dickinson | 2009-12-11 20:17:17 +0000 (Fri, 11 Dec 2009) | 9 lines Merged revisions 76755 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76755 | mark.dickinson | 2009-12-11 17:29:33 +0000 (Fri, 11 Dec 2009) | 2 lines Issue #3366: Add lgamma function to math module. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Dec 11 21:18:19 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Dec 2009 20:18:19 -0000 Subject: [Python-checkins] r76759 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Fri Dec 11 21:18:18 2009 New Revision: 76759 Log: Blocked revisions 76755 via svnmerge ........ r76755 | mark.dickinson | 2009-12-11 17:29:33 +0000 (Fri, 11 Dec 2009) | 2 lines Issue #3366: Add lgamma function to math module. ........ Modified: python/branches/release26-maint/ (props changed) From solipsis at pitrou.net Sat Dec 12 00:47:21 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 12 Dec 2009 00:47:21 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76757): sum=0 Message-ID: <20091211234721.1DEEE17A13@ns6635.ovh.net> py3k results for svn r76757 (hg cset 32af8a9ebcad) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog7CsbtK', '-x', 'test_httpservers'] From python-checkins at python.org Sat Dec 12 12:49:00 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 12 Dec 2009 11:49:00 -0000 Subject: [Python-checkins] r76760 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Sat Dec 12 12:49:00 2009 New Revision: 76760 Log: added more details for requesite #2 Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Sat Dec 12 12:49:00 2009 @@ -78,7 +78,9 @@ also a micro revision). 2. most projects need special meaning versions for "pre-releases" (such as "alpha", "beta", "rc"), and these have widely used aliases ("a" stands - for "alpha", "b" for "beta" and "c" for "rc"). + for "alpha", "b" for "beta" and "c" for "rc"). And these pre-release + versions make it impossible to use a simple alphanumerical ordering + of the version string components. (Example: 3.1a1 < 3.1) 3. some projects also need "post-releases" of regular versions, mainly for installer work which can't be clearly expressed otherwise. 4. development versions allow packagers of unreleased work to avoid version From python-checkins at python.org Sat Dec 12 19:36:47 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 12 Dec 2009 18:36:47 -0000 Subject: [Python-checkins] r76761 - in python/branches/release26-maint: Lib/imaplib.py Lib/test/test_imaplib.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sat Dec 12 19:36:47 2009 New Revision: 76761 Log: Merged revisions 76726-76727 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk This merge changes the test harness to manually do the socket shutdown that was made automatic in trunk by enhancement patch r73638 (issue 6267). Patch modification by Scott Dial. ........ r76726 | r.david.murray | 2009-12-09 10:15:31 -0500 (Wed, 09 Dec 2009) | 6 lines Issue 5949: fixed IMAP4_SSL hang when the IMAP server response is missing proper end-of-line termination. Patch and tests by Scott Dial. The new tests include a test harness which will make it easier to add additional tests. ........ r76727 | r.david.murray | 2009-12-09 11:41:39 -0500 (Wed, 09 Dec 2009) | 2 lines Skip new imaplib SSL tests if ssl is not available. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/imaplib.py python/branches/release26-maint/Lib/test/test_imaplib.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/imaplib.py ============================================================================== --- python/branches/release26-maint/Lib/imaplib.py (original) +++ python/branches/release26-maint/Lib/imaplib.py Sat Dec 12 19:36:47 2009 @@ -1001,6 +1001,8 @@ raise self.abort('socket error: EOF') # Protocol mandates all lines terminated by CRLF + if not line.endswith('\r\n'): + raise self.abort('socket error: unterminated line') line = line[:-2] if __debug__: @@ -1167,7 +1169,7 @@ while 1: char = self.sslobj.read(1) line.append(char) - if char == "\n": return ''.join(line) + if char in ("\n", ""): return ''.join(line) def send(self, data): Modified: python/branches/release26-maint/Lib/test/test_imaplib.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_imaplib.py (original) +++ python/branches/release26-maint/Lib/test/test_imaplib.py Sat Dec 12 19:36:47 2009 @@ -1,11 +1,31 @@ +from test import test_support as support +# If we end up with a significant number of tests that don't require +# threading, this test module should be split. Right now we skip +# them all if we don't have threading. +threading = support.import_module('threading') + +from contextlib import contextmanager import imaplib +import os.path +import select +import socket +import SocketServer +import sys import time -from test import test_support +from test_support import verbose import unittest +try: + import ssl +except ImportError: + ssl = None + +CERTFILE = None + class TestImaplib(unittest.TestCase): + def test_that_Time2Internaldate_returns_a_result(self): # We can check only that it successfully produces a result, # not the correctness of the result itself, since the result @@ -17,9 +37,176 @@ imaplib.Time2Internaldate(t) +if ssl: + + class SecureTCPServer(SocketServer.TCPServer): + + def get_request(self): + newsocket, fromaddr = self.socket.accept() + connstream = ssl.wrap_socket(newsocket, + server_side=True, + certfile=CERTFILE) + return connstream, fromaddr + + IMAP4_SSL = imaplib.IMAP4_SSL + +else: + + class SecureTCPServer: + pass + + IMAP4_SSL = None + +class TimeoutStreamRequestHandler(SocketServer.StreamRequestHandler): + + timeout = 1 + + def setup(self): + self.connection = self.request + if self.timeout is not None: + self.connection.settimeout(self.timeout) + self.rfile = self.connection.makefile('rb', self.rbufsize) + self.wfile = self.connection.makefile('wb', self.wbufsize) + + +class SimpleIMAPHandler(TimeoutStreamRequestHandler): + + def _send(self, message): + if verbose: print "SENT:", message.strip() + self.wfile.write(message) + + def handle(self): + # Send a welcome message. + self._send('* OK IMAP4rev1\r\n') + while 1: + # Gather up input until we receive a line terminator or we timeout. + # Accumulate read(1) because it's simpler to handle the differences + # between naked sockets and SSL sockets. + line = '' + while 1: + try: + part = self.rfile.read(1) + if part == '': + # Naked sockets return empty strings.. + return + line += part + except IOError: + # ..but SSLSockets throw exceptions. + return + if line.endswith('\r\n'): + break + + if verbose: print 'GOT:', line.strip() + splitline = line.split() + tag = splitline[0] + cmd = splitline[1] + args = splitline[2:] + + if hasattr(self, 'cmd_%s' % (cmd,)): + getattr(self, 'cmd_%s' % (cmd,))(tag, args) + else: + self._send('%s BAD %s unknown\r\n' % (tag, cmd)) + + def cmd_CAPABILITY(self, tag, args): + self._send('* CAPABILITY IMAP4rev1\r\n') + self._send('%s OK CAPABILITY completed\r\n' % (tag,)) + +class BaseThreadedNetworkedTests(unittest.TestCase): + + def make_server(self, addr, hdlr): + + class MyServer(self.server_class): + def handle_error(self, request, client_address): + self.close_request(request) + self.server_close() + raise + + if verbose: print "creating server" + server = MyServer(addr, hdlr) + self.assertEquals(server.server_address, server.socket.getsockname()) + + if verbose: + print "server created" + print "ADDR =", addr + print "CLASS =", self.server_class + print "HDLR =", server.RequestHandlerClass + + t = threading.Thread( + name='%s serving' % self.server_class, + target=server.serve_forever, + # Short poll interval to make the test finish quickly. + # Time between requests is short enough that we won't wake + # up spuriously too many times. + kwargs={'poll_interval':0.01}) + t.daemon = True # In case this function raises. + t.start() + if verbose: print "server running" + return server, t + + def reap_server(self, server, thread): + if verbose: print "waiting for server" + server.shutdown() + thread.join() + if verbose: print "done" + + @contextmanager + def reaped_server(self, hdlr): + server, thread = self.make_server((support.HOST, 0), hdlr) + try: + yield server + finally: + self.reap_server(server, thread) + + def test_connect(self): + with self.reaped_server(SimpleIMAPHandler) as server: + client = self.imap_class(*server.server_address) + client.shutdown() + + def test_issue5949(self): + + class EOFHandler(TimeoutStreamRequestHandler): + def handle(self): + # EOF without sending a complete welcome message. + self.wfile.write('* OK') + # explicitly shutdown. socket.close() merely releases + # the socket and waits for GC to perform the actual close. + self.request.shutdown(socket.SHUT_WR) + + with self.reaped_server(EOFHandler) as server: + self.assertRaises(imaplib.IMAP4.abort, + self.imap_class, *server.server_address) + +class ThreadedNetworkedTests(BaseThreadedNetworkedTests): + + server_class = SocketServer.TCPServer + imap_class = imaplib.IMAP4 + + +class ThreadedNetworkedTestsSSL(BaseThreadedNetworkedTests): + + server_class = SecureTCPServer + imap_class = IMAP4_SSL + + def test_main(): - test_support.run_unittest(TestImaplib) + tests = [TestImaplib] + + if support.is_resource_enabled('network'): + if ssl: + global CERTFILE + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, + "keycert.pem") + if not os.path.exists(CERTFILE): + raise support.TestFailed("Can't read certificate files!") + tests.append(ThreadedNetworkedTestsSSL) + tests.append(ThreadedNetworkedTests) + + threadinfo = support.threading_setup() + + support.run_unittest(*tests) + support.threading_cleanup(*threadinfo) if __name__ == "__main__": - unittest.main() + support.use_resources = ['network'] + test_main() Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Dec 12 19:36:47 2009 @@ -33,6 +33,9 @@ Library ------- +- Issue #5949: fixed IMAP4_SSL hang when the IMAP server response is + missing proper end-of-line termination. + - Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d - Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is From python-checkins at python.org Sat Dec 12 19:38:24 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 12 Dec 2009 18:38:24 -0000 Subject: [Python-checkins] r76762 - in python/branches/release31-maint: Lib/imaplib.py Lib/test/test_imaplib.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sat Dec 12 19:38:24 2009 New Revision: 76762 Log: Merged revisions 76730 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76730 | r.david.murray | 2009-12-09 21:08:06 -0500 (Wed, 09 Dec 2009) | 20 lines Merged revisions 76726-76727 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk The merge adds a test with an invalid rather than a missing line end, since the py3K code passed the original issue 5949 test. New test also by Scott Dial. ........ r76726 | r.david.murray | 2009-12-09 10:15:31 -0500 (Wed, 09 Dec 2009) | 6 lines Issue 5949: fixed IMAP4_SSL hang when the IMAP server response is missing proper end-of-line termination. Patch and tests by Scott Dial. The new tests include a test harness which will make it easier to add additional tests. ........ r76727 | r.david.murray | 2009-12-09 11:41:39 -0500 (Wed, 09 Dec 2009) | 2 lines Skip new imaplib SSL tests if ssl is not available. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/imaplib.py python/branches/release31-maint/Lib/test/test_imaplib.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/imaplib.py ============================================================================== --- python/branches/release31-maint/Lib/imaplib.py (original) +++ python/branches/release31-maint/Lib/imaplib.py Sat Dec 12 19:38:24 2009 @@ -1023,6 +1023,8 @@ raise self.abort('socket error: EOF') # Protocol mandates all lines terminated by CRLF + if not line.endswith(b'\r\n'): + raise self.abort('socket error: unterminated line') line = line[:-2] if __debug__: Modified: python/branches/release31-maint/Lib/test/test_imaplib.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_imaplib.py (original) +++ python/branches/release31-maint/Lib/test/test_imaplib.py Sat Dec 12 19:38:24 2009 @@ -1,11 +1,31 @@ +from test import support +# If we end up with a significant number of tests that don't require +# threading, this test module should be split. Right now we skip +# them all if we don't have threading. +threading = support.import_module('threading') + +from contextlib import contextmanager import imaplib +import os.path +import select +import socket +import socketserver +import sys import time -from test import support +from test.support import reap_threads, verbose import unittest +try: + import ssl +except ImportError: + ssl = None + +CERTFILE = None + class TestImaplib(unittest.TestCase): + def test_that_Time2Internaldate_returns_a_result(self): # We can check only that it successfully produces a result, # not the correctness of the result itself, since the result @@ -17,9 +37,180 @@ imaplib.Time2Internaldate(t) +if ssl: + + class SecureTCPServer(socketserver.TCPServer): + + def get_request(self): + newsocket, fromaddr = self.socket.accept() + connstream = ssl.wrap_socket(newsocket, + server_side=True, + certfile=CERTFILE) + return connstream, fromaddr + + IMAP4_SSL = imaplib.IMAP4_SSL + +else: + + class SecureTCPServer: + pass + + IMAP4_SSL = None + + +class SimpleIMAPHandler(socketserver.StreamRequestHandler): + + timeout = 1 + + def _send(self, message): + if verbose: print("SENT:", message.strip()) + self.wfile.write(message) + + def handle(self): + # Send a welcome message. + self._send(b'* OK IMAP4rev1\r\n') + while 1: + # Gather up input until we receive a line terminator or we timeout. + # Accumulate read(1) because it's simpler to handle the differences + # between naked sockets and SSL sockets. + line = b'' + while 1: + try: + part = self.rfile.read(1) + if part == b'': + # Naked sockets return empty strings.. + return + line += part + except IOError: + # ..but SSLSockets throw exceptions. + return + if line.endswith(b'\r\n'): + break + + if verbose: print('GOT:', line.strip()) + splitline = line.split() + tag = splitline[0].decode('ASCII') + cmd = splitline[1].decode('ASCII') + args = splitline[2:] + + if hasattr(self, 'cmd_'+cmd): + getattr(self, 'cmd_'+cmd)(tag, args) + else: + self._send('{} BAD {} unknown\r\n'.format(tag, cmd).encode('ASCII')) + + def cmd_CAPABILITY(self, tag, args): + self._send(b'* CAPABILITY IMAP4rev1\r\n') + self._send('{} OK CAPABILITY completed\r\n'.format(tag).encode('ASCII')) + + +class BaseThreadedNetworkedTests(unittest.TestCase): + + def make_server(self, addr, hdlr): + + class MyServer(self.server_class): + def handle_error(self, request, client_address): + self.close_request(request) + self.server_close() + raise + + if verbose: print("creating server") + server = MyServer(addr, hdlr) + self.assertEquals(server.server_address, server.socket.getsockname()) + + if verbose: + print("server created") + print("ADDR =", addr) + print("CLASS =", self.server_class) + print("HDLR =", server.RequestHandlerClass) + + t = threading.Thread( + name='%s serving' % self.server_class, + target=server.serve_forever, + # Short poll interval to make the test finish quickly. + # Time between requests is short enough that we won't wake + # up spuriously too many times. + kwargs={'poll_interval':0.01}) + t.daemon = True # In case this function raises. + t.start() + if verbose: print("server running") + return server, t + + def reap_server(self, server, thread): + if verbose: print("waiting for server") + server.shutdown() + thread.join() + if verbose: print("done") + + @contextmanager + def reaped_server(self, hdlr): + server, thread = self.make_server((support.HOST, 0), hdlr) + try: + yield server + finally: + self.reap_server(server, thread) + + @reap_threads + def test_connect(self): + with self.reaped_server(SimpleIMAPHandler) as server: + client = self.imap_class(*server.server_address) + client.shutdown() + + @reap_threads + def test_issue5949(self): + + class EOFHandler(socketserver.StreamRequestHandler): + def handle(self): + # EOF without sending a complete welcome message. + self.wfile.write(b'* OK') + + with self.reaped_server(EOFHandler) as server: + self.assertRaises(imaplib.IMAP4.abort, + self.imap_class, *server.server_address) + + @reap_threads + def test_line_termination(self): + + class BadNewlineHandler(SimpleIMAPHandler): + + def cmd_CAPABILITY(self, tag, args): + self._send(b'* CAPABILITY IMAP4rev1 AUTH\n') + self._send('{} OK CAPABILITY completed\r\n'.format(tag).encode('ASCII')) + + with self.reaped_server(BadNewlineHandler) as server: + self.assertRaises(imaplib.IMAP4.abort, + self.imap_class, *server.server_address) + + + +class ThreadedNetworkedTests(BaseThreadedNetworkedTests): + + server_class = socketserver.TCPServer + imap_class = imaplib.IMAP4 + + + at unittest.skipUnless(ssl, "SSL not available") +class ThreadedNetworkedTestsSSL(BaseThreadedNetworkedTests): + + server_class = SecureTCPServer + imap_class = IMAP4_SSL + + def test_main(): - support.run_unittest(TestImaplib) + + tests = [TestImaplib] + + if support.is_resource_enabled('network'): + if ssl: + global CERTFILE + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, + "keycert.pem") + if not os.path.exists(CERTFILE): + raise support.TestFailed("Can't read certificate files!") + tests.extend([ThreadedNetworkedTests, ThreadedNetworkedTestsSSL]) + + support.run_unittest(*tests) if __name__ == "__main__": - unittest.main() + support.use_resources = ['network'] + test_main() Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sat Dec 12 19:38:24 2009 @@ -55,6 +55,9 @@ Library ------- +- Issue #5949: added check for correct lineends in input from IMAP server + in imaplib. + - Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d - Issue #6986: Fix crash in the JSON C accelerator when called with the From python-checkins at python.org Sat Dec 12 20:13:08 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 12 Dec 2009 19:13:08 -0000 Subject: [Python-checkins] r76763 - in python/trunk: Lib/test/test_tuple.py Objects/tupleobject.c Message-ID: Author: antoine.pitrou Date: Sat Dec 12 20:13:08 2009 New Revision: 76763 Log: Issue #7466: segmentation fault when the garbage collector is called in the middle of populating a tuple. Patch by Florent Xicluna. (note: no NEWS entry for trunk since the bug was introduced in 2.7/3.1) Modified: python/trunk/Lib/test/test_tuple.py python/trunk/Objects/tupleobject.c Modified: python/trunk/Lib/test/test_tuple.py ============================================================================== --- python/trunk/Lib/test/test_tuple.py (original) +++ python/trunk/Lib/test/test_tuple.py Sat Dec 12 20:13:08 2009 @@ -146,6 +146,9 @@ pass self.check_track_dynamic(MyTuple, True) + def test_bug7466(self): + # Trying to untrack an unfinished tuple could crash Python + self._not_tracked(tuple(gc.collect() for i in range(101))) def test_main(): test_support.run_unittest(TupleTest) Modified: python/trunk/Objects/tupleobject.c ============================================================================== --- python/trunk/Objects/tupleobject.c (original) +++ python/trunk/Objects/tupleobject.c Sat Dec 12 20:13:08 2009 @@ -875,7 +875,8 @@ /* XXX UNREF/NEWREF interface should be more symmetrical */ _Py_DEC_REFTOTAL; - _PyObject_GC_UNTRACK(v); + if (_PyObject_GC_IS_TRACKED(v)) + _PyObject_GC_UNTRACK(v); _Py_ForgetReference((PyObject *) v); /* DECREF items deleted by shrinkage */ for (i = newsize; i < oldsize; i++) { From python-checkins at python.org Sat Dec 12 20:18:27 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 12 Dec 2009 19:18:27 -0000 Subject: [Python-checkins] r76764 - in python/branches/py3k: Lib/test/test_tuple.py Misc/NEWS Objects/tupleobject.c Message-ID: Author: antoine.pitrou Date: Sat Dec 12 20:18:27 2009 New Revision: 76764 Log: Merged revisions 76763 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76763 | antoine.pitrou | 2009-12-12 20:13:08 +0100 (sam., 12 d?c. 2009) | 7 lines Issue #7466: segmentation fault when the garbage collector is called in the middle of populating a tuple. Patch by Florent Xicluna. (note: no NEWS entry for trunk since the bug was introduced in 2.7/3.1) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_tuple.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/tupleobject.c Modified: python/branches/py3k/Lib/test/test_tuple.py ============================================================================== --- python/branches/py3k/Lib/test/test_tuple.py (original) +++ python/branches/py3k/Lib/test/test_tuple.py Sat Dec 12 20:18:27 2009 @@ -146,6 +146,9 @@ pass self.check_track_dynamic(MyTuple, True) + def test_bug7466(self): + # Trying to untrack an unfinished tuple could crash Python + self._not_tracked(tuple(gc.collect() for i in range(101))) def test_main(): support.run_unittest(TupleTest) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 12 20:18:27 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7466: segmentation fault when the garbage collector is called + in the middle of populating a tuple. Patch by Florent Xicluna. + - Issue #7419: setlocale() could crash the interpreter on Windows when called with invalid values. Modified: python/branches/py3k/Objects/tupleobject.c ============================================================================== --- python/branches/py3k/Objects/tupleobject.c (original) +++ python/branches/py3k/Objects/tupleobject.c Sat Dec 12 20:18:27 2009 @@ -850,7 +850,8 @@ /* XXX UNREF/NEWREF interface should be more symmetrical */ _Py_DEC_REFTOTAL; - _PyObject_GC_UNTRACK(v); + if (_PyObject_GC_IS_TRACKED(v)) + _PyObject_GC_UNTRACK(v); _Py_ForgetReference((PyObject *) v); /* DECREF items deleted by shrinkage */ for (i = newsize; i < oldsize; i++) { From python-checkins at python.org Sat Dec 12 20:26:06 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 12 Dec 2009 19:26:06 -0000 Subject: [Python-checkins] r76765 - in python/branches/release31-maint: Lib/test/test_tuple.py Misc/NEWS Objects/tupleobject.c Message-ID: Author: antoine.pitrou Date: Sat Dec 12 20:26:06 2009 New Revision: 76765 Log: Merged revisions 76764 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76764 | antoine.pitrou | 2009-12-12 20:18:27 +0100 (sam., 12 d?c. 2009) | 12 lines Merged revisions 76763 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76763 | antoine.pitrou | 2009-12-12 20:13:08 +0100 (sam., 12 d?c. 2009) | 7 lines Issue #7466: segmentation fault when the garbage collector is called in the middle of populating a tuple. Patch by Florent Xicluna. (note: no NEWS entry for trunk since the bug was introduced in 2.7/3.1) ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_tuple.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Objects/tupleobject.c Modified: python/branches/release31-maint/Lib/test/test_tuple.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_tuple.py (original) +++ python/branches/release31-maint/Lib/test/test_tuple.py Sat Dec 12 20:26:06 2009 @@ -146,6 +146,9 @@ pass self.check_track_dynamic(MyTuple, True) + def test_bug7466(self): + # Trying to untrack an unfinished tuple could crash Python + self._not_tracked(tuple(gc.collect() for i in range(101))) def test_main(): support.run_unittest(TupleTest) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sat Dec 12 20:26:06 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7466: segmentation fault when the garbage collector is called + in the middle of populating a tuple. Patch by Florent Xicluna. + - Issue #7419: setlocale() could crash the interpreter on Windows when called with invalid values. Modified: python/branches/release31-maint/Objects/tupleobject.c ============================================================================== --- python/branches/release31-maint/Objects/tupleobject.c (original) +++ python/branches/release31-maint/Objects/tupleobject.c Sat Dec 12 20:26:06 2009 @@ -850,7 +850,8 @@ /* XXX UNREF/NEWREF interface should be more symmetrical */ _Py_DEC_REFTOTAL; - _PyObject_GC_UNTRACK(v); + if (_PyObject_GC_IS_TRACKED(v)) + _PyObject_GC_UNTRACK(v); _Py_ForgetReference((PyObject *) v); /* DECREF items deleted by shrinkage */ for (i = newsize; i < oldsize; i++) { From python-checkins at python.org Sat Dec 12 20:27:08 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 12 Dec 2009 19:27:08 -0000 Subject: [Python-checkins] r76766 - python/branches/release26-maint Message-ID: Author: antoine.pitrou Date: Sat Dec 12 20:27:08 2009 New Revision: 76766 Log: Blocked revisions 76763 via svnmerge ........ r76763 | antoine.pitrou | 2009-12-12 20:13:08 +0100 (sam., 12 d?c. 2009) | 7 lines Issue #7466: segmentation fault when the garbage collector is called in the middle of populating a tuple. Patch by Florent Xicluna. (note: no NEWS entry for trunk since the bug was introduced in 2.7/3.1) ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Dec 12 21:01:38 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 12 Dec 2009 20:01:38 -0000 Subject: [Python-checkins] r76767 - sandbox/trunk/dbm_sqlite-3783 Message-ID: Author: antoine.pitrou Date: Sat Dec 12 21:01:37 2009 New Revision: 76767 Log: Create a proper branch for dbm.sqlite Added: sandbox/trunk/dbm_sqlite-3783/ - copied from r76766, /python/branches/py3k/ From python-checkins at python.org Sat Dec 12 21:09:08 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 12 Dec 2009 20:09:08 -0000 Subject: [Python-checkins] r76768 - sandbox/trunk/dbm_sqlite-3783 Message-ID: Author: antoine.pitrou Date: Sat Dec 12 21:09:08 2009 New Revision: 76768 Log: Initialized merge tracking via "svnmerge" with revisions "1-76766" from svn+ssh://pythondev at svn.python.org/python/branches/py3k Modified: sandbox/trunk/dbm_sqlite-3783/ (props changed) From python-checkins at python.org Sat Dec 12 22:08:11 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 12 Dec 2009 21:08:11 -0000 Subject: [Python-checkins] r76769 - in sandbox/trunk/dbm_sqlite-3783/Lib: dbm/sqlite.py test/test_dbm_sqlite.py Message-ID: Author: antoine.pitrou Date: Sat Dec 12 22:08:11 2009 New Revision: 76769 Log: Commit a modified version of Raymond's implementation + Skip's test Added: sandbox/trunk/dbm_sqlite-3783/Lib/dbm/sqlite.py (contents, props changed) sandbox/trunk/dbm_sqlite-3783/Lib/test/test_dbm_sqlite.py (contents, props changed) Added: sandbox/trunk/dbm_sqlite-3783/Lib/dbm/sqlite.py ============================================================================== --- (empty file) +++ sandbox/trunk/dbm_sqlite-3783/Lib/dbm/sqlite.py Sat Dec 12 22:08:11 2009 @@ -0,0 +1,146 @@ +''' Dbm based on sqlite -- Needed to support shelves + +Key and values are always stored as bytes. This means that when strings are +used they are implicitly converted to the default encoding before being +stored. + +Issues: + + # ??? how to coordinate with whichdb + # ??? Any difference between blobs and text + # ??? does default encoding affect str-->bytes or PySqlite3 always use UTF-8 + # ??? what is the correct isolation mode + +''' + +__all__ = ['error', 'open'] + +import sqlite3 +import collections +from operator import itemgetter + +error = sqlite3.DatabaseError + +# Disabled: the INSERT trigger gives erroneours results when REPLACE +# is used for __setitem__. + +#MAKE_SHELF = ''' +#CREATE TABLE IF NOT EXISTS info + #(key TEXT PRIMARY KEY, + #value INFO NOT NULL); + +#INSERT OR IGNORE INTO info (key, value) VALUES ('size', 0); + +#CREATE TABLE IF NOT EXISTS shelf + #(key TEXT PRIMARY KEY, + #value TEXT NOT NULL); + +#CREATE TRIGGER IF NOT EXISTS insert_shelf + #AFTER INSERT ON shelf + #BEGIN + #UPDATE info SET value = value + 1 WHERE key = 'size'; + #END; + +#CREATE TRIGGER IF NOT EXISTS delete_shelf + #AFTER DELETE ON shelf + #BEGIN + #UPDATE info SET value = value - 1 WHERE key = 'size'; + #END;''' + +MAKE_SHELF = '''CREATE TABLE IF NOT EXISTS shelf + (key TEXT PRIMARY KEY, + value TEXT NOT NULL);''' + +GET_LEN = 'SELECT COUNT(*) FROM shelf' +#GET_LEN = "SELECT value FROM info WHERE key = 'size'" +GET_BOOL = 'SELECT 1 FROM shelf LIMIT 1' + +HAS_ITEM = 'SELECT 1 FROM shelf WHERE key = ?' +GET_ITEM = 'SELECT value FROM shelf WHERE key = ?' +SET_ITEM = 'REPLACE INTO shelf (key, value) VALUES (?,?)' +DEL_ITEM = 'DELETE FROM shelf WHERE key = ?' + +ITER_KEYS = 'SELECT key from shelf' +ITER_VALUES = 'SELECT value from shelf' +ITER_ITEMS = 'SELECT key, value from shelf' + +UPDATE_ITEMS = 'REPLACE INTO shelf (key, value) VALUES (?, ?)' + +CLEAR_ALL = 'DELETE FROM shelf; VACUUM;' + + +class SQLHash(collections.MutableMapping): + + def __init__(self, filename=':memory:', flags='r', mode=None): + # XXX add flag/mode handling + # c -- create if it doesn't exist + # n -- new empty + # w -- open existing + # r -- readonly + self.conn = sqlite3.connect(filename) + self.conn.text_factory = bytes + self.conn.executescript(MAKE_SHELF) + self.conn.commit() + + def __len__(self): + return self.conn.execute(GET_LEN).fetchone()[0] + + def __bool__(self): + return self.conn.execute(GET_BOOL).fetchone() is not None + + def keys(self): + return map(itemgetter(0), self.conn.execute(ITER_KEYS)) + + __iter__ = keys + + def values(self): + return map(itemgetter(0), self.conn.execute(ITER_VALUES)) + + def items(self): + return iter(self.conn.execute(ITER_ITEMS)) + + def __contains__(self, key): + return self.conn.execute(HAS_ITEM, (key,)).fetchone() is not None + + def __getitem__(self, key): + item = self.conn.execute(GET_ITEM, (key,)).fetchone() + if item is None: + raise KeyError(key) + return item[0] + + def __setitem__(self, key, value): + self.conn.execute(SET_ITEM, (key, value)) + + def __delitem__(self, key): + if key not in self: + raise KeyError(key) + self.conn.execute(DEL_ITEM, (key,)) + + def update(self, items=(), **kwds): + if isinstance(items, collections.Mapping): + items = items.items() + self.conn.executemany(UPDATE_ITEMS, items) + self.conn.commit() + if kwds: + self.update(kwds) + + def clear(self): + self.conn.executescript(CLEAR_ALL) + self.conn.commit() + + def sync(self): + if self.conn is not None: + self.conn.commit() + + def close(self): + if self.conn is not None: + self.conn.commit() + self.conn.close() + self.conn = None + + def __del__(self): + self.close() + + +def open(filename, _flag=None, mode=0o666): + return SQLHash(filename, mode) Added: sandbox/trunk/dbm_sqlite-3783/Lib/test/test_dbm_sqlite.py ============================================================================== --- (empty file) +++ sandbox/trunk/dbm_sqlite-3783/Lib/test/test_dbm_sqlite.py Sat Dec 12 22:08:11 2009 @@ -0,0 +1,177 @@ +#! /usr/bin/env python +"""Test script for the dbm.sqlite module + by Skip Montanaro, based on the 3.0 dumbdbm test module. +""" + +import io +import os +import unittest +import dbm.sqlite +from test import support + +_fname = support.TESTFN + +def _delete_files(): + try: + support.unlink(_fname) + except OSError: + pass + +class DbmSQLiteTestCase(unittest.TestCase): + _dict = {b'0': b'', + b'a': b'Python:', + b'b': b'Programming', + b'c': b'the', + b'd': b'way', + b'f': b'Guido', + b'g': b'intended', + } + + def init_db(self): + f = dbm.sqlite.open(_fname, 'w') + for k in self._dict: + f[k] = self._dict[k] + f.close() + + def keys_helper(self, f): + keys = sorted(f.keys()) + dkeys = sorted(self._dict.keys()) + self.assertEqual(keys, dkeys) + return keys + + def read_helper(self, f): + keys = self.keys_helper(f) + for key in self._dict: + self.assertEqual(self._dict[key], f[key]) + + def test_creation(self): + f = dbm.sqlite.open(_fname, 'c') + self.assertEqual(list(f.keys()), []) + for key in self._dict: + f[key] = self._dict[key] + self.read_helper(f) + f.close() + + def test_close_twice(self): + f = dbm.sqlite.open(_fname) + f[b'a'] = b'b' + f.close() + f.close() + + def test_modification(self): + self.init_db() + f = dbm.sqlite.open(_fname, 'w') + self._dict[b'g'] = f[b'g'] = b"indented" + self.read_helper(f) + f.close() + + def test_read(self): + self.init_db() + f = dbm.sqlite.open(_fname, 'r') + self.read_helper(f) + f.close() + + def test_keys(self): + self.init_db() + f = dbm.sqlite.open(_fname) + keys = self.keys_helper(f) + f.close() + + def test_len_bool(self): + f = dbm.sqlite.open(_fname) + self.assertEqual(len(f), 0) + self.assertFalse(f) + f[b'1'] = b'hello' + self.assertEqual(len(f), 1) + self.assertTrue(f) + f[b'1'] = b'goodbye' + self.assertEqual(len(f), 1) + self.assertTrue(f) + f[b'a'] = b'goodbye' + self.assertEqual(len(f), 2) + self.assertTrue(f) + del f[b'1'] + self.assertEqual(len(f), 1) + self.assertTrue(f) + f.clear() + self.assertEqual(len(f), 0) + self.assertFalse(f) + f.close() + + def test_write_contains(self): + f = dbm.sqlite.open(_fname) + f[b'1'] = b'hello' + self.assertTrue(b'1' in f) + f.close() + + def test_write_write_read(self): + # test for bug #482460 + f = dbm.sqlite.open(_fname) + f[b'1'] = b'hello' + f[b'1'] = b'hello2' + f.close() + f = dbm.sqlite.open(_fname) + self.assertEqual(f[b'1'], b'hello2') + f.close() + + def test_write_then_read(self): + # test for bug #482460 + f = dbm.sqlite.open(_fname) + f[b'1'] = b'hello' + self.assertEqual(f[b'1'], b'hello') + f.close() + + # Perform randomized operations. This doesn't make assumptions about + # what *might* fail. + def test_random(self): + import random + d = {} # mirror the database + for dummy in range(5): + f = dbm.sqlite.open(_fname) + for dummy in range(100): + k = random.choice('abcdefghijklm').encode('ascii') + if random.random() < 0.2: + if k in d: + del d[k] + del f[k] + else: + v = (random.choice((b'a', b'b', b'c')) * + random.randrange(100)) + d[k] = v + f[k] = v + if not (d[k], v == f[k] == d[k]): + print("v:", v, "f[k]:", f[k], + "d[k]:") + self.assertEqual(f[k], v) + f.close() + + f = dbm.sqlite.open(_fname) + expected = sorted(d.items()) + got = sorted(f.items()) + self.assertEqual(expected, got) + f.close() + + # XXX: not an useful invariant, and enforcing it might slow things down + #def test_keys_values_items(self): + #f = dbm.sqlite.open(_fname, 'c') + #self.assertEqual(list(f.keys()), []) + #for key in self._dict: + #f[key.encode("ascii")] = self._dict[key] + #self.assertEqual(list(zip(f.keys(), f.values())), + #list(f.items())) + #f.close() + + def tearDown(self): + _delete_files() + + def setUp(self): + _delete_files() + +def test_main(): + try: + support.run_unittest(DbmSQLiteTestCase) + finally: + _delete_files() + +if __name__ == "__main__": + test_main() From python-checkins at python.org Sat Dec 12 23:35:59 2009 From: python-checkins at python.org (brett.cannon) Date: Sat, 12 Dec 2009 22:35:59 -0000 Subject: [Python-checkins] r76770 - python/branches/py3k/Lib/importlib/abc.py Message-ID: Author: brett.cannon Date: Sat Dec 12 23:35:59 2009 New Revision: 76770 Log: Clarify importlib.abc.PyPycLoader.write_bytecode(). Modified: python/branches/py3k/Lib/importlib/abc.py Modified: python/branches/py3k/Lib/importlib/abc.py ============================================================================== --- python/branches/py3k/Lib/importlib/abc.py (original) +++ python/branches/py3k/Lib/importlib/abc.py Sat Dec 12 23:35:59 2009 @@ -132,7 +132,8 @@ raise NotImplementedError @abc.abstractmethod - def write_bytecode(self, fullname:str, bytecode:bytes): + def write_bytecode(self, fullname:str, bytecode:bytes) -> bool: """Abstract method which when implemented should attempt to write the - bytecode for the module.""" + bytecode for the module, returning a boolean representing whether the + bytecode was written or not.""" raise NotImplementedError From solipsis at pitrou.net Sun Dec 13 00:49:28 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 13 Dec 2009 00:49:28 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76764): sum=0 Message-ID: <20091212234928.86DEB17759@ns6635.ovh.net> py3k results for svn r76764 (hg cset e63300cc78ad) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogezqfaN', '-x', 'test_httpservers'] From python-checkins at python.org Sun Dec 13 01:32:16 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 00:32:16 -0000 Subject: [Python-checkins] r76771 - python/branches/py3k/Doc/library/functions.rst Message-ID: Author: benjamin.peterson Date: Sun Dec 13 01:32:14 2009 New Revision: 76771 Log: death to exec statement 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 Sun Dec 13 01:32:14 2009 @@ -142,9 +142,9 @@ .. function:: compile(source, filename, mode, flags=0, dont_inherit=False) Compile the *source* into a code or AST object. Code objects can be executed - by an :keyword:`exec` statement or evaluated by a call to :func:`eval`. - *source* can either be a string or an AST object. Refer to the :mod:`ast` - module documentation for information on how to work with AST objects. + by:func:`exec` or :func:`eval`. *source* can either be a string or an AST + object. Refer to the :mod:`ast` module documentation for information on how + to work with AST objects. The *filename* argument should give the file from which the code was read; pass some recognizable value if it wasn't read from a file (``''`` is From python-checkins at python.org Sun Dec 13 01:36:41 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 00:36:41 -0000 Subject: [Python-checkins] r76772 - in python/branches/release31-maint: Doc/library/functions.rst Message-ID: Author: benjamin.peterson Date: Sun Dec 13 01:36:41 2009 New Revision: 76772 Log: Merged revisions 76771 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76771 | benjamin.peterson | 2009-12-12 18:32:14 -0600 (Sat, 12 Dec 2009) | 1 line death to exec statement ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/functions.rst Modified: python/branches/release31-maint/Doc/library/functions.rst ============================================================================== --- python/branches/release31-maint/Doc/library/functions.rst (original) +++ python/branches/release31-maint/Doc/library/functions.rst Sun Dec 13 01:36:41 2009 @@ -142,9 +142,9 @@ .. function:: compile(source, filename, mode, flags=0, dont_inherit=False) Compile the *source* into a code or AST object. Code objects can be executed - by an :keyword:`exec` statement or evaluated by a call to :func:`eval`. - *source* can either be a string or an AST object. Refer to the :mod:`ast` - module documentation for information on how to work with AST objects. + by:func:`exec` or :func:`eval`. *source* can either be a string or an AST + object. Refer to the :mod:`ast` module documentation for information on how + to work with AST objects. The *filename* argument should give the file from which the code was read; pass some recognizable value if it wasn't read from a file (``''`` is From python-checkins at python.org Sun Dec 13 01:38:59 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 00:38:59 -0000 Subject: [Python-checkins] r76773 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Sun Dec 13 01:38:59 2009 New Revision: 76773 Log: Blocked revisions 76602,76690-76691,76736-76737,76754 via svnmerge ........ r76602 | raymond.hettinger | 2009-11-30 15:13:52 -0600 (Mon, 30 Nov 2009) | 1 line Handle step values other than one. ........ r76690 | vinay.sajip | 2009-12-06 11:57:11 -0600 (Sun, 06 Dec 2009) | 1 line logging: Added optional 'secure' parameter to SMTPHandler. ........ r76691 | vinay.sajip | 2009-12-06 12:05:04 -0600 (Sun, 06 Dec 2009) | 1 line logging: Improved support for SMTP over TLS. ........ r76736 | raymond.hettinger | 2009-12-10 00:00:33 -0600 (Thu, 10 Dec 2009) | 1 line Fix variants of deque.extend: d.extend(d) d+=d d.extendleft(d) ........ r76737 | raymond.hettinger | 2009-12-10 00:42:54 -0600 (Thu, 10 Dec 2009) | 1 line Add a reverse() method to collections.deque(). ........ r76754 | vinay.sajip | 2009-12-11 03:16:01 -0600 (Fri, 11 Dec 2009) | 1 line Issue #7470: logging: fix bug in Unicode encoding fallback. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Dec 13 01:54:16 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 00:54:16 -0000 Subject: [Python-checkins] r76774 - in python/trunk: Parser/asdl_c.py Python/Python-ast.c Python/bltinmodule.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 01:54:15 2009 New Revision: 76774 Log: account for PyObject_IsInstance's new ability to fail Modified: python/trunk/Parser/asdl_c.py python/trunk/Python/Python-ast.c python/trunk/Python/bltinmodule.c Modified: python/trunk/Parser/asdl_c.py ============================================================================== --- python/trunk/Parser/asdl_c.py (original) +++ python/trunk/Parser/asdl_c.py Sun Dec 13 01:54:15 2009 @@ -367,6 +367,7 @@ self.emit("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name, ctype), 0) self.emit("{", 0) self.emit("PyObject* tmp = NULL;", 1) + self.emit("int isinstance;", 1) self.emit("", 0) def sumTrailer(self, name): @@ -386,7 +387,13 @@ def simpleSum(self, sum, name): self.funcHeader(name) for t in sum.types: - self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + line = ("isinstance = PyObject_IsInstance(obj, " + "(PyObject *)%s_type);") + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) self.emit("*out = %s;" % t.name, 2) self.emit("return 0;", 2) self.emit("}", 1) @@ -408,7 +415,12 @@ for a in sum.attributes: self.visitField(a, name, sum=sum, depth=1) for t in sum.types: - self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + line = "isinstance = PyObject_IsInstance(obj, (PyObject*)%s_type);" + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) for f in t.fields: self.visitFieldDeclaration(f, t.name, sum=sum, depth=2) self.emit("", 0) @@ -1093,11 +1105,15 @@ PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, (PyObject*)Interactive_type}; char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; assert(0 <= mode && mode <= 2); init_types(); - if (!PyObject_IsInstance(ast, req_type[mode])) { + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", req_name[mode], Py_TYPE(ast)->tp_name); return NULL; Modified: python/trunk/Python/Python-ast.c ============================================================================== --- python/trunk/Python/Python-ast.c (original) +++ python/trunk/Python/Python-ast.c Sun Dec 13 01:54:15 2009 @@ -3175,13 +3175,18 @@ obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; if (obj == Py_None) { *out = NULL; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Module_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Module_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3213,7 +3218,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Interactive_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Interactive_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3245,7 +3254,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Expression_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Expression_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty body; if (PyObject_HasAttrString(obj, "body")) { @@ -3264,7 +3277,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Suite_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Suite_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3309,6 +3326,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -3341,7 +3359,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)FunctionDef_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)FunctionDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier name; arguments_ty args; asdl_seq* body; @@ -3426,7 +3448,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ClassDef_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ClassDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier name; asdl_seq* bases; asdl_seq* body; @@ -3524,7 +3550,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Return_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Return_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -3542,7 +3572,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Delete_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Delete_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* targets; if (PyObject_HasAttrString(obj, "targets")) { @@ -3574,7 +3608,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Assign_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Assign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* targets; expr_ty value; @@ -3619,7 +3657,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugAssign_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)AugAssign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty target; operator_ty op; expr_ty value; @@ -3664,7 +3706,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Print_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Print_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty dest; asdl_seq* values; bool nl; @@ -3721,7 +3767,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)For_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)For_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty target; expr_ty iter; asdl_seq* body; @@ -3806,7 +3856,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)While_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)While_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; asdl_seq* body; asdl_seq* orelse; @@ -3877,7 +3931,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)If_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)If_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; asdl_seq* body; asdl_seq* orelse; @@ -3948,7 +4006,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)With_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)With_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty context_expr; expr_ty optional_vars; asdl_seq* body; @@ -4006,7 +4068,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Raise_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Raise_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty type; expr_ty inst; expr_ty tback; @@ -4048,7 +4114,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)TryExcept_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)TryExcept_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; asdl_seq* handlers; asdl_seq* orelse; @@ -4133,7 +4203,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)TryFinally_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)TryFinally_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; asdl_seq* finalbody; @@ -4191,7 +4265,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Assert_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Assert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; expr_ty msg; @@ -4222,7 +4300,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Import_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Import_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4254,7 +4336,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ImportFrom_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ImportFrom_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier module; asdl_seq* names; int level; @@ -4311,7 +4397,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Exec_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Exec_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty body; expr_ty globals; expr_ty locals; @@ -4354,7 +4444,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Global_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Global_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4386,7 +4480,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Expr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Expr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -4405,19 +4503,31 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Pass_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Pass_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Pass(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Break_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Break_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Break(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Continue_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Continue_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Continue(lineno, col_offset, arena); if (*out == NULL) goto failed; @@ -4436,6 +4546,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -4468,7 +4579,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)BoolOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)BoolOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { boolop_ty op; asdl_seq* values; @@ -4513,7 +4628,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BinOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)BinOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty left; operator_ty op; expr_ty right; @@ -4558,7 +4677,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)UnaryOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)UnaryOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { unaryop_ty op; expr_ty operand; @@ -4590,7 +4713,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Lambda_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Lambda_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { arguments_ty args; expr_ty body; @@ -4622,7 +4749,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)IfExp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)IfExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; expr_ty body; expr_ty orelse; @@ -4667,7 +4798,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Dict_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Dict_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* keys; asdl_seq* values; @@ -4725,7 +4860,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ListComp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ListComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -4770,7 +4909,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -4815,7 +4958,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Yield_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Yield_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -4833,7 +4980,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Compare_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Compare_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty left; asdl_int_seq* ops; asdl_seq* comparators; @@ -4905,7 +5056,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Call_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Call_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty func; asdl_seq* args; asdl_seq* keywords; @@ -5001,7 +5156,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Repr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Repr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -5020,7 +5179,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Num_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Num_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { object n; if (PyObject_HasAttrString(obj, "n")) { @@ -5039,7 +5202,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Str_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Str_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { string s; if (PyObject_HasAttrString(obj, "s")) { @@ -5058,7 +5225,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Attribute_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Attribute_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; identifier attr; expr_context_ty ctx; @@ -5103,7 +5274,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Subscript_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Subscript_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; slice_ty slice; expr_context_ty ctx; @@ -5148,7 +5323,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Name_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Name_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier id; expr_context_ty ctx; @@ -5180,7 +5359,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)List_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)List_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; expr_context_ty ctx; @@ -5225,7 +5408,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Tuple_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Tuple_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; expr_context_ty ctx; @@ -5283,28 +5470,53 @@ obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Load_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Load_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Load; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Store_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Store_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Store; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Del_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Del_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Del; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugLoad_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)AugLoad_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = AugLoad; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugStore_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)AugStore_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = AugStore; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Param_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Param_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Param; return 0; } @@ -5321,19 +5533,28 @@ obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; if (obj == Py_None) { *out = NULL; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Ellipsis_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Ellipsis_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Ellipsis(arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Slice_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Slice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty lower; expr_ty upper; expr_ty step; @@ -5375,7 +5596,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ExtSlice_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ExtSlice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* dims; if (PyObject_HasAttrString(obj, "dims")) { @@ -5407,7 +5632,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Index_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Index_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -5439,12 +5668,21 @@ obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)And_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)And_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = And; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Or_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Or_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Or; return 0; } @@ -5461,52 +5699,101 @@ obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Add_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Add_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Add; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Sub_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Sub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Sub; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Mult_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Mult_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Mult; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Div_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Div_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Div; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Mod_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Mod_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Mod; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Pow_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Pow_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Pow; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)LShift_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)LShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = LShift; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)RShift_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)RShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = RShift; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitOr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitOr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitOr; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitXor_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitXor_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitXor; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitAnd_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitAnd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitAnd; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)FloorDiv_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)FloorDiv_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = FloorDiv; return 0; } @@ -5523,20 +5810,37 @@ obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Invert_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Invert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Invert; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Not_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Not_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Not; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)UAdd_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)UAdd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = UAdd; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)USub_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)USub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = USub; return 0; } @@ -5553,44 +5857,85 @@ obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Eq_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Eq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Eq; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)NotEq_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)NotEq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = NotEq; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Lt_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Lt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Lt; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)LtE_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)LtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = LtE; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Gt_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Gt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Gt; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)GtE_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)GtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = GtE; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Is_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Is_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Is; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)IsNot_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)IsNot_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = IsNot; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)In_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)In_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = In; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)NotIn_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)NotIn_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = NotIn; return 0; } @@ -5671,6 +6016,7 @@ obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -5703,7 +6049,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty type; expr_ty name; asdl_seq* body; @@ -6104,11 +6454,15 @@ PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, (PyObject*)Interactive_type}; char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; assert(0 <= mode && mode <= 2); init_types(); - if (!PyObject_IsInstance(ast, req_type[mode])) { + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", req_name[mode], Py_TYPE(ast)->tp_name); return NULL; Modified: python/trunk/Python/bltinmodule.c ============================================================================== --- python/trunk/Python/bltinmodule.c (original) +++ python/trunk/Python/bltinmodule.c Sun Dec 13 01:54:15 2009 @@ -466,6 +466,7 @@ int mode = -1; int dont_inherit = 0; int supplied_flags = 0; + int is_ast; PyCompilerFlags cf; PyObject *result = NULL, *cmd, *tmp = NULL; Py_ssize_t length; @@ -505,7 +506,10 @@ return NULL; } - if (PyAST_Check(cmd)) { + is_ast = PyAST_Check(cmd); + if (is_ast == -1) + return NULL; + if (is_ast) { if (supplied_flags & PyCF_ONLY_AST) { Py_INCREF(cmd); result = cmd; From python-checkins at python.org Sun Dec 13 01:59:02 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 00:59:02 -0000 Subject: [Python-checkins] r76775 - in python/branches/release26-maint: Parser/asdl_c.py Python/Python-ast.c Python/bltinmodule.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 01:59:01 2009 New Revision: 76775 Log: Merged revisions 76774 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76774 | benjamin.peterson | 2009-12-12 18:54:15 -0600 (Sat, 12 Dec 2009) | 1 line account for PyObject_IsInstance's new ability to fail ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Parser/asdl_c.py python/branches/release26-maint/Python/Python-ast.c python/branches/release26-maint/Python/bltinmodule.c Modified: python/branches/release26-maint/Parser/asdl_c.py ============================================================================== --- python/branches/release26-maint/Parser/asdl_c.py (original) +++ python/branches/release26-maint/Parser/asdl_c.py Sun Dec 13 01:59:01 2009 @@ -367,6 +367,7 @@ self.emit("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name, ctype), 0) self.emit("{", 0) self.emit("PyObject* tmp = NULL;", 1) + self.emit("int isinstance;", 1) self.emit("", 0) def sumTrailer(self, name): @@ -386,7 +387,13 @@ def simpleSum(self, sum, name): self.funcHeader(name) for t in sum.types: - self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + line = ("isinstance = PyObject_IsInstance(obj, " + "(PyObject *)%s_type);") + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) self.emit("*out = %s;" % t.name, 2) self.emit("return 0;", 2) self.emit("}", 1) @@ -408,7 +415,12 @@ for a in sum.attributes: self.visitField(a, name, sum=sum, depth=1) for t in sum.types: - self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + line = "isinstance = PyObject_IsInstance(obj, (PyObject*)%s_type);" + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) for f in t.fields: self.visitFieldDeclaration(f, t.name, sum=sum, depth=2) self.emit("", 0) @@ -1093,11 +1105,15 @@ PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, (PyObject*)Interactive_type}; char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; assert(0 <= mode && mode <= 2); init_types(); - if (!PyObject_IsInstance(ast, req_type[mode])) { + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", req_name[mode], Py_TYPE(ast)->tp_name); return NULL; Modified: python/branches/release26-maint/Python/Python-ast.c ============================================================================== --- python/branches/release26-maint/Python/Python-ast.c (original) +++ python/branches/release26-maint/Python/Python-ast.c Sun Dec 13 01:59:01 2009 @@ -3180,13 +3180,18 @@ obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; if (obj == Py_None) { *out = NULL; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Module_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Module_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3218,7 +3223,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Interactive_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Interactive_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3250,7 +3259,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Expression_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Expression_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty body; if (PyObject_HasAttrString(obj, "body")) { @@ -3269,7 +3282,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Suite_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Suite_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3314,6 +3331,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -3346,7 +3364,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)FunctionDef_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)FunctionDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier name; arguments_ty args; asdl_seq* body; @@ -3431,7 +3453,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ClassDef_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ClassDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier name; asdl_seq* bases; asdl_seq* body; @@ -3529,7 +3555,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Return_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Return_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -3547,7 +3577,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Delete_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Delete_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* targets; if (PyObject_HasAttrString(obj, "targets")) { @@ -3579,7 +3613,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Assign_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Assign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* targets; expr_ty value; @@ -3624,7 +3662,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugAssign_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)AugAssign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty target; operator_ty op; expr_ty value; @@ -3669,7 +3711,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Print_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Print_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty dest; asdl_seq* values; bool nl; @@ -3726,7 +3772,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)For_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)For_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty target; expr_ty iter; asdl_seq* body; @@ -3811,7 +3861,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)While_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)While_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; asdl_seq* body; asdl_seq* orelse; @@ -3882,7 +3936,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)If_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)If_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; asdl_seq* body; asdl_seq* orelse; @@ -3953,7 +4011,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)With_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)With_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty context_expr; expr_ty optional_vars; asdl_seq* body; @@ -4011,7 +4073,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Raise_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Raise_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty type; expr_ty inst; expr_ty tback; @@ -4053,7 +4119,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)TryExcept_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)TryExcept_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; asdl_seq* handlers; asdl_seq* orelse; @@ -4138,7 +4208,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)TryFinally_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)TryFinally_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; asdl_seq* finalbody; @@ -4196,7 +4270,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Assert_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Assert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; expr_ty msg; @@ -4227,7 +4305,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Import_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Import_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4259,7 +4341,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ImportFrom_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ImportFrom_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier module; asdl_seq* names; int level; @@ -4317,7 +4403,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Exec_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Exec_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty body; expr_ty globals; expr_ty locals; @@ -4360,7 +4450,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Global_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Global_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4392,7 +4486,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Expr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Expr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -4411,19 +4509,31 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Pass_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Pass_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Pass(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Break_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Break_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Break(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Continue_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Continue_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Continue(lineno, col_offset, arena); if (*out == NULL) goto failed; @@ -4442,6 +4552,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -4474,7 +4585,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)BoolOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)BoolOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { boolop_ty op; asdl_seq* values; @@ -4519,7 +4634,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BinOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)BinOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty left; operator_ty op; expr_ty right; @@ -4564,7 +4683,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)UnaryOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)UnaryOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { unaryop_ty op; expr_ty operand; @@ -4596,7 +4719,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Lambda_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Lambda_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { arguments_ty args; expr_ty body; @@ -4628,7 +4755,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)IfExp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)IfExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; expr_ty body; expr_ty orelse; @@ -4673,7 +4804,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Dict_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Dict_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* keys; asdl_seq* values; @@ -4731,7 +4866,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ListComp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ListComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -4776,7 +4915,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -4821,7 +4964,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Yield_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Yield_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -4839,7 +4986,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Compare_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Compare_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty left; asdl_int_seq* ops; asdl_seq* comparators; @@ -4911,7 +5062,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Call_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Call_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty func; asdl_seq* args; asdl_seq* keywords; @@ -5007,7 +5162,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Repr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Repr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -5026,7 +5185,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Num_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Num_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { object n; if (PyObject_HasAttrString(obj, "n")) { @@ -5045,7 +5208,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Str_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Str_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { string s; if (PyObject_HasAttrString(obj, "s")) { @@ -5064,7 +5231,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Attribute_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Attribute_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; identifier attr; expr_context_ty ctx; @@ -5109,7 +5280,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Subscript_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Subscript_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; slice_ty slice; expr_context_ty ctx; @@ -5154,7 +5329,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Name_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Name_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier id; expr_context_ty ctx; @@ -5186,7 +5365,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)List_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)List_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; expr_context_ty ctx; @@ -5231,7 +5414,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Tuple_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Tuple_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; expr_context_ty ctx; @@ -5289,28 +5476,53 @@ obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Load_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Load_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Load; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Store_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Store_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Store; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Del_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Del_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Del; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugLoad_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)AugLoad_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = AugLoad; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugStore_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)AugStore_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = AugStore; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Param_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Param_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Param; return 0; } @@ -5327,19 +5539,28 @@ obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; if (obj == Py_None) { *out = NULL; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Ellipsis_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Ellipsis_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Ellipsis(arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Slice_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Slice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty lower; expr_ty upper; expr_ty step; @@ -5381,7 +5602,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ExtSlice_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ExtSlice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* dims; if (PyObject_HasAttrString(obj, "dims")) { @@ -5413,7 +5638,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Index_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Index_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -5445,12 +5674,21 @@ obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)And_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)And_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = And; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Or_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Or_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Or; return 0; } @@ -5467,52 +5705,101 @@ obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Add_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Add_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Add; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Sub_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Sub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Sub; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Mult_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Mult_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Mult; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Div_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Div_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Div; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Mod_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Mod_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Mod; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Pow_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Pow_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Pow; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)LShift_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)LShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = LShift; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)RShift_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)RShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = RShift; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitOr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitOr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitOr; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitXor_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitXor_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitXor; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitAnd_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitAnd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitAnd; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)FloorDiv_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)FloorDiv_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = FloorDiv; return 0; } @@ -5529,20 +5816,37 @@ obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Invert_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Invert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Invert; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Not_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Not_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Not; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)UAdd_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)UAdd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = UAdd; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)USub_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)USub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = USub; return 0; } @@ -5559,44 +5863,85 @@ obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Eq_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Eq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Eq; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)NotEq_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)NotEq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = NotEq; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Lt_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Lt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Lt; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)LtE_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)LtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = LtE; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Gt_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Gt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Gt; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)GtE_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)GtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = GtE; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Is_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Is_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Is; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)IsNot_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)IsNot_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = IsNot; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)In_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)In_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = In; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)NotIn_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)NotIn_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = NotIn; return 0; } @@ -5677,6 +6022,7 @@ obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -5709,7 +6055,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty type; expr_ty name; asdl_seq* body; @@ -6110,11 +6460,15 @@ PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, (PyObject*)Interactive_type}; char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; assert(0 <= mode && mode <= 2); init_types(); - if (!PyObject_IsInstance(ast, req_type[mode])) { + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", req_name[mode], Py_TYPE(ast)->tp_name); return NULL; Modified: python/branches/release26-maint/Python/bltinmodule.c ============================================================================== --- python/branches/release26-maint/Python/bltinmodule.c (original) +++ python/branches/release26-maint/Python/bltinmodule.c Sun Dec 13 01:59:01 2009 @@ -465,6 +465,7 @@ int mode = -1; int dont_inherit = 0; int supplied_flags = 0; + int is_ast; PyCompilerFlags cf; PyObject *result = NULL, *cmd, *tmp = NULL; Py_ssize_t length; @@ -504,7 +505,10 @@ return NULL; } - if (PyAST_Check(cmd)) { + is_ast = PyAST_Check(cmd); + if (is_ast == -1) + return NULL; + if (is_ast) { if (supplied_flags & PyCF_ONLY_AST) { Py_INCREF(cmd); result = cmd; From python-checkins at python.org Sun Dec 13 02:23:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 01:23:40 -0000 Subject: [Python-checkins] r76776 - in python/branches/py3k: Doc/library/functions.rst Doc/whatsnew/2.7.rst Parser/asdl_c.py Python/bltinmodule.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 02:23:39 2009 New Revision: 76776 Log: Merged revisions 76534,76538,76628,76701,76774 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76534 | martin.v.loewis | 2009-11-26 02:42:05 -0600 (Thu, 26 Nov 2009) | 2 lines Fix typo. ........ r76538 | georg.brandl | 2009-11-26 14:48:25 -0600 (Thu, 26 Nov 2009) | 1 line #7400: typo. ........ r76628 | andrew.kuchling | 2009-12-02 08:27:11 -0600 (Wed, 02 Dec 2009) | 1 line Markup fixes ........ r76701 | andrew.kuchling | 2009-12-07 20:37:05 -0600 (Mon, 07 Dec 2009) | 1 line Typo fix; grammar fix ........ r76774 | benjamin.peterson | 2009-12-12 18:54:15 -0600 (Sat, 12 Dec 2009) | 1 line account for PyObject_IsInstance's new ability to fail ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/whatsnew/2.7.rst python/branches/py3k/Parser/asdl_c.py python/branches/py3k/Python/bltinmodule.c Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Sun Dec 13 02:23:39 2009 @@ -973,7 +973,7 @@ .. function:: set([iterable]) :noindex: - Return a new set, optionally with elements are taken from *iterable*. + Return a new set, optionally with elements taken from *iterable*. The set type is described in :ref:`types-set`. 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 Dec 13 02:23:39 2009 @@ -70,7 +70,7 @@ * A version of the :mod:`io` library, rewritten in C for performance. * The ordered-dictionary type described in :ref:`pep-0372`. -* The new format specified described in :ref:`pep-0378`. +* The new format specifier described in :ref:`pep-0378`. * The :class:`memoryview` object. * A small subset of the :mod:`importlib` module `described below <#importlib-section>`__. @@ -515,7 +515,7 @@ more sensible for numeric types. (Changed by Mark Dickinson; :issue:`6857`.) * Distutils is being more actively developed, thanks to Tarek Ziade - has taken over maintenance of the package. A new + who has taken over maintenance of the package. A new :file:`setup.py` subcommand, ``check``, will check that the arguments being passed to the :func:`setup` function are complete and correct (:issue:`5732`). @@ -587,14 +587,14 @@ an invalid file descriptor. (Implemented by Benjamin Peterson; :issue:`4991`.) -* New function: ``itertools.compress(*data*, *selectors*)`` takes two +* 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*)`` + 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:: @@ -1080,5 +1080,5 @@ The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this -article: no one yet. +article: Ryan Lovett, Hugh Secker-Walker. Modified: python/branches/py3k/Parser/asdl_c.py ============================================================================== --- python/branches/py3k/Parser/asdl_c.py (original) +++ python/branches/py3k/Parser/asdl_c.py Sun Dec 13 02:23:39 2009 @@ -366,6 +366,7 @@ self.emit("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name, ctype), 0) self.emit("{", 0) self.emit("PyObject* tmp = NULL;", 1) + self.emit("int isinstance;", 1) self.emit("", 0) def sumTrailer(self, name): @@ -385,7 +386,13 @@ def simpleSum(self, sum, name): self.funcHeader(name) for t in sum.types: - self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + line = ("isinstance = PyObject_IsInstance(obj, " + "(PyObject *)%s_type);") + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) self.emit("*out = %s;" % t.name, 2) self.emit("return 0;", 2) self.emit("}", 1) @@ -407,7 +414,12 @@ for a in sum.attributes: self.visitField(a, name, sum=sum, depth=1) for t in sum.types: - self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + line = "isinstance = PyObject_IsInstance(obj, (PyObject*)%s_type);" + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) for f in t.fields: self.visitFieldDeclaration(f, t.name, sum=sum, depth=2) self.emit("", 0) @@ -1077,11 +1089,15 @@ PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, (PyObject*)Interactive_type}; char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; assert(0 <= mode && mode <= 2); init_types(); - if (!PyObject_IsInstance(ast, req_type[mode])) { + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", req_name[mode], Py_TYPE(ast)->tp_name); return NULL; Modified: python/branches/py3k/Python/bltinmodule.c ============================================================================== --- python/branches/py3k/Python/bltinmodule.c (original) +++ python/branches/py3k/Python/bltinmodule.c Sun Dec 13 02:23:39 2009 @@ -529,6 +529,7 @@ int mode = -1; int dont_inherit = 0; int supplied_flags = 0; + int is_ast; PyCompilerFlags cf; PyObject *cmd; static char *kwlist[] = {"source", "filename", "mode", "flags", @@ -567,7 +568,10 @@ return NULL; } - if (PyAST_Check(cmd)) { + is_ast = PyAST_Check(cmd); + if (is_ast == -1) + return NULL; + if (is_ast) { PyObject *result; if (supplied_flags & PyCF_ONLY_AST) { Py_INCREF(cmd); From python-checkins at python.org Sun Dec 13 02:24:58 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 01:24:58 -0000 Subject: [Python-checkins] r76777 - python/branches/py3k/Python/Python-ast.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 02:24:58 2009 New Revision: 76777 Log: regenerate Python-ast.c Modified: python/branches/py3k/Python/Python-ast.c Modified: python/branches/py3k/Python/Python-ast.c ============================================================================== --- python/branches/py3k/Python/Python-ast.c (original) +++ python/branches/py3k/Python/Python-ast.c Sun Dec 13 02:24:58 2009 @@ -3374,13 +3374,18 @@ obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; if (obj == Py_None) { *out = NULL; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Module_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Module_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3412,7 +3417,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Interactive_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Interactive_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3444,7 +3453,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Expression_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Expression_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty body; if (PyObject_HasAttrString(obj, "body")) { @@ -3463,7 +3476,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Suite_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Suite_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3508,6 +3525,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -3540,7 +3558,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)FunctionDef_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)FunctionDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier name; arguments_ty args; asdl_seq* body; @@ -3637,7 +3659,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ClassDef_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ClassDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier name; asdl_seq* bases; asdl_seq* keywords; @@ -3785,7 +3811,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Return_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Return_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -3803,7 +3833,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Delete_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Delete_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* targets; if (PyObject_HasAttrString(obj, "targets")) { @@ -3835,7 +3869,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Assign_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Assign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* targets; expr_ty value; @@ -3880,7 +3918,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugAssign_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)AugAssign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty target; operator_ty op; expr_ty value; @@ -3925,7 +3967,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)For_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)For_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty target; expr_ty iter; asdl_seq* body; @@ -4010,7 +4056,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)While_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)While_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; asdl_seq* body; asdl_seq* orelse; @@ -4081,7 +4131,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)If_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)If_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; asdl_seq* body; asdl_seq* orelse; @@ -4152,7 +4206,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)With_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)With_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty context_expr; expr_ty optional_vars; asdl_seq* body; @@ -4210,7 +4268,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Raise_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Raise_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty exc; expr_ty cause; @@ -4240,7 +4302,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)TryExcept_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)TryExcept_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; asdl_seq* handlers; asdl_seq* orelse; @@ -4325,7 +4391,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)TryFinally_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)TryFinally_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; asdl_seq* finalbody; @@ -4383,7 +4453,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Assert_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Assert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; expr_ty msg; @@ -4414,7 +4488,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Import_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Import_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4446,7 +4524,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ImportFrom_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ImportFrom_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier module; asdl_seq* names; int level; @@ -4503,7 +4585,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Global_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Global_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4535,7 +4621,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Nonlocal_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Nonlocal_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4567,7 +4657,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Expr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Expr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -4586,19 +4680,31 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Pass_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Pass_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Pass(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Break_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Break_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Break(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Continue_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Continue_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Continue(lineno, col_offset, arena); if (*out == NULL) goto failed; @@ -4617,6 +4723,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -4649,7 +4756,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)BoolOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)BoolOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { boolop_ty op; asdl_seq* values; @@ -4694,7 +4805,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BinOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)BinOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty left; operator_ty op; expr_ty right; @@ -4739,7 +4854,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)UnaryOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)UnaryOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { unaryop_ty op; expr_ty operand; @@ -4771,7 +4890,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Lambda_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Lambda_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { arguments_ty args; expr_ty body; @@ -4803,7 +4926,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)IfExp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)IfExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; expr_ty body; expr_ty orelse; @@ -4848,7 +4975,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Dict_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Dict_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* keys; asdl_seq* values; @@ -4906,7 +5037,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Set_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Set_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; if (PyObject_HasAttrString(obj, "elts")) { @@ -4938,7 +5073,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ListComp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ListComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -4983,7 +5122,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)SetComp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)SetComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -5028,7 +5171,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)DictComp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)DictComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty key; expr_ty value; asdl_seq* generators; @@ -5087,7 +5234,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -5132,7 +5283,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Yield_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Yield_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -5150,7 +5305,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Compare_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Compare_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty left; asdl_int_seq* ops; asdl_seq* comparators; @@ -5222,7 +5381,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Call_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Call_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty func; asdl_seq* args; asdl_seq* keywords; @@ -5318,7 +5481,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Num_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Num_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { object n; if (PyObject_HasAttrString(obj, "n")) { @@ -5337,7 +5504,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Str_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Str_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { string s; if (PyObject_HasAttrString(obj, "s")) { @@ -5356,7 +5527,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Bytes_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Bytes_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { string s; if (PyObject_HasAttrString(obj, "s")) { @@ -5375,13 +5550,21 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Ellipsis_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Ellipsis_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Ellipsis(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Attribute_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Attribute_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; identifier attr; expr_context_ty ctx; @@ -5426,7 +5609,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Subscript_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Subscript_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; slice_ty slice; expr_context_ty ctx; @@ -5471,7 +5658,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Starred_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Starred_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; expr_context_ty ctx; @@ -5503,7 +5694,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Name_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Name_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier id; expr_context_ty ctx; @@ -5535,7 +5730,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)List_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)List_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; expr_context_ty ctx; @@ -5580,7 +5779,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Tuple_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Tuple_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; expr_context_ty ctx; @@ -5638,28 +5841,53 @@ obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Load_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Load_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Load; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Store_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Store_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Store; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Del_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Del_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Del; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugLoad_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)AugLoad_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = AugLoad; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugStore_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)AugStore_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = AugStore; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Param_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Param_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Param; return 0; } @@ -5676,13 +5904,18 @@ obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; if (obj == Py_None) { *out = NULL; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Slice_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Slice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty lower; expr_ty upper; expr_ty step; @@ -5724,7 +5957,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ExtSlice_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ExtSlice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* dims; if (PyObject_HasAttrString(obj, "dims")) { @@ -5756,7 +5993,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Index_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Index_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -5788,12 +6029,21 @@ obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)And_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)And_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = And; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Or_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Or_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Or; return 0; } @@ -5810,52 +6060,101 @@ obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Add_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Add_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Add; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Sub_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Sub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Sub; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Mult_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Mult_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Mult; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Div_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Div_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Div; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Mod_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Mod_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Mod; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Pow_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Pow_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Pow; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)LShift_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)LShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = LShift; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)RShift_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)RShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = RShift; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitOr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitOr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitOr; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitXor_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitXor_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitXor; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitAnd_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitAnd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitAnd; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)FloorDiv_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)FloorDiv_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = FloorDiv; return 0; } @@ -5872,20 +6171,37 @@ obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Invert_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Invert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Invert; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Not_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Not_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Not; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)UAdd_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)UAdd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = UAdd; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)USub_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)USub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = USub; return 0; } @@ -5902,44 +6218,85 @@ obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Eq_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Eq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Eq; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)NotEq_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)NotEq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = NotEq; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Lt_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Lt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Lt; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)LtE_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)LtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = LtE; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Gt_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Gt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Gt; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)GtE_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)GtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = GtE; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Is_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Is_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Is; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)IsNot_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)IsNot_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = IsNot; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)In_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)In_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = In; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)NotIn_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)NotIn_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = NotIn; return 0; } @@ -6020,6 +6377,7 @@ obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -6052,7 +6410,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty type; identifier name; asdl_seq* body; @@ -6629,11 +6991,15 @@ PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, (PyObject*)Interactive_type}; char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; assert(0 <= mode && mode <= 2); init_types(); - if (!PyObject_IsInstance(ast, req_type[mode])) { + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", req_name[mode], Py_TYPE(ast)->tp_name); return NULL; From python-checkins at python.org Sun Dec 13 02:29:00 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 01:29:00 -0000 Subject: [Python-checkins] r76778 - in python/branches/release31-maint: Doc/library/functions.rst Parser/asdl_c.py Python/Python-ast.c Python/bltinmodule.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 02:29:00 2009 New Revision: 76778 Log: Merged revisions 76776 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76776 | benjamin.peterson | 2009-12-12 19:23:39 -0600 (Sat, 12 Dec 2009) | 25 lines Merged revisions 76534,76538,76628,76701,76774 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76534 | martin.v.loewis | 2009-11-26 02:42:05 -0600 (Thu, 26 Nov 2009) | 2 lines Fix typo. ........ r76538 | georg.brandl | 2009-11-26 14:48:25 -0600 (Thu, 26 Nov 2009) | 1 line #7400: typo. ........ r76628 | andrew.kuchling | 2009-12-02 08:27:11 -0600 (Wed, 02 Dec 2009) | 1 line Markup fixes ........ r76701 | andrew.kuchling | 2009-12-07 20:37:05 -0600 (Mon, 07 Dec 2009) | 1 line Typo fix; grammar fix ........ r76774 | benjamin.peterson | 2009-12-12 18:54:15 -0600 (Sat, 12 Dec 2009) | 1 line account for PyObject_IsInstance's new ability to fail ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/functions.rst python/branches/release31-maint/Parser/asdl_c.py python/branches/release31-maint/Python/Python-ast.c python/branches/release31-maint/Python/bltinmodule.c Modified: python/branches/release31-maint/Doc/library/functions.rst ============================================================================== --- python/branches/release31-maint/Doc/library/functions.rst (original) +++ python/branches/release31-maint/Doc/library/functions.rst Sun Dec 13 02:29:00 2009 @@ -965,7 +965,7 @@ .. function:: set([iterable]) :noindex: - Return a new set, optionally with elements are taken from *iterable*. + Return a new set, optionally with elements taken from *iterable*. The set type is described in :ref:`types-set`. Modified: python/branches/release31-maint/Parser/asdl_c.py ============================================================================== --- python/branches/release31-maint/Parser/asdl_c.py (original) +++ python/branches/release31-maint/Parser/asdl_c.py Sun Dec 13 02:29:00 2009 @@ -366,6 +366,7 @@ self.emit("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name, ctype), 0) self.emit("{", 0) self.emit("PyObject* tmp = NULL;", 1) + self.emit("int isinstance;", 1) self.emit("", 0) def sumTrailer(self, name): @@ -385,7 +386,13 @@ def simpleSum(self, sum, name): self.funcHeader(name) for t in sum.types: - self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + line = ("isinstance = PyObject_IsInstance(obj, " + "(PyObject *)%s_type);") + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) self.emit("*out = %s;" % t.name, 2) self.emit("return 0;", 2) self.emit("}", 1) @@ -407,7 +414,12 @@ for a in sum.attributes: self.visitField(a, name, sum=sum, depth=1) for t in sum.types: - self.emit("if (PyObject_IsInstance(obj, (PyObject*)%s_type)) {" % t.name, 1) + line = "isinstance = PyObject_IsInstance(obj, (PyObject*)%s_type);" + self.emit(line % (t.name,), 1) + self.emit("if (isinstance == -1) {", 1) + self.emit("return 1;", 2) + self.emit("}", 1) + self.emit("if (isinstance) {", 1) for f in t.fields: self.visitFieldDeclaration(f, t.name, sum=sum, depth=2) self.emit("", 0) @@ -1077,11 +1089,15 @@ PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, (PyObject*)Interactive_type}; char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; assert(0 <= mode && mode <= 2); init_types(); - if (!PyObject_IsInstance(ast, req_type[mode])) { + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", req_name[mode], Py_TYPE(ast)->tp_name); return NULL; Modified: python/branches/release31-maint/Python/Python-ast.c ============================================================================== --- python/branches/release31-maint/Python/Python-ast.c (original) +++ python/branches/release31-maint/Python/Python-ast.c Sun Dec 13 02:29:00 2009 @@ -3379,13 +3379,18 @@ obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; if (obj == Py_None) { *out = NULL; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Module_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Module_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3417,7 +3422,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Interactive_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Interactive_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3449,7 +3458,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Expression_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Expression_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty body; if (PyObject_HasAttrString(obj, "body")) { @@ -3468,7 +3481,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Suite_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Suite_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; if (PyObject_HasAttrString(obj, "body")) { @@ -3513,6 +3530,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -3545,7 +3563,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)FunctionDef_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)FunctionDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier name; arguments_ty args; asdl_seq* body; @@ -3642,7 +3664,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ClassDef_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ClassDef_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier name; asdl_seq* bases; asdl_seq* keywords; @@ -3790,7 +3816,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Return_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Return_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -3808,7 +3838,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Delete_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Delete_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* targets; if (PyObject_HasAttrString(obj, "targets")) { @@ -3840,7 +3874,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Assign_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Assign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* targets; expr_ty value; @@ -3885,7 +3923,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugAssign_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)AugAssign_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty target; operator_ty op; expr_ty value; @@ -3930,7 +3972,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)For_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)For_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty target; expr_ty iter; asdl_seq* body; @@ -4015,7 +4061,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)While_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)While_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; asdl_seq* body; asdl_seq* orelse; @@ -4086,7 +4136,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)If_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)If_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; asdl_seq* body; asdl_seq* orelse; @@ -4157,7 +4211,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)With_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)With_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty context_expr; expr_ty optional_vars; asdl_seq* body; @@ -4215,7 +4273,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Raise_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Raise_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty exc; expr_ty cause; @@ -4245,7 +4307,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)TryExcept_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)TryExcept_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; asdl_seq* handlers; asdl_seq* orelse; @@ -4330,7 +4396,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)TryFinally_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)TryFinally_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* body; asdl_seq* finalbody; @@ -4388,7 +4458,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Assert_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Assert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; expr_ty msg; @@ -4419,7 +4493,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Import_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Import_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4451,7 +4529,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ImportFrom_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ImportFrom_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier module; asdl_seq* names; int level; @@ -4509,7 +4591,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Global_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Global_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4541,7 +4627,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Nonlocal_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Nonlocal_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* names; if (PyObject_HasAttrString(obj, "names")) { @@ -4573,7 +4663,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Expr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Expr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -4592,19 +4686,31 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Pass_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Pass_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Pass(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Break_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Break_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Break(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Continue_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Continue_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Continue(lineno, col_offset, arena); if (*out == NULL) goto failed; @@ -4623,6 +4729,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -4655,7 +4762,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)BoolOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)BoolOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { boolop_ty op; asdl_seq* values; @@ -4700,7 +4811,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BinOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)BinOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty left; operator_ty op; expr_ty right; @@ -4745,7 +4860,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)UnaryOp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)UnaryOp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { unaryop_ty op; expr_ty operand; @@ -4777,7 +4896,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Lambda_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Lambda_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { arguments_ty args; expr_ty body; @@ -4809,7 +4932,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)IfExp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)IfExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty test; expr_ty body; expr_ty orelse; @@ -4854,7 +4981,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Dict_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Dict_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* keys; asdl_seq* values; @@ -4912,7 +5043,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Set_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Set_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; if (PyObject_HasAttrString(obj, "elts")) { @@ -4944,7 +5079,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ListComp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ListComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -4989,7 +5128,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)SetComp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)SetComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -5034,7 +5177,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)DictComp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)DictComp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty key; expr_ty value; asdl_seq* generators; @@ -5093,7 +5240,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty elt; asdl_seq* generators; @@ -5138,7 +5289,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Yield_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Yield_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -5156,7 +5311,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Compare_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Compare_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty left; asdl_int_seq* ops; asdl_seq* comparators; @@ -5228,7 +5387,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Call_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Call_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty func; asdl_seq* args; asdl_seq* keywords; @@ -5324,7 +5487,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Num_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Num_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { object n; if (PyObject_HasAttrString(obj, "n")) { @@ -5343,7 +5510,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Str_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Str_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { string s; if (PyObject_HasAttrString(obj, "s")) { @@ -5362,7 +5533,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Bytes_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Bytes_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { string s; if (PyObject_HasAttrString(obj, "s")) { @@ -5381,13 +5556,21 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Ellipsis_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Ellipsis_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Ellipsis(lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Attribute_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Attribute_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; identifier attr; expr_context_ty ctx; @@ -5432,7 +5615,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Subscript_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Subscript_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; slice_ty slice; expr_context_ty ctx; @@ -5477,7 +5664,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Starred_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Starred_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; expr_context_ty ctx; @@ -5509,7 +5700,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Name_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Name_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { identifier id; expr_context_ty ctx; @@ -5541,7 +5736,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)List_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)List_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; expr_context_ty ctx; @@ -5586,7 +5785,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Tuple_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Tuple_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* elts; expr_context_ty ctx; @@ -5644,28 +5847,53 @@ obj2ast_expr_context(PyObject* obj, expr_context_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Load_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Load_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Load; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Store_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Store_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Store; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Del_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Del_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Del; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugLoad_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)AugLoad_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = AugLoad; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)AugStore_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)AugStore_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = AugStore; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Param_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Param_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Param; return 0; } @@ -5682,13 +5910,18 @@ obj2ast_slice(PyObject* obj, slice_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; if (obj == Py_None) { *out = NULL; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Slice_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Slice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty lower; expr_ty upper; expr_ty step; @@ -5730,7 +5963,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)ExtSlice_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ExtSlice_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { asdl_seq* dims; if (PyObject_HasAttrString(obj, "dims")) { @@ -5762,7 +5999,11 @@ if (*out == NULL) goto failed; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Index_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)Index_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty value; if (PyObject_HasAttrString(obj, "value")) { @@ -5794,12 +6035,21 @@ obj2ast_boolop(PyObject* obj, boolop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)And_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)And_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = And; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Or_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Or_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Or; return 0; } @@ -5816,52 +6066,101 @@ obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Add_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Add_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Add; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Sub_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Sub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Sub; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Mult_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Mult_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Mult; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Div_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Div_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Div; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Mod_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Mod_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Mod; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Pow_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Pow_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Pow; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)LShift_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)LShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = LShift; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)RShift_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)RShift_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = RShift; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitOr_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitOr_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitOr; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitXor_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitXor_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitXor; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)BitAnd_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)BitAnd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = BitAnd; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)FloorDiv_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)FloorDiv_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = FloorDiv; return 0; } @@ -5878,20 +6177,37 @@ obj2ast_unaryop(PyObject* obj, unaryop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Invert_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Invert_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Invert; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Not_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Not_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Not; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)UAdd_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)UAdd_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = UAdd; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)USub_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)USub_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = USub; return 0; } @@ -5908,44 +6224,85 @@ obj2ast_cmpop(PyObject* obj, cmpop_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; - if (PyObject_IsInstance(obj, (PyObject*)Eq_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Eq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Eq; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)NotEq_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)NotEq_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = NotEq; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Lt_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Lt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Lt; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)LtE_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)LtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = LtE; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Gt_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Gt_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Gt; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)GtE_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)GtE_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = GtE; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)Is_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)Is_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = Is; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)IsNot_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)IsNot_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = IsNot; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)In_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)In_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = In; return 0; } - if (PyObject_IsInstance(obj, (PyObject*)NotIn_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject *)NotIn_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { *out = NotIn; return 0; } @@ -6026,6 +6383,7 @@ obj2ast_excepthandler(PyObject* obj, excepthandler_ty* out, PyArena* arena) { PyObject* tmp = NULL; + int isinstance; int lineno; int col_offset; @@ -6058,7 +6416,11 @@ PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler"); return 1; } - if (PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type)) { + isinstance = PyObject_IsInstance(obj, (PyObject*)ExceptHandler_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { expr_ty type; identifier name; asdl_seq* body; @@ -6635,11 +6997,15 @@ PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, (PyObject*)Interactive_type}; char *req_name[] = {"Module", "Expression", "Interactive"}; + int isinstance; assert(0 <= mode && mode <= 2); init_types(); - if (!PyObject_IsInstance(ast, req_type[mode])) { + isinstance = PyObject_IsInstance(ast, req_type[mode]); + if (isinstance == -1) + return NULL; + if (!isinstance) { PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s", req_name[mode], Py_TYPE(ast)->tp_name); return NULL; Modified: python/branches/release31-maint/Python/bltinmodule.c ============================================================================== --- python/branches/release31-maint/Python/bltinmodule.c (original) +++ python/branches/release31-maint/Python/bltinmodule.c Sun Dec 13 02:29:00 2009 @@ -529,6 +529,7 @@ int mode = -1; int dont_inherit = 0; int supplied_flags = 0; + int is_ast; PyCompilerFlags cf; PyObject *cmd; static char *kwlist[] = {"source", "filename", "mode", "flags", @@ -567,7 +568,10 @@ return NULL; } - if (PyAST_Check(cmd)) { + is_ast = PyAST_Check(cmd); + if (is_ast == -1) + return NULL; + if (is_ast) { PyObject *result; if (supplied_flags & PyCF_ONLY_AST) { Py_INCREF(cmd); From python-checkins at python.org Sun Dec 13 03:10:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 02:10:36 -0000 Subject: [Python-checkins] r76779 - in python/branches/py3k: Lib/test/test_parser.py Lib/unittest/case.py Objects/abstract.c Parser/tokenizer.c configure configure.in Message-ID: Author: benjamin.peterson Date: Sun Dec 13 03:10:36 2009 New Revision: 76779 Log: Merged revisions 76052,76522,76591,76689,76697,76733 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76052 | gregory.p.smith | 2009-11-01 20:02:38 -0600 (Sun, 01 Nov 2009) | 5 lines see issue1006238, this merges in the following patch to ease cross compiling the printf %zd check. http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-lang/python/files/python-2.5-cross-printf.patch?rev=1.1&view=markup ........ r76522 | barry.warsaw | 2009-11-25 12:38:32 -0600 (Wed, 25 Nov 2009) | 2 lines Add mktime_tz to __all__. It's documented as being available in email.utils. ........ r76591 | benjamin.peterson | 2009-11-29 16:26:26 -0600 (Sun, 29 Nov 2009) | 4 lines now that deepcopy can handle instance methods, this hack can be removed #7409 Thanks Robert Collins ........ r76689 | benjamin.peterson | 2009-12-06 11:37:48 -0600 (Sun, 06 Dec 2009) | 1 line rewrite translate_newlines for clarity ........ r76697 | benjamin.peterson | 2009-12-06 15:24:30 -0600 (Sun, 06 Dec 2009) | 2 lines fix test_parser from tokenizer tweak ........ r76733 | benjamin.peterson | 2009-12-09 21:37:59 -0600 (Wed, 09 Dec 2009) | 1 line substitute PyDict_Check() for PyObject_IsInstance ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_parser.py python/branches/py3k/Lib/unittest/case.py python/branches/py3k/Objects/abstract.c python/branches/py3k/Parser/tokenizer.c python/branches/py3k/configure python/branches/py3k/configure.in Modified: python/branches/py3k/Lib/test/test_parser.py ============================================================================== --- python/branches/py3k/Lib/test/test_parser.py (original) +++ python/branches/py3k/Lib/test/test_parser.py Sun Dec 13 03:10:36 2009 @@ -208,7 +208,7 @@ def test_position(self): # An absolutely minimal test of position information. Better # tests would be a big project. - code = "def f(x):\n return x + 1\n" + code = "def f(x):\n return x + 1" st1 = parser.suite(code) st2 = st1.totuple(line_info=1, col_info=1) @@ -237,9 +237,9 @@ (14, '+', 2, 13), (2, '1', 2, 15), (4, '', 2, 16), - (6, '', 3, -1), - (4, '', 3, -1), - (0, '', 3, -1)], + (6, '', 2, -1), + (4, '', 2, -1), + (0, '', 2, -1)], terminals) def test_extended_unpacking(self): Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Sun Dec 13 03:10:36 2009 @@ -130,17 +130,6 @@ 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. @@ -214,7 +203,7 @@ 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) + self._type_equality_funcs[typeobj] = function def addCleanup(self, function, *args, **kwargs): """Add a function, with arguments, to be called when the test is @@ -437,7 +426,7 @@ if type(first) is type(second): asserter = self._type_equality_funcs.get(type(first)) if asserter is not None: - return asserter.function + return asserter return self._baseAssertEqual Modified: python/branches/py3k/Objects/abstract.c ============================================================================== --- python/branches/py3k/Objects/abstract.c (original) +++ python/branches/py3k/Objects/abstract.c Sun Dec 13 03:10:36 2009 @@ -1453,7 +1453,7 @@ int PySequence_Check(PyObject *s) { - if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type)) + if (PyDict_Check(s)) return 0; return s != NULL && s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL; Modified: python/branches/py3k/Parser/tokenizer.c ============================================================================== --- python/branches/py3k/Parser/tokenizer.c (original) +++ python/branches/py3k/Parser/tokenizer.c Sun Dec 13 03:10:36 2009 @@ -652,20 +652,20 @@ static char * translate_newlines(const char *s, int exec_input, struct tok_state *tok) { - int skip_next_lf = 0, length = strlen(s), final_length; + int skip_next_lf = 0, needed_length = strlen(s) + 2, final_length; char *buf, *current; - char c; - buf = PyMem_MALLOC(length + 2); + char c = '\0'; + buf = PyMem_MALLOC(needed_length); if (buf == NULL) { tok->done = E_NOMEM; return NULL; } - for (current = buf; (c = *s++);) { + for (current = buf; *s; s++, current++) { + c = *s; if (skip_next_lf) { skip_next_lf = 0; if (c == '\n') { - c = *s; - s++; + c = *++s; if (!c) break; } @@ -675,19 +675,18 @@ c = '\n'; } *current = c; - current++; } - /* If this is exec input, add a newline to the end of the file if + /* If this is exec input, add a newline to the end of the string if there isn't one already. */ - if (exec_input && *current != '\n') { + if (exec_input && c != '\n') { *current = '\n'; current++; } *current = '\0'; - final_length = current - buf; - if (final_length < length && final_length) + final_length = current - buf + 1; + if (final_length < needed_length && final_length) /* should never fail */ - buf = PyMem_REALLOC(buf, final_length + 1); + buf = PyMem_REALLOC(buf, final_length); return buf; } Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sun Dec 13 03:10:36 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76637 . +# From configure.in Revision: 76645 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -26672,7 +26672,8 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then - ac_cv_have_size_t_format=no + ac_cv_have_size_t_format="cross -- assuming yes" + else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -26750,13 +26751,10 @@ fi - fi - { echo "$as_me:$LINENO: result: $ac_cv_have_size_t_format" >&5 echo "${ECHO_T}$ac_cv_have_size_t_format" >&6; } -if test $ac_cv_have_size_t_format = yes -then +if test "$ac_cv_have_size_t_format" != no ; then cat >>confdefs.h <<\_ACEOF #define PY_FORMAT_SIZE_T "z" Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sun Dec 13 03:10:36 2009 @@ -3905,9 +3905,8 @@ LIBS="$LIBS -framework CoreFoundation" fi -AC_MSG_CHECKING(for %zd printf() format support) -AC_CACHE_VAL(ac_cv_have_size_t_format, -AC_TRY_RUN([[ +AC_CACHE_CHECK([for %zd printf() format support], ac_cv_have_size_t_format, [dnl +AC_TRY_RUN([ #include #include #include @@ -3942,13 +3941,11 @@ return 0; } -]], ac_cv_have_size_t_format=yes, +], ac_cv_have_size_t_format=yes, ac_cv_have_size_t_format=no, - ac_cv_have_size_t_format=no) -) -AC_MSG_RESULT($ac_cv_have_size_t_format) -if test $ac_cv_have_size_t_format = yes -then + [ac_cv_have_size_t_format="cross -- assuming yes"] +)]) +if test "$ac_cv_have_size_t_format" != no ; then AC_DEFINE(PY_FORMAT_SIZE_T, "z", [Define to printf format modifier for Py_ssize_t]) fi From python-checkins at python.org Sun Dec 13 12:32:27 2009 From: python-checkins at python.org (lars.gustaebel) Date: Sun, 13 Dec 2009 11:32:27 -0000 Subject: [Python-checkins] r76780 - in python/trunk: Lib/tarfile.py Misc/NEWS Message-ID: Author: lars.gustaebel Date: Sun Dec 13 12:32:27 2009 New Revision: 76780 Log: Issue #7357: No longer suppress fatal extraction errors by default. TarFile's errorlevel argument controls how errors are handled that occur during extraction. There are three possible levels 0, 1 and 2. If errorlevel is set to 1 or 2 fatal errors (e.g. a full filesystem) are raised as exceptions. If it is set to 0, which is the default value, extraction errors are suppressed, and error messages are written to the debug log instead. But, if the debug log is not activated, which is the default as well, all these errors go unnoticed. The original intention was to imitate GNU tar which tries to extract as many members as possible instead of stopping on the first error. It turns out that this is no good default behaviour for a tar library. This patch simply changes the default value for the errorlevel argument from 0 to 1, so that fatal extraction errors are raised as EnvironmentError exceptions. Modified: python/trunk/Lib/tarfile.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/tarfile.py ============================================================================== --- python/trunk/Lib/tarfile.py (original) +++ python/trunk/Lib/tarfile.py Sun Dec 13 12:32:27 2009 @@ -1489,7 +1489,7 @@ ignore_zeros = False # If true, skips empty or invalid blocks and # continues processing. - errorlevel = 0 # If 0, fatal errors only appear in debug + errorlevel = 1 # If 0, fatal errors only appear in debug # messages (if debug >= 0). If > 0, errors # are passed to the caller as exceptions. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 13 12:32:27 2009 @@ -15,6 +15,9 @@ Library ------- +- Issue #7357: tarfile no longer suppresses fatal extraction errors by + default. + - Issue #7470: logging: fix bug in Unicode encoding fallback. - Issue #5949: fixed IMAP4_SSL hang when the IMAP server response is From python-checkins at python.org Sun Dec 13 12:38:07 2009 From: python-checkins at python.org (lars.gustaebel) Date: Sun, 13 Dec 2009 11:38:07 -0000 Subject: [Python-checkins] r76781 - python/branches/release26-maint Message-ID: Author: lars.gustaebel Date: Sun Dec 13 12:38:07 2009 New Revision: 76781 Log: Blocked revisions 76780 via svnmerge ........ r76780 | lars.gustaebel | 2009-12-13 12:32:27 +0100 (Sun, 13 Dec 2009) | 21 lines Issue #7357: No longer suppress fatal extraction errors by default. TarFile's errorlevel argument controls how errors are handled that occur during extraction. There are three possible levels 0, 1 and 2. If errorlevel is set to 1 or 2 fatal errors (e.g. a full filesystem) are raised as exceptions. If it is set to 0, which is the default value, extraction errors are suppressed, and error messages are written to the debug log instead. But, if the debug log is not activated, which is the default as well, all these errors go unnoticed. The original intention was to imitate GNU tar which tries to extract as many members as possible instead of stopping on the first error. It turns out that this is no good default behaviour for a tar library. This patch simply changes the default value for the errorlevel argument from 0 to 1, so that fatal extraction errors are raised as EnvironmentError exceptions. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 13 12:42:30 2009 From: python-checkins at python.org (lars.gustaebel) Date: Sun, 13 Dec 2009 11:42:30 -0000 Subject: [Python-checkins] r76782 - in python/branches/py3k: Lib/tarfile.py Misc/NEWS Message-ID: Author: lars.gustaebel Date: Sun Dec 13 12:42:29 2009 New Revision: 76782 Log: Merged revisions 76780 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76780 | lars.gustaebel | 2009-12-13 12:32:27 +0100 (Sun, 13 Dec 2009) | 21 lines Issue #7357: No longer suppress fatal extraction errors by default. TarFile's errorlevel argument controls how errors are handled that occur during extraction. There are three possible levels 0, 1 and 2. If errorlevel is set to 1 or 2 fatal errors (e.g. a full filesystem) are raised as exceptions. If it is set to 0, which is the default value, extraction errors are suppressed, and error messages are written to the debug log instead. But, if the debug log is not activated, which is the default as well, all these errors go unnoticed. The original intention was to imitate GNU tar which tries to extract as many members as possible instead of stopping on the first error. It turns out that this is no good default behaviour for a tar library. This patch simply changes the default value for the errorlevel argument from 0 to 1, so that fatal extraction errors are raised as EnvironmentError exceptions. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/tarfile.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/tarfile.py ============================================================================== --- python/branches/py3k/Lib/tarfile.py (original) +++ python/branches/py3k/Lib/tarfile.py Sun Dec 13 12:42:29 2009 @@ -1481,7 +1481,7 @@ ignore_zeros = False # If true, skips empty or invalid blocks and # continues processing. - errorlevel = 0 # If 0, fatal errors only appear in debug + errorlevel = 1 # If 0, fatal errors only appear in debug # messages (if debug >= 0). If > 0, errors # are passed to the caller as exceptions. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Dec 13 12:42:29 2009 @@ -157,6 +157,9 @@ Library ------- +- Issue #7357: tarfile no longer suppresses fatal extraction errors by + default. + - Issue #5949: added check for correct lineends in input from IMAP server in imaplib. From python-checkins at python.org Sun Dec 13 12:43:59 2009 From: python-checkins at python.org (lars.gustaebel) Date: Sun, 13 Dec 2009 11:43:59 -0000 Subject: [Python-checkins] r76783 - python/branches/release31-maint Message-ID: Author: lars.gustaebel Date: Sun Dec 13 12:43:59 2009 New Revision: 76783 Log: Blocked revisions 76782 via svnmerge ................ r76782 | lars.gustaebel | 2009-12-13 12:42:29 +0100 (Sun, 13 Dec 2009) | 28 lines Merged revisions 76780 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76780 | lars.gustaebel | 2009-12-13 12:32:27 +0100 (Sun, 13 Dec 2009) | 21 lines Issue #7357: No longer suppress fatal extraction errors by default. TarFile's errorlevel argument controls how errors are handled that occur during extraction. There are three possible levels 0, 1 and 2. If errorlevel is set to 1 or 2 fatal errors (e.g. a full filesystem) are raised as exceptions. If it is set to 0, which is the default value, extraction errors are suppressed, and error messages are written to the debug log instead. But, if the debug log is not activated, which is the default as well, all these errors go unnoticed. The original intention was to imitate GNU tar which tries to extract as many members as possible instead of stopping on the first error. It turns out that this is no good default behaviour for a tar library. This patch simply changes the default value for the errorlevel argument from 0 to 1, so that fatal extraction errors are raised as EnvironmentError exceptions. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Dec 13 12:47:36 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 13 Dec 2009 11:47:36 -0000 Subject: [Python-checkins] r76784 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Sun Dec 13 12:47:36 2009 New Revision: 76784 Log: 'Rational' becomes 'Normalized' Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Sun Dec 13 12:47:36 2009 @@ -76,11 +76,12 @@ 1. it should be possible to express more than one versioning level (usually this is expressed as major and minor revision and, sometimes, also a micro revision). -2. most projects need special meaning versions for "pre-releases" (such as - "alpha", "beta", "rc"), and these have widely used aliases ("a" stands - for "alpha", "b" for "beta" and "c" for "rc"). And these pre-release - versions make it impossible to use a simple alphanumerical ordering - of the version string components. (Example: 3.1a1 < 3.1) +2. a significant number of projects need special meaning versions for + "pre-releases" (such as "alpha", "beta", "rc"), and these have widely + used aliases ("a" stands for "alpha", "b" for "beta" and "c" for "rc"). + And these pre-release versions make it impossible to use a simple + alphanumerical ordering of the version string components. + (Example: 3.1a1 < 3.1) 3. some projects also need "post-releases" of regular versions, mainly for installer work which can't be clearly expressed otherwise. 4. development versions allow packagers of unreleased work to avoid version @@ -307,7 +308,7 @@ Some examples probably make it clearer:: - >>> from verlib import RationalVersion as V + >>> from verlib import NormalizedVersion as V >>> (V('1.0a1') ... < V('1.0a2.dev456') ... < V('1.0a2') @@ -334,18 +335,18 @@ before a ``.post456`` marker. This can be used to do development versions of post releases. -``verlib`` provides a ``RationalVersion`` class and a -``suggest_rational_version`` function. +``verlib`` provides a ``NormalizedVersion`` class and a +``suggest_normalized_version`` function. -RationalVersion ---------------- +NormalizedVersion +----------------- -The `RationalVersion` class is used to hold a version and to compare it with +The `NormalizedVersion` class is used to hold a version and to compare it with others. It takes a string as an argument, that contains the representation of the version:: - >>> from verlib import RationalVersion - >>> version = RationalVersion('1.0') + >>> from verlib import NormalizedVersion + >>> version = NormalizedVersion('1.0') The version can be represented as a string:: @@ -354,9 +355,9 @@ Or compared with others:: - >>> RationalVersion('1.0') > RationalVersion('0.9') + >>> NormalizedVersion('1.0') > NormalizedVersion('0.9') True - >>> RationalVersion('1.0') < RationalVersion('1.1') + >>> NormalizedVersion('1.0') < NormalizedVersion('1.1') True A class method called ``from_parts`` is available if you want to create an @@ -364,63 +365,64 @@ Examples :: - >>> version = RationalVersion.from_parts((1, 0)) + >>> version = NormalizedVersion.from_parts((1, 0)) >>> str(version) '1.0' - >>> version = RationalVersion.from_parts((1, 0), ('c', 4)) + >>> version = NormalizedVersion.from_parts((1, 0), ('c', 4)) >>> str(version) '1.0c4' - >>> version = RationalVersion.from_parts((1, 0), ('c', 4), ('dev', 34)) + >>> version = NormalizedVersion.from_parts((1, 0), ('c', 4), ('dev', 34)) >>> str(version) '1.0c4.dev34' -suggest_rational_version ------------------------- +suggest_normalized_version +-------------------------- -``suggest_rational_version`` is a function that suggests a rational version +``suggest_normalized_version`` is a function that suggests a normalized version close to the given version string. If you have a version string that isn't -rational (i.e. ``RationalVersion`` doesn't like it) then you might be able -to get an equivalent (or close) rational version from this function. +normalized (i.e. ``NormalizedVersion`` doesn't like it) then you might be able +to get an equivalent (or close) normalized version from this function. This does a number of simple normalizations to the given string, based on observation of versions currently in use on PyPI. Given a dump of those version during PyCon 2009, 4287 of them: -- 2312 (53.93%) match RationalVersion without change with the automatic +- 2312 (53.93%) match NormalizedVersion without change with the automatic suggestion - 3474 (81.04%) match when using this suggestion method When a tool needs to work with versions, a strategy is to use -``suggest_rational_version`` on the versions string. If this function returns +``suggest_normalized_version`` on the versions string. If this function returns ``None``, it means that the provided version is not close enough to the standard scheme. If it returns a version that slighlty differs from -the original version, it's a suggested rational version. Last, if it +the original version, it's a suggested normalized version. Last, if it returns the same string, it means that the version matches the scheme. Here's an example of usage :: - >>> from verlib import suggest_rational_version, RationalVersion + >>> from verlib import suggest_normalized_version, NormalizedVersion >>> import warnings >>> def validate_version(version): - ... rversion = suggest_rational_version(version) + ... rversion = suggest_normalized_version(version) ... if rversion is None: ... raise ValueError('Cannot work with "%s"' % version) ... if rversion != version: - ... warnings.warn('"%s" is not a rational version, ' - ... 'it has been transformed into "%s" ' + ... warnings.warn('"%s" is not a normalized version.\n' + ... 'It has been transformed into "%s" ' ... 'for interoperability.' % (version, rversion)) - ... return RationalVersion(rversion) + ... return NormalizedVersion(rversion) ... >>> validate_version('2.4rc1') - __main__:8: UserWarning: "2.4rc1" is not a rational version, it has been transformed into "2.4c1" for interoperability. - RationalVersion('2.4c1') + __main__:8: UserWarning: "2.4rc1" is not a normalized version. + It has been transformed into "2.4c1" for interoperability. + NormalizedVersion('2.4c1') >>> validate_version('2.4c1') - RationalVersion('2.4c1') + NormalizedVersion('2.4c1') >>> validate_version('foo') Traceback (most recent call last): @@ -432,7 +434,7 @@ ======= Distutils will deprecate its existing versions class in favor of -``RationalVersion``. The ``verlib`` module presented in this PEP will be +``NormalizedVersion``. The ``verlib`` module presented in this PEP will be renamed to ``version`` and placed into the ``distutils`` package. References From python-checkins at python.org Sun Dec 13 15:18:08 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 14:18:08 -0000 Subject: [Python-checkins] r76785 - in python/trunk: Doc/license.rst LICENSE Message-ID: Author: benjamin.peterson Date: Sun Dec 13 15:18:08 2009 New Revision: 76785 Log: add 2.6.x point releases Modified: python/trunk/Doc/license.rst python/trunk/LICENSE Modified: python/trunk/Doc/license.rst ============================================================================== --- python/trunk/Doc/license.rst (original) +++ python/trunk/Doc/license.rst Sun Dec 13 15:18:08 2009 @@ -96,6 +96,12 @@ +----------------+--------------+-----------+------------+-----------------+ | 2.6.1 | 2.6 | 2008 | PSF | yes | +----------------+--------------+-----------+------------+-----------------+ +| 2.6.2 | 2.6.1 | 2009 | PSF | yes | ++----------------+--------------+-----------+------------+-----------------+ +| 2.6.3 | 2.6.2 | 2009 | PSF | yes | ++----------------+--------------+-----------+------------+-----------------+ +| 2.6.4 | 2.6.3 | 2009 | PSF | yes | ++----------------+--------------+-----------+------------+-----------------+ .. note:: Modified: python/trunk/LICENSE ============================================================================== --- python/trunk/LICENSE (original) +++ python/trunk/LICENSE Sun Dec 13 15:18:08 2009 @@ -59,6 +59,9 @@ 2.5.3 2.5.2 2008 PSF yes 2.6 2.5 2008 PSF yes 2.6.1 2.6 2008 PSF yes + 2.6.2 2.6.1 2009 PSF yes + 2.6.3 2.6.2 2009 PSF yes + 2.6.4 2.6.3 2009 PSF yes Footnotes: From python-checkins at python.org Sun Dec 13 15:20:15 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 14:20:15 -0000 Subject: [Python-checkins] r76786 - in python/branches/release26-maint: Doc/license.rst LICENSE Message-ID: Author: benjamin.peterson Date: Sun Dec 13 15:20:15 2009 New Revision: 76786 Log: Merged revisions 76785 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76785 | benjamin.peterson | 2009-12-13 08:18:08 -0600 (Sun, 13 Dec 2009) | 1 line add 2.6.x point releases ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/license.rst python/branches/release26-maint/LICENSE Modified: python/branches/release26-maint/Doc/license.rst ============================================================================== --- python/branches/release26-maint/Doc/license.rst (original) +++ python/branches/release26-maint/Doc/license.rst Sun Dec 13 15:20:15 2009 @@ -96,6 +96,12 @@ +----------------+--------------+-----------+------------+-----------------+ | 2.6.1 | 2.6 | 2008 | PSF | yes | +----------------+--------------+-----------+------------+-----------------+ +| 2.6.2 | 2.6.1 | 2009 | PSF | yes | ++----------------+--------------+-----------+------------+-----------------+ +| 2.6.3 | 2.6.2 | 2009 | PSF | yes | ++----------------+--------------+-----------+------------+-----------------+ +| 2.6.4 | 2.6.3 | 2009 | PSF | yes | ++----------------+--------------+-----------+------------+-----------------+ .. note:: Modified: python/branches/release26-maint/LICENSE ============================================================================== --- python/branches/release26-maint/LICENSE (original) +++ python/branches/release26-maint/LICENSE Sun Dec 13 15:20:15 2009 @@ -59,6 +59,9 @@ 2.5.3 2.5.2 2008 PSF yes 2.6 2.5 2008 PSF yes 2.6.1 2.6 2008 PSF yes + 2.6.2 2.6.1 2009 PSF yes + 2.6.3 2.6.2 2009 PSF yes + 2.6.4 2.6.3 2009 PSF yes Footnotes: From python-checkins at python.org Sun Dec 13 15:21:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 14:21:47 -0000 Subject: [Python-checkins] r76787 - in python/branches/py3k: Doc/license.rst LICENSE Message-ID: Author: benjamin.peterson Date: Sun Dec 13 15:21:46 2009 New Revision: 76787 Log: Merged revisions 76785 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76785 | benjamin.peterson | 2009-12-13 08:18:08 -0600 (Sun, 13 Dec 2009) | 1 line add 2.6.x point releases ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/license.rst python/branches/py3k/LICENSE Modified: python/branches/py3k/Doc/license.rst ============================================================================== --- python/branches/py3k/Doc/license.rst (original) +++ python/branches/py3k/Doc/license.rst Sun Dec 13 15:21:46 2009 @@ -98,6 +98,12 @@ +----------------+--------------+------------+------------+-----------------+ | 3.2 | 3.1 | 2009 | PSF | yes | +----------------+--------------+------------+------------+-----------------+ +| 2.6.2 | 2.6.1 | 2009 | PSF | yes | ++----------------+--------------+-----------+------------+-----------------+ +| 2.6.3 | 2.6.2 | 2009 | PSF | yes | ++----------------+--------------+-----------+------------+-----------------+ +| 2.6.4 | 2.6.3 | 2009 | PSF | yes | ++----------------+--------------+-----------+------------+-----------------+ .. note:: Modified: python/branches/py3k/LICENSE ============================================================================== --- python/branches/py3k/LICENSE (original) +++ python/branches/py3k/LICENSE Sun Dec 13 15:21:46 2009 @@ -59,6 +59,9 @@ 2.5.3 2.5.2 2008 PSF yes 2.6 2.5 2008 PSF yes 2.6.1 2.6 2008 PSF yes + 2.6.2 2.6.1 2009 PSF yes + 2.6.3 2.6.2 2009 PSF yes + 2.6.4 2.6.3 2009 PSF yes 3.0 2.6 2008 PSF yes 3.1 3.0 2009 PSF yes 3.2 3.1 2009 PSF yes From python-checkins at python.org Sun Dec 13 15:23:30 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 14:23:30 -0000 Subject: [Python-checkins] r76788 - python/branches/py3k/Doc/license.rst Message-ID: Author: benjamin.peterson Date: Sun Dec 13 15:23:30 2009 New Revision: 76788 Log: fix markup Modified: python/branches/py3k/Doc/license.rst Modified: python/branches/py3k/Doc/license.rst ============================================================================== --- python/branches/py3k/Doc/license.rst (original) +++ python/branches/py3k/Doc/license.rst Sun Dec 13 15:23:30 2009 @@ -98,12 +98,12 @@ +----------------+--------------+------------+------------+-----------------+ | 3.2 | 3.1 | 2009 | PSF | yes | +----------------+--------------+------------+------------+-----------------+ -| 2.6.2 | 2.6.1 | 2009 | PSF | yes | -+----------------+--------------+-----------+------------+-----------------+ -| 2.6.3 | 2.6.2 | 2009 | PSF | yes | -+----------------+--------------+-----------+------------+-----------------+ -| 2.6.4 | 2.6.3 | 2009 | PSF | yes | -+----------------+--------------+-----------+------------+-----------------+ +| 2.6.2 | 2.6.1 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ +| 2.6.3 | 2.6.2 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ +| 2.6.4 | 2.6.3 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ .. note:: From python-checkins at python.org Sun Dec 13 15:26:42 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 14:26:42 -0000 Subject: [Python-checkins] r76789 - in python/branches/py3k: Doc/license.rst LICENSE Message-ID: Author: benjamin.peterson Date: Sun Dec 13 15:26:42 2009 New Revision: 76789 Log: update 3.x versions Modified: python/branches/py3k/Doc/license.rst python/branches/py3k/LICENSE Modified: python/branches/py3k/Doc/license.rst ============================================================================== --- python/branches/py3k/Doc/license.rst (original) +++ python/branches/py3k/Doc/license.rst Sun Dec 13 15:26:42 2009 @@ -92,18 +92,20 @@ +----------------+--------------+------------+------------+-----------------+ | 2.6.1 | 2.6 | 2008 | PSF | yes | +----------------+--------------+------------+------------+-----------------+ -| 3.0 | 2.6 | 2008 | PSF | yes | -+----------------+--------------+------------+------------+-----------------+ -| 3.1 | 3.0 | 2009 | PSF | yes | -+----------------+--------------+------------+------------+-----------------+ -| 3.2 | 3.1 | 2009 | PSF | yes | -+----------------+--------------+------------+------------+-----------------+ | 2.6.2 | 2.6.1 | 2009 | PSF | yes | +----------------+--------------+------------+------------+-----------------+ | 2.6.3 | 2.6.2 | 2009 | PSF | yes | +----------------+--------------+------------+------------+-----------------+ | 2.6.4 | 2.6.3 | 2009 | PSF | yes | +----------------+--------------+------------+------------+-----------------+ +| 3.0 | 2.6 | 2008 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ +| 3.0.1 | 3.0 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ +| 3.1 | 3.0.1 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ +| 3.1.1 | 3.1 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ .. note:: Modified: python/branches/py3k/LICENSE ============================================================================== --- python/branches/py3k/LICENSE (original) +++ python/branches/py3k/LICENSE Sun Dec 13 15:26:42 2009 @@ -63,8 +63,9 @@ 2.6.3 2.6.2 2009 PSF yes 2.6.4 2.6.3 2009 PSF yes 3.0 2.6 2008 PSF yes - 3.1 3.0 2009 PSF yes - 3.2 3.1 2009 PSF yes + 3.0.1 3.0 2009 PSF yes + 3.1 3.0.1 2009 PSF yes + 3.1.1 3.1 2009 PSF yes Footnotes: From python-checkins at python.org Sun Dec 13 15:29:43 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 14:29:43 -0000 Subject: [Python-checkins] r76790 - in python/branches/release31-maint: Doc/license.rst LICENSE Message-ID: Author: benjamin.peterson Date: Sun Dec 13 15:29:42 2009 New Revision: 76790 Log: Merged revisions 76787-76789 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76787 | benjamin.peterson | 2009-12-13 08:21:46 -0600 (Sun, 13 Dec 2009) | 9 lines Merged revisions 76785 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76785 | benjamin.peterson | 2009-12-13 08:18:08 -0600 (Sun, 13 Dec 2009) | 1 line add 2.6.x point releases ........ ................ r76788 | benjamin.peterson | 2009-12-13 08:23:30 -0600 (Sun, 13 Dec 2009) | 1 line fix markup ................ r76789 | benjamin.peterson | 2009-12-13 08:26:42 -0600 (Sun, 13 Dec 2009) | 1 line update 3.x versions ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/license.rst python/branches/release31-maint/LICENSE Modified: python/branches/release31-maint/Doc/license.rst ============================================================================== --- python/branches/release31-maint/Doc/license.rst (original) +++ python/branches/release31-maint/Doc/license.rst Sun Dec 13 15:29:42 2009 @@ -92,8 +92,20 @@ +----------------+--------------+------------+------------+-----------------+ | 2.6.1 | 2.6 | 2008 | PSF | yes | +----------------+--------------+------------+------------+-----------------+ +| 2.6.2 | 2.6.1 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ +| 2.6.3 | 2.6.2 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ +| 2.6.4 | 2.6.3 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ | 3.0 | 2.6 | 2008 | PSF | yes | +----------------+--------------+------------+------------+-----------------+ +| 3.0.1 | 3.0 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ +| 3.1 | 3.0.1 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ +| 3.1.1 | 3.1 | 2009 | PSF | yes | ++----------------+--------------+------------+------------+-----------------+ .. note:: Modified: python/branches/release31-maint/LICENSE ============================================================================== --- python/branches/release31-maint/LICENSE (original) +++ python/branches/release31-maint/LICENSE Sun Dec 13 15:29:42 2009 @@ -59,7 +59,13 @@ 2.5.3 2.5.2 2008 PSF yes 2.6 2.5 2008 PSF yes 2.6.1 2.6 2008 PSF yes + 2.6.2 2.6.1 2009 PSF yes + 2.6.3 2.6.2 2009 PSF yes + 2.6.4 2.6.3 2009 PSF yes 3.0 2.6 2008 PSF yes + 3.0.1 3.0 2009 PSF yes + 3.1 3.0.1 2009 PSF yes + 3.1.1 3.1 2009 PSF yes Footnotes: From rdmurray at bitdance.com Sun Dec 13 15:37:49 2009 From: rdmurray at bitdance.com (R. David Murray) Date: Sun, 13 Dec 2009 09:37:49 -0500 Subject: [Python-checkins] r76763 - in python/trunk: Lib/test/test_tuple.py Objects/tupleobject.c In-Reply-To: <20091212191320.B51961FA671@kimball.webabinitio.net> References: <20091212191320.B51961FA671@kimball.webabinitio.net> Message-ID: <20091213143749.A2CA21F9E18@kimball.webabinitio.net> On Sat, 12 Dec 2009 14:13:20 -0500, antoine.pitrou wrote: > Author: antoine.pitrou > Date: Sat Dec 12 20:13:08 2009 > New Revision: 76763 > > Log: > Issue #7466: segmentation fault when the garbage collector is called > in the middle of populating a tuple. Patch by Florent Xicluna. > > (note: no NEWS entry for trunk since the bug was introduced in 2.7/3.1) Since there's an alpha out that doesn't include this patch, shouldn't there still be a NEWS item on trunk? --David From solipsis at pitrou.net Sun Dec 13 17:15:16 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Sun, 13 Dec 2009 16:15:16 +0000 (UTC) Subject: [Python-checkins] =?utf-8?q?r76763_-_in_python/trunk=3A=09Lib/tes?= =?utf-8?q?t/test=5Ftuple=2Epy_Objects/tupleobject=2Ec?= References: <20091212191320.B51961FA671@kimball.webabinitio.net> <20091213143749.A2CA21F9E18@kimball.webabinitio.net> Message-ID: R. David Murray bitdance.com> writes: > > > Log: > > Issue #7466: segmentation fault when the garbage collector is called > > in the middle of populating a tuple. Patch by Florent Xicluna. > > > > (note: no NEWS entry for trunk since the bug was introduced in 2.7/3.1) > > Since there's an alpha out that doesn't include this patch, shouldn't > there still be a NEWS item on trunk? Ah, indeed. That's a good point. Antoine. From python-checkins at python.org Sun Dec 13 17:18:14 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 13 Dec 2009 16:18:14 -0000 Subject: [Python-checkins] r76791 - python/trunk/Misc/NEWS Message-ID: Author: antoine.pitrou Date: Sun Dec 13 17:18:14 2009 New Revision: 76791 Log: Add NEWS entry as per RDM's suggestion (the bug was actually present in 2.7 alpha 1) Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 13 17:18:14 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7466: segmentation fault when the garbage collector is called + in the middle of populating a tuple. Patch by Florent Xicluna. + Library ------- From python-checkins at python.org Sun Dec 13 17:19:44 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 13 Dec 2009 16:19:44 -0000 Subject: [Python-checkins] r76792 - python/branches/release26-maint Message-ID: Author: antoine.pitrou Date: Sun Dec 13 17:19:43 2009 New Revision: 76792 Log: Blocked revisions 76791 via svnmerge ........ r76791 | antoine.pitrou | 2009-12-13 17:18:14 +0100 (dim., 13 d?c. 2009) | 5 lines Add NEWS entry as per RDM's suggestion (the bug was actually present in 2.7 alpha 1) ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 13 17:19:47 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 13 Dec 2009 16:19:47 -0000 Subject: [Python-checkins] r76793 - python/branches/py3k Message-ID: Author: antoine.pitrou Date: Sun Dec 13 17:19:46 2009 New Revision: 76793 Log: Blocked revisions 76791 via svnmerge ........ r76791 | antoine.pitrou | 2009-12-13 17:18:14 +0100 (dim., 13 d?c. 2009) | 5 lines Add NEWS entry as per RDM's suggestion (the bug was actually present in 2.7 alpha 1) ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Dec 13 17:36:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 16:36:54 -0000 Subject: [Python-checkins] r76794 - in python/trunk: Lib/test/test_descr.py Misc/NEWS Objects/typeobject.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 17:36:53 2009 New Revision: 76794 Log: fix the ignoring of __cmp__ method on metaclasses #7491 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 Sun Dec 13 17:36:53 2009 @@ -1222,6 +1222,15 @@ # This used to crash self.assertRaises(TypeError, MyABC.a.__set__, u, 3) + def test_metaclass_cmp(self): + # See bug 7491. + class M(type): + def __cmp__(self, other): + return -1 + class X(object): + __metaclass__ = M + self.assertTrue(X < M) + def test_dynamics(self): # Testing class attribute propagation... class D(object): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 13 17:36:53 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #7491: Metaclass's __cmp__ method was ignored. + - Issue #7466: segmentation fault when the garbage collector is called in the middle of populating a tuple. Patch by Florent Xicluna. Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Sun Dec 13 17:36:53 2009 @@ -628,7 +628,11 @@ int c; /* Make sure both arguments are types. */ - if (!PyType_Check(v) || !PyType_Check(w)) { + if (!PyType_Check(v) || !PyType_Check(w) || + /* If there is a __cmp__ method defined, let it be called instead + of our dumb function designed merely to warn. See bug + #7491. */ + Py_TYPE(v)->tp_compare || Py_TYPE(w)->tp_compare) { result = Py_NotImplemented; goto out; } From python-checkins at python.org Sun Dec 13 17:39:38 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 16:39:38 -0000 Subject: [Python-checkins] r76795 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Sun Dec 13 17:39:38 2009 New Revision: 76795 Log: Blocked revisions 76794 via svnmerge ........ r76794 | benjamin.peterson | 2009-12-13 10:36:53 -0600 (Sun, 13 Dec 2009) | 2 lines fix the ignoring of __cmp__ method on metaclasses #7491 ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Dec 13 17:41:45 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 16:41:45 -0000 Subject: [Python-checkins] r76796 - in python/branches/release26-maint: Lib/test/test_descr.py Misc/NEWS Objects/typeobject.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 17:41:44 2009 New Revision: 76796 Log: Merged revisions 76794 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76794 | benjamin.peterson | 2009-12-13 10:36:53 -0600 (Sun, 13 Dec 2009) | 2 lines fix the ignoring of __cmp__ method on metaclasses #7491 ........ 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 Sun Dec 13 17:41:44 2009 @@ -1198,6 +1198,15 @@ # This used to crash self.assertRaises(TypeError, MyABC.a.__set__, u, 3) + def test_metaclass_cmp(self): + # See bug 7491. + class M(type): + def __cmp__(self, other): + return -1 + class X(object): + __metaclass__ = M + self.assertTrue(X < M) + def test_dynamics(self): # Testing class attribute propagation... class D(object): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Dec 13 17:41:44 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #7491: Metaclass's __cmp__ method was ignored. + - Add Py3k warnings for parameter names in parenthesis. - Issue #7362: Give a proper error message for def f((x)=3): pass. Modified: python/branches/release26-maint/Objects/typeobject.c ============================================================================== --- python/branches/release26-maint/Objects/typeobject.c (original) +++ python/branches/release26-maint/Objects/typeobject.c Sun Dec 13 17:41:44 2009 @@ -645,7 +645,11 @@ int c; /* Make sure both arguments are types. */ - if (!PyType_Check(v) || !PyType_Check(w)) { + if (!PyType_Check(v) || !PyType_Check(w) || + /* If there is a __cmp__ method defined, let it be called instead + of our dumb function designed merely to warn. See bug + #7491. */ + Py_TYPE(v)->tp_compare || Py_TYPE(w)->tp_compare) { result = Py_NotImplemented; goto out; } From python-checkins at python.org Sun Dec 13 17:42:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 16:42:09 -0000 Subject: [Python-checkins] r76797 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Sun Dec 13 17:42:09 2009 New Revision: 76797 Log: Blocked revisions 76738 via svnmerge ........ r76738 | ronald.oussoren | 2009-12-10 04:27:09 -0600 (Thu, 10 Dec 2009) | 6 lines Fix an issue with the detection of a non-existing SDK on OSX. Without this patch it wasn't possible after all to compile extensions on OSX 10.6 with the binary installer unless the user had installed the (non-default) 10.4u SDK. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Dec 13 18:29:16 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 17:29:16 -0000 Subject: [Python-checkins] r76798 - in python/trunk/Lib: StringIO.py test/test_StringIO.py Message-ID: Author: benjamin.peterson Date: Sun Dec 13 18:29:16 2009 New Revision: 76798 Log: make StringIO like other file objects in that readline(-1) has no effect #7348 Modified: python/trunk/Lib/StringIO.py python/trunk/Lib/test/test_StringIO.py Modified: python/trunk/Lib/StringIO.py ============================================================================== --- python/trunk/Lib/StringIO.py (original) +++ python/trunk/Lib/StringIO.py Sun Dec 13 18:29:16 2009 @@ -158,7 +158,7 @@ newpos = self.len else: newpos = i+1 - if length is not None: + if length is not None and length > 0: if self.pos + length < newpos: newpos = self.pos + length r = self.buf[self.pos:newpos] Modified: python/trunk/Lib/test/test_StringIO.py ============================================================================== --- python/trunk/Lib/test/test_StringIO.py (original) +++ python/trunk/Lib/test/test_StringIO.py Sun Dec 13 18:29:16 2009 @@ -28,6 +28,8 @@ eq(self._fp.read(10), self._line[:10]) eq(self._fp.readline(), self._line[10:] + '\n') eq(len(self._fp.readlines(60)), 2) + self._fp.seek(0) + eq(self._fp.readline(-1), self._line + '\n') def test_writes(self): f = self.MODULE.StringIO() From python-checkins at python.org Sun Dec 13 18:31:31 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 17:31:31 -0000 Subject: [Python-checkins] r76799 - python/trunk/Misc/NEWS Message-ID: Author: benjamin.peterson Date: Sun Dec 13 18:31:31 2009 New Revision: 76799 Log: add NEWS note Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 13 18:31:31 2009 @@ -20,6 +20,9 @@ Library ------- +- Issue #7348: StringIO.StringIO.readline(-1) now acts as if it got no argument + like other file objects. + - Issue #7357: tarfile no longer suppresses fatal extraction errors by default. From python-checkins at python.org Sun Dec 13 18:32:59 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 17:32:59 -0000 Subject: [Python-checkins] r76800 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Sun Dec 13 18:32:59 2009 New Revision: 76800 Log: Blocked revisions 76798-76799 via svnmerge ........ r76798 | benjamin.peterson | 2009-12-13 11:29:16 -0600 (Sun, 13 Dec 2009) | 1 line make StringIO like other file objects in that readline(-1) has no effect #7348 ........ r76799 | benjamin.peterson | 2009-12-13 11:31:31 -0600 (Sun, 13 Dec 2009) | 1 line add NEWS note ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Dec 13 18:34:05 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 17:34:05 -0000 Subject: [Python-checkins] r76801 - in python/branches/release26-maint: Lib/StringIO.py Lib/test/test_StringIO.py Misc/NEWS Message-ID: Author: benjamin.peterson Date: Sun Dec 13 18:34:05 2009 New Revision: 76801 Log: Merged revisions 76798-76799 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76798 | benjamin.peterson | 2009-12-13 11:29:16 -0600 (Sun, 13 Dec 2009) | 1 line make StringIO like other file objects in that readline(-1) has no effect #7348 ........ r76799 | benjamin.peterson | 2009-12-13 11:31:31 -0600 (Sun, 13 Dec 2009) | 1 line add NEWS note ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/StringIO.py python/branches/release26-maint/Lib/test/test_StringIO.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/StringIO.py ============================================================================== --- python/branches/release26-maint/Lib/StringIO.py (original) +++ python/branches/release26-maint/Lib/StringIO.py Sun Dec 13 18:34:05 2009 @@ -158,7 +158,7 @@ newpos = self.len else: newpos = i+1 - if length is not None: + if length is not None and length > 0: if self.pos + length < newpos: newpos = self.pos + length r = self.buf[self.pos:newpos] Modified: python/branches/release26-maint/Lib/test/test_StringIO.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_StringIO.py (original) +++ python/branches/release26-maint/Lib/test/test_StringIO.py Sun Dec 13 18:34:05 2009 @@ -28,6 +28,8 @@ eq(self._fp.read(10), self._line[:10]) eq(self._fp.readline(), self._line[10:] + '\n') eq(len(self._fp.readlines(60)), 2) + self._fp.seek(0) + eq(self._fp.readline(-1), self._line + '\n') def test_writes(self): f = self.MODULE.StringIO() Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Dec 13 18:34:05 2009 @@ -35,6 +35,9 @@ Library ------- +- Issue #7348: StringIO.StringIO.readline(-1) now acts as if it got no argument + like other file objects. + - Issue #5949: fixed IMAP4_SSL hang when the IMAP server response is missing proper end-of-line termination. From python-checkins at python.org Sun Dec 13 18:49:34 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 13 Dec 2009 17:49:34 -0000 Subject: [Python-checkins] r76802 - python/branches/release31-maint Message-ID: Author: r.david.murray Date: Sun Dec 13 18:49:34 2009 New Revision: 76802 Log: Blocked revisions 73742,73820,73845,73878,73987,74099,74101 via svnmerge Note: All of these are descendants of the issue 6267 patch, which was an enhancement and thus not a backport candidate, even though it may have also contained a couple bug fixes. ........ r73742 | kristjan.jonsson | 2009-07-01 06:01:31 -0400 (Wed, 01 Jul 2009) | 2 lines http://bugs.python.org/issue6267 porting revision 73638 to py3k ........ r73820 | kristjan.jonsson | 2009-07-03 19:23:50 -0400 (Fri, 03 Jul 2009) | 2 lines http://bugs.python.org/issue6267 Incorrect exception handling for xmlrpclient retry ........ r73845 | kristjan.jonsson | 2009-07-04 11:18:00 -0400 (Sat, 04 Jul 2009) | 2 lines http://bugs.python.org/issue6381 merging revision 73819 from trunk ........ r73878 | kristjan.jonsson | 2009-07-07 05:09:10 -0400 (Tue, 07 Jul 2009) | 2 lines http://bugs.python.org/issue6382 added the shutdown_request() which can perform shutdown before calling close. This is needed for the ForkingMixIn because different close semantics are required for child and parent process. shutdown_request(), for TCP servers, calls socket.shutdown() and then calls close_request(). Therefore, this is not an backwards incompatible change, since subclasses that continue to override close_request() continue to work. ........ r73987 | kristjan.jonsson | 2009-07-12 18:45:18 -0400 (Sun, 12 Jul 2009) | 3 lines merging revision 73986 from trunk: http://bugs.python.org/issue6267 Add more tests for the xlmrpc.ServerProxy ........ r74099 | kristjan.jonsson | 2009-07-19 18:29:24 -0400 (Sun, 19 Jul 2009) | 4 lines porting revision 74098 from trunk: http://bugs.python.org/issue6499 zlib/gzip may not be present for all builds. Make xmlrpclib gracefully not supporg gzip encoding in this case ........ r74101 | kristjan.jonsson | 2009-07-19 18:38:38 -0400 (Sun, 19 Jul 2009) | 3 lines merging revision 74100 from trunk: http://bugs.python.org/issue6499 gzip.GzipFile may not exist as a parent class ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Dec 13 18:55:03 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 13 Dec 2009 17:55:03 -0000 Subject: [Python-checkins] r76803 - python/branches/release26-maint Message-ID: Author: r.david.murray Date: Sun Dec 13 18:55:03 2009 New Revision: 76803 Log: Blocked revisions 73819,73821-73822,73877,73986,74098,74100 via svnmerge All of these are descendants of the issue 6267 patch (r73638), which was an enhancement patch and thus blocked from backport (even though it may have contained a couple fixes...) ........ r73819 | kristjan.jonsson | 2009-07-03 19:07:07 -0400 (Fri, 03 Jul 2009) | 2 lines http://bugs.python.org/issue6381 some platforms may raise ENOTCONN if the stack has disconnected the socket on behalf of the peer. ........ r73821 | kristjan.jonsson | 2009-07-03 19:26:02 -0400 (Fri, 03 Jul 2009) | 2 lines http://bugs.python.org/issue6267 Incorrect exception handling for xmlrp client retry ........ r73822 | kristjan.jonsson | 2009-07-03 19:29:50 -0400 (Fri, 03 Jul 2009) | 2 lines http://bugs.python.org/issue6267 Incorrect exception handling for xmlrpc client retry ........ r73877 | kristjan.jonsson | 2009-07-07 05:01:34 -0400 (Tue, 07 Jul 2009) | 2 lines http://bugs.python.org/issue6382 added the shutdown_request() which can perform shutdown before calling close. This is needed for the ForkingMixIn because different close semantics are required for child and parent process. shutdown_request(), for TCP servers, calls socket.shutdown() and then calls close_request(). Therefore, this is not an backwards incompatible change, since subclasses that continue to override close_request() continue to work. ........ r73986 | kristjan.jonsson | 2009-07-12 18:42:08 -0400 (Sun, 12 Jul 2009) | 2 lines http://bugs.python.org/issue6267 Add more tests for the xlmrpc.ServerProxy ........ r74098 | kristjan.jonsson | 2009-07-19 18:14:00 -0400 (Sun, 19 Jul 2009) | 2 lines http://bugs.python.org/issue6499 zlib/gzip may not be present for all builds. Make xmlrpclib gracefully not supporg gzip encoding in this case ........ r74100 | kristjan.jonsson | 2009-07-19 18:35:44 -0400 (Sun, 19 Jul 2009) | 2 lines http://bugs.python.org/issue6499 gzip.GzipFile may not exist as a parent class ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 13 19:54:53 2009 From: python-checkins at python.org (ezio.melotti) Date: Sun, 13 Dec 2009 18:54:53 -0000 Subject: [Python-checkins] r76804 - python/trunk/Lib/test/test_strptime.py Message-ID: Author: ezio.melotti Date: Sun Dec 13 19:54:53 2009 New Revision: 76804 Log: #7342: make sure that the datetime object in test_fraction always has a number of microseconds != 0 Modified: python/trunk/Lib/test/test_strptime.py Modified: python/trunk/Lib/test/test_strptime.py ============================================================================== --- python/trunk/Lib/test/test_strptime.py (original) +++ python/trunk/Lib/test/test_strptime.py Sun Dec 13 19:54:53 2009 @@ -274,10 +274,11 @@ self.helper('S', 5) def test_fraction(self): + # Test microseconds import datetime - now = datetime.datetime.now() - tup, frac = _strptime._strptime(str(now), format="%Y-%m-%d %H:%M:%S.%f") - self.assertEqual(frac, now.microsecond) + d = datetime.datetime(2012, 12, 20, 12, 34, 56, 78987) + tup, frac = _strptime._strptime(str(d), format="%Y-%m-%d %H:%M:%S.%f") + self.assertEqual(frac, d.microsecond) def test_weekday(self): # Test weekday directives From python-checkins at python.org Sun Dec 13 20:19:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 19:19:09 -0000 Subject: [Python-checkins] r76805 - in python/trunk: Lib/test/test_fileio.py Lib/test/test_io.py Misc/NEWS Modules/_io/_iomodule.c Modules/_io/_iomodule.h Modules/_io/bufferedio.c Modules/_io/fileio.c Modules/_io/iobase.c Modules/_io/textio.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 20:19:07 2009 New Revision: 76805 Log: accept None as the same as having passed no argument in file types #7349 This is for consistency with imitation file objects like StringIO and BytesIO. This commit also adds a few tests, where they were lacking for concerned methods. Modified: python/trunk/Lib/test/test_fileio.py python/trunk/Lib/test/test_io.py python/trunk/Misc/NEWS python/trunk/Modules/_io/_iomodule.c python/trunk/Modules/_io/_iomodule.h python/trunk/Modules/_io/bufferedio.c python/trunk/Modules/_io/fileio.c python/trunk/Modules/_io/iobase.c python/trunk/Modules/_io/textio.c Modified: python/trunk/Lib/test/test_fileio.py ============================================================================== --- python/trunk/Lib/test/test_fileio.py (original) +++ python/trunk/Lib/test/test_fileio.py Sun Dec 13 20:19:07 2009 @@ -71,6 +71,15 @@ n = self.f.readinto(a) self.assertEquals(array(b'b', [1, 2]), a[:n]) + def test_none_args(self): + self.f.write(b"hi\nbye\nabc") + self.f.close() + self.f = _FileIO(TESTFN, 'r') + self.assertEqual(self.f.read(None), b"hi\nbye\nabc") + self.f.seek(0) + self.assertEqual(self.f.readline(None), b"hi\n") + self.assertEqual(self.f.readlines(None), [b"bye\n", b"abc"]) + def testRepr(self): self.assertEquals(repr(self.f), "<_io.FileIO name=%r mode='%s'>" % (self.f.name, self.f.mode)) Modified: python/trunk/Lib/test/test_io.py ============================================================================== --- python/trunk/Lib/test/test_io.py (original) +++ python/trunk/Lib/test/test_io.py Sun Dec 13 20:19:07 2009 @@ -341,7 +341,7 @@ 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.assertEqual(f.readline(None), 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) @@ -654,9 +654,10 @@ self.assertEquals(b"abc", bufio.read()) def test_read(self): - rawio = self.MockRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - self.assertEquals(b"abcdef", bufio.read(6)) + for arg in (None, 7): + rawio = self.MockRawIO((b"abc", b"d", b"efg")) + bufio = self.tp(rawio) + self.assertEquals(b"abcdefg", bufio.read(arg)) # Invalid args self.assertRaises(ValueError, bufio.read, -2) @@ -673,6 +674,7 @@ self.assertEquals(b"efg", bufio.read1(100)) self.assertEquals(rawio._reads, 3) self.assertEquals(b"", bufio.read1(100)) + self.assertEquals(rawio._reads, 4) # Invalid args self.assertRaises(ValueError, bufio.read1, -1) @@ -691,6 +693,14 @@ self.assertEquals(bufio.readinto(b), 0) self.assertEquals(b, b"gf") + def test_readlines(self): + def bufio(): + rawio = self.MockRawIO((b"abc\n", b"d\n", b"ef")) + return self.tp(rawio) + self.assertEquals(bufio().readlines(), [b"abc\n", b"d\n", b"ef"]) + self.assertEquals(bufio().readlines(5), [b"abc\n", b"d\n"]) + self.assertEquals(bufio().readlines(None), [b"abc\n", b"d\n", b"ef"]) + def test_buffering(self): data = b"abcdefghi" dlen = len(data) @@ -1131,6 +1141,14 @@ self.assertEqual(pair.read(3), b"abc") self.assertEqual(pair.read(1), b"d") self.assertEqual(pair.read(), b"ef") + pair = self.tp(self.BytesIO(b"abc"), self.MockRawIO()) + self.assertEqual(pair.read(None), b"abc") + + def test_readlines(self): + pair = lambda: self.tp(self.BytesIO(b"abc\ndef\nh"), self.MockRawIO()) + self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"]) + self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"]) + self.assertEqual(pair().readlines(5), [b"abc\n", b"def\n"]) def test_read1(self): # .read1() is delegated to the underlying reader object, so this test @@ -1781,6 +1799,8 @@ self.assertEquals(f.read(), "abc") cookie = f.tell() self.assertEquals(f.seek(0), 0) + self.assertEquals(f.read(None), "abc") + f.seek(0) self.assertEquals(f.read(2), "ab") self.assertEquals(f.read(1), "c") self.assertEquals(f.read(1), "") @@ -1951,6 +1971,14 @@ reads += c self.assertEquals(reads, "AA\nBB") + def test_readlines(self): + txt = self.TextIOWrapper(self.BytesIO(b"AA\nBB\nCC")) + self.assertEqual(txt.readlines(), ["AA\n", "BB\n", "CC"]) + txt.seek(0) + self.assertEqual(txt.readlines(None), ["AA\n", "BB\n", "CC"]) + txt.seek(0) + self.assertEqual(txt.readlines(5), ["AA\n", "BB\n"]) + # read in amounts equal to TextIOWrapper._CHUNK_SIZE which is 128. def test_read_by_chunk(self): # make sure "\r\n" straddles 128 char boundary. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 13 20:19:07 2009 @@ -20,6 +20,10 @@ Library ------- +- Issue #7349: Make methods of file objects in the io module accept None as an + argument where file-like objects (ie StringIO and BytesIO) accept them to mean + the same as passing no argument. + - Issue #7348: StringIO.StringIO.readline(-1) now acts as if it got no argument like other file objects. Modified: python/trunk/Modules/_io/_iomodule.c ============================================================================== --- python/trunk/Modules/_io/_iomodule.c (original) +++ python/trunk/Modules/_io/_iomodule.c Sun Dec 13 20:19:07 2009 @@ -573,6 +573,29 @@ } +/* Basically the "n" format code with the ability to turn None into -1. */ +int +_PyIO_ConvertSsize_t(PyObject *obj, void *result) { + Py_ssize_t limit; + if (obj == Py_None) { + limit = -1; + } + else if (PyNumber_Check(obj)) { + limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError); + if (limit == -1 && PyErr_Occurred()) + return 0; + } + else { + PyErr_Format(PyExc_TypeError, + "integer argument expected, got '%.200s'", + Py_TYPE(obj)->tp_name); + return 0; + } + *((Py_ssize_t *)result) = limit; + return 1; +} + + /* * Module definition */ Modified: python/trunk/Modules/_io/_iomodule.h ============================================================================== --- python/trunk/Modules/_io/_iomodule.h (original) +++ python/trunk/Modules/_io/_iomodule.h Sun Dec 13 20:19:07 2009 @@ -19,6 +19,9 @@ extern PyTypeObject PyTextIOWrapper_Type; extern PyTypeObject PyIncrementalNewlineDecoder_Type; + +extern int _PyIO_ConvertSsize_t(PyObject *, void *); + /* 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. Modified: python/trunk/Modules/_io/bufferedio.c ============================================================================== --- python/trunk/Modules/_io/bufferedio.c (original) +++ python/trunk/Modules/_io/bufferedio.c Sun Dec 13 20:19:07 2009 @@ -720,7 +720,7 @@ PyObject *res; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|n:read", &n)) { + if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) { return NULL; } if (n < -1) { @@ -950,25 +950,11 @@ static PyObject * buffered_readline(buffered *self, PyObject *args) { - PyObject *limitobj = NULL; Py_ssize_t limit = -1; CHECK_INITIALIZED(self) - - if (!PyArg_ParseTuple(args, "|O:readline", &limitobj)) { + if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) return NULL; - } - if (limitobj) { - if (!PyNumber_Check(limitobj)) { - PyErr_Format(PyExc_TypeError, - "integer argument expected, got '%.200s'", - Py_TYPE(limitobj)->tp_name); - return NULL; - } - limit = PyNumber_AsSsize_t(limitobj, PyExc_OverflowError); - if (limit == -1 && PyErr_Occurred()) - return NULL; - } return _buffered_readline(self, limit); } Modified: python/trunk/Modules/_io/fileio.c ============================================================================== --- python/trunk/Modules/_io/fileio.c (original) +++ python/trunk/Modules/_io/fileio.c Sun Dec 13 20:19:07 2009 @@ -599,7 +599,7 @@ if (!self->readable) return err_mode("reading"); - if (!PyArg_ParseTuple(args, "|n", &size)) + if (!PyArg_ParseTuple(args, "|O&", &_PyIO_ConvertSsize_t, &size)) return NULL; if (size < 0) { Modified: python/trunk/Modules/_io/iobase.c ============================================================================== --- python/trunk/Modules/_io/iobase.c (original) +++ python/trunk/Modules/_io/iobase.c Sun Dec 13 20:19:07 2009 @@ -455,7 +455,7 @@ PyObject *buffer, *result; Py_ssize_t old_size = -1; - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { + if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) { return NULL; } @@ -579,14 +579,9 @@ Py_ssize_t hint = -1, length = 0; PyObject *hintobj = Py_None, *result; - if (!PyArg_ParseTuple(args, "|O:readlines", &hintobj)) { + if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) { 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) Modified: python/trunk/Modules/_io/textio.c ============================================================================== --- python/trunk/Modules/_io/textio.c (original) +++ python/trunk/Modules/_io/textio.c Sun Dec 13 20:19:07 2009 @@ -1455,7 +1455,7 @@ CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|n:read", &n)) + if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) return NULL; CHECK_CLOSED(self); From python-checkins at python.org Sun Dec 13 20:25:34 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 19:25:34 -0000 Subject: [Python-checkins] r76806 - in python/branches/py3k: Lib/test/test_fileio.py Lib/test/test_io.py Misc/NEWS Modules/_io/_iomodule.c Modules/_io/_iomodule.h Modules/_io/bufferedio.c Modules/_io/fileio.c Modules/_io/iobase.c Modules/_io/textio.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 20:25:34 2009 New Revision: 76806 Log: Merged revisions 76805 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76805 | benjamin.peterson | 2009-12-13 13:19:07 -0600 (Sun, 13 Dec 2009) | 7 lines accept None as the same as having passed no argument in file types #7349 This is for consistency with imitation file objects like StringIO and BytesIO. This commit also adds a few tests, where they were lacking for concerned methods. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_fileio.py python/branches/py3k/Lib/test/test_io.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_io/_iomodule.c python/branches/py3k/Modules/_io/_iomodule.h python/branches/py3k/Modules/_io/bufferedio.c python/branches/py3k/Modules/_io/fileio.c python/branches/py3k/Modules/_io/iobase.c python/branches/py3k/Modules/_io/textio.c Modified: python/branches/py3k/Lib/test/test_fileio.py ============================================================================== --- python/branches/py3k/Lib/test/test_fileio.py (original) +++ python/branches/py3k/Lib/test/test_fileio.py Sun Dec 13 20:25:34 2009 @@ -69,6 +69,15 @@ n = self.f.readinto(a) self.assertEquals(array('b', [1, 2]), a[:n]) + def test_none_args(self): + self.f.write(b"hi\nbye\nabc") + self.f.close() + self.f = _FileIO(TESTFN, 'r') + self.assertEqual(self.f.read(None), b"hi\nbye\nabc") + self.f.seek(0) + self.assertEqual(self.f.readline(None), b"hi\n") + self.assertEqual(self.f.readlines(None), [b"bye\n", b"abc"]) + def testRepr(self): self.assertEquals(repr(self.f), "<_io.FileIO name=%r mode=%r>" % (self.f.name, self.f.mode)) 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 Dec 13 20:25:34 2009 @@ -336,7 +336,7 @@ 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.assertEqual(f.readline(None), 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) @@ -647,9 +647,10 @@ self.assertEquals(b"abc", bufio.read()) def test_read(self): - rawio = self.MockRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - self.assertEquals(b"abcdef", bufio.read(6)) + for arg in (None, 7): + rawio = self.MockRawIO((b"abc", b"d", b"efg")) + bufio = self.tp(rawio) + self.assertEquals(b"abcdefg", bufio.read(arg)) # Invalid args self.assertRaises(ValueError, bufio.read, -2) @@ -666,6 +667,7 @@ self.assertEquals(b"efg", bufio.read1(100)) self.assertEquals(rawio._reads, 3) self.assertEquals(b"", bufio.read1(100)) + self.assertEquals(rawio._reads, 4) # Invalid args self.assertRaises(ValueError, bufio.read1, -1) @@ -684,6 +686,14 @@ self.assertEquals(bufio.readinto(b), 0) self.assertEquals(b, b"gf") + def test_readlines(self): + def bufio(): + rawio = self.MockRawIO((b"abc\n", b"d\n", b"ef")) + return self.tp(rawio) + self.assertEquals(bufio().readlines(), [b"abc\n", b"d\n", b"ef"]) + self.assertEquals(bufio().readlines(5), [b"abc\n", b"d\n"]) + self.assertEquals(bufio().readlines(None), [b"abc\n", b"d\n", b"ef"]) + def test_buffering(self): data = b"abcdefghi" dlen = len(data) @@ -1123,6 +1133,14 @@ self.assertEqual(pair.read(3), b"abc") self.assertEqual(pair.read(1), b"d") self.assertEqual(pair.read(), b"ef") + pair = self.tp(self.BytesIO(b"abc"), self.MockRawIO()) + self.assertEqual(pair.read(None), b"abc") + + def test_readlines(self): + pair = lambda: self.tp(self.BytesIO(b"abc\ndef\nh"), self.MockRawIO()) + self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"]) + self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"]) + self.assertEqual(pair().readlines(5), [b"abc\n", b"def\n"]) def test_read1(self): # .read1() is delegated to the underlying reader object, so this test @@ -1773,6 +1791,8 @@ self.assertEquals(f.read(), "abc") cookie = f.tell() self.assertEquals(f.seek(0), 0) + self.assertEquals(f.read(None), "abc") + f.seek(0) self.assertEquals(f.read(2), "ab") self.assertEquals(f.read(1), "c") self.assertEquals(f.read(1), "") @@ -1943,6 +1963,14 @@ reads += c self.assertEquals(reads, "AA\nBB") + def test_readlines(self): + txt = self.TextIOWrapper(self.BytesIO(b"AA\nBB\nCC")) + self.assertEqual(txt.readlines(), ["AA\n", "BB\n", "CC"]) + txt.seek(0) + self.assertEqual(txt.readlines(None), ["AA\n", "BB\n", "CC"]) + txt.seek(0) + self.assertEqual(txt.readlines(5), ["AA\n", "BB\n"]) + # read in amounts equal to TextIOWrapper._CHUNK_SIZE which is 128. def test_read_by_chunk(self): # make sure "\r\n" straddles 128 char boundary. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Dec 13 20:25:34 2009 @@ -157,6 +157,10 @@ Library ------- +- Issue #7349: Make methods of file objects in the io module accept None as an + argument where file-like objects (ie StringIO and BytesIO) accept them to mean + the same as passing no argument. + - Issue #7357: tarfile no longer suppresses fatal extraction errors by default. Modified: python/branches/py3k/Modules/_io/_iomodule.c ============================================================================== --- python/branches/py3k/Modules/_io/_iomodule.c (original) +++ python/branches/py3k/Modules/_io/_iomodule.c Sun Dec 13 20:25:34 2009 @@ -561,6 +561,30 @@ return result; } + +/* Basically the "n" format code with the ability to turn None into -1. */ +int +_PyIO_ConvertSsize_t(PyObject *obj, void *result) { + Py_ssize_t limit; + if (obj == Py_None) { + limit = -1; + } + else if (PyNumber_Check(obj)) { + limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError); + if (limit == -1 && PyErr_Occurred()) + return 0; + } + else { + PyErr_Format(PyExc_TypeError, + "integer argument expected, got '%.200s'", + Py_TYPE(obj)->tp_name); + return 0; + } + *((Py_ssize_t *)result) = limit; + return 1; +} + + static int iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { _PyIO_State *state = IO_MOD_STATE(mod); @@ -574,6 +598,7 @@ return 0; } + static int iomodule_clear(PyObject *mod) { _PyIO_State *state = IO_MOD_STATE(mod); @@ -591,6 +616,7 @@ iomodule_clear(mod); } + /* * Module definition */ Modified: python/branches/py3k/Modules/_io/_iomodule.h ============================================================================== --- python/branches/py3k/Modules/_io/_iomodule.h (original) +++ python/branches/py3k/Modules/_io/_iomodule.h Sun Dec 13 20:25:34 2009 @@ -19,6 +19,9 @@ extern PyTypeObject PyTextIOWrapper_Type; extern PyTypeObject PyIncrementalNewlineDecoder_Type; + +extern int _PyIO_ConvertSsize_t(PyObject *, void *); + /* 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. Modified: python/branches/py3k/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k/Modules/_io/bufferedio.c (original) +++ python/branches/py3k/Modules/_io/bufferedio.c Sun Dec 13 20:25:34 2009 @@ -720,7 +720,7 @@ PyObject *res; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|n:read", &n)) { + if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) { return NULL; } if (n < -1) { @@ -953,10 +953,8 @@ Py_ssize_t limit = -1; CHECK_INITIALIZED(self) - - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { + if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) return NULL; - } return _buffered_readline(self, limit); } Modified: python/branches/py3k/Modules/_io/fileio.c ============================================================================== --- python/branches/py3k/Modules/_io/fileio.c (original) +++ python/branches/py3k/Modules/_io/fileio.c Sun Dec 13 20:25:34 2009 @@ -599,7 +599,7 @@ if (!self->readable) return err_mode("reading"); - if (!PyArg_ParseTuple(args, "|n", &size)) + if (!PyArg_ParseTuple(args, "|O&", &_PyIO_ConvertSsize_t, &size)) return NULL; if (size < 0) { Modified: python/branches/py3k/Modules/_io/iobase.c ============================================================================== --- python/branches/py3k/Modules/_io/iobase.c (original) +++ python/branches/py3k/Modules/_io/iobase.c Sun Dec 13 20:25:34 2009 @@ -455,7 +455,7 @@ PyObject *buffer, *result; Py_ssize_t old_size = -1; - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { + if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) { return NULL; } @@ -579,14 +579,9 @@ Py_ssize_t hint = -1, length = 0; PyObject *hintobj = Py_None, *result; - if (!PyArg_ParseTuple(args, "|O:readlines", &hintobj)) { + if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) { 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) Modified: python/branches/py3k/Modules/_io/textio.c ============================================================================== --- python/branches/py3k/Modules/_io/textio.c (original) +++ python/branches/py3k/Modules/_io/textio.c Sun Dec 13 20:25:34 2009 @@ -1479,7 +1479,7 @@ CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|n:read", &n)) + if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) return NULL; CHECK_CLOSED(self); From python-checkins at python.org Sun Dec 13 20:27:02 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 19:27:02 -0000 Subject: [Python-checkins] r76807 - python/trunk/Modules/_io/iobase.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 20:27:02 2009 New Revision: 76807 Log: remove unused variable Modified: python/trunk/Modules/_io/iobase.c Modified: python/trunk/Modules/_io/iobase.c ============================================================================== --- python/trunk/Modules/_io/iobase.c (original) +++ python/trunk/Modules/_io/iobase.c Sun Dec 13 20:27:02 2009 @@ -577,7 +577,7 @@ iobase_readlines(PyObject *self, PyObject *args) { Py_ssize_t hint = -1, length = 0; - PyObject *hintobj = Py_None, *result; + PyObject *result; if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) { return NULL; From python-checkins at python.org Sun Dec 13 20:28:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 19:28:09 -0000 Subject: [Python-checkins] r76808 - in python/branches/py3k: Modules/_io/iobase.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 20:28:09 2009 New Revision: 76808 Log: Merged revisions 76807 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76807 | benjamin.peterson | 2009-12-13 13:27:02 -0600 (Sun, 13 Dec 2009) | 1 line remove unused variable ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_io/iobase.c Modified: python/branches/py3k/Modules/_io/iobase.c ============================================================================== --- python/branches/py3k/Modules/_io/iobase.c (original) +++ python/branches/py3k/Modules/_io/iobase.c Sun Dec 13 20:28:09 2009 @@ -577,7 +577,7 @@ iobase_readlines(PyObject *self, PyObject *args) { Py_ssize_t hint = -1, length = 0; - PyObject *hintobj = Py_None, *result; + PyObject *result; if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) { return NULL; From python-checkins at python.org Sun Dec 13 20:30:15 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 19:30:15 -0000 Subject: [Python-checkins] r76809 - in python/branches/release31-maint: Lib/test/test_fileio.py Lib/test/test_io.py Misc/NEWS Modules/_io/_iomodule.c Modules/_io/_iomodule.h Modules/_io/bufferedio.c Modules/_io/fileio.c Modules/_io/iobase.c Modules/_io/textio.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 20:30:15 2009 New Revision: 76809 Log: Merged revisions 76806,76808 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76806 | benjamin.peterson | 2009-12-13 13:25:34 -0600 (Sun, 13 Dec 2009) | 14 lines Merged revisions 76805 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76805 | benjamin.peterson | 2009-12-13 13:19:07 -0600 (Sun, 13 Dec 2009) | 7 lines accept None as the same as having passed no argument in file types #7349 This is for consistency with imitation file objects like StringIO and BytesIO. This commit also adds a few tests, where they were lacking for concerned methods. ........ ................ r76808 | benjamin.peterson | 2009-12-13 13:28:09 -0600 (Sun, 13 Dec 2009) | 9 lines Merged revisions 76807 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76807 | benjamin.peterson | 2009-12-13 13:27:02 -0600 (Sun, 13 Dec 2009) | 1 line remove unused variable ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_fileio.py python/branches/release31-maint/Lib/test/test_io.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/_io/_iomodule.c python/branches/release31-maint/Modules/_io/_iomodule.h python/branches/release31-maint/Modules/_io/bufferedio.c python/branches/release31-maint/Modules/_io/fileio.c python/branches/release31-maint/Modules/_io/iobase.c python/branches/release31-maint/Modules/_io/textio.c Modified: python/branches/release31-maint/Lib/test/test_fileio.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_fileio.py (original) +++ python/branches/release31-maint/Lib/test/test_fileio.py Sun Dec 13 20:30:15 2009 @@ -69,6 +69,15 @@ n = self.f.readinto(a) self.assertEquals(array('b', [1, 2]), a[:n]) + def test_none_args(self): + self.f.write(b"hi\nbye\nabc") + self.f.close() + self.f = _FileIO(TESTFN, 'r') + self.assertEqual(self.f.read(None), b"hi\nbye\nabc") + self.f.seek(0) + self.assertEqual(self.f.readline(None), b"hi\n") + self.assertEqual(self.f.readlines(None), [b"bye\n", b"abc"]) + def testRepr(self): self.assertEquals(repr(self.f), "<_io.FileIO name=%r mode=%r>" % (self.f.name, self.f.mode)) Modified: python/branches/release31-maint/Lib/test/test_io.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_io.py (original) +++ python/branches/release31-maint/Lib/test/test_io.py Sun Dec 13 20:30:15 2009 @@ -336,7 +336,7 @@ 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.assertEqual(f.readline(None), 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) @@ -647,9 +647,10 @@ self.assertEquals(b"abc", bufio.read()) def test_read(self): - rawio = self.MockRawIO((b"abc", b"d", b"efg")) - bufio = self.tp(rawio) - self.assertEquals(b"abcdef", bufio.read(6)) + for arg in (None, 7): + rawio = self.MockRawIO((b"abc", b"d", b"efg")) + bufio = self.tp(rawio) + self.assertEquals(b"abcdefg", bufio.read(arg)) # Invalid args self.assertRaises(ValueError, bufio.read, -2) @@ -666,6 +667,7 @@ self.assertEquals(b"efg", bufio.read1(100)) self.assertEquals(rawio._reads, 3) self.assertEquals(b"", bufio.read1(100)) + self.assertEquals(rawio._reads, 4) # Invalid args self.assertRaises(ValueError, bufio.read1, -1) @@ -684,6 +686,14 @@ self.assertEquals(bufio.readinto(b), 0) self.assertEquals(b, b"gf") + def test_readlines(self): + def bufio(): + rawio = self.MockRawIO((b"abc\n", b"d\n", b"ef")) + return self.tp(rawio) + self.assertEquals(bufio().readlines(), [b"abc\n", b"d\n", b"ef"]) + self.assertEquals(bufio().readlines(5), [b"abc\n", b"d\n"]) + self.assertEquals(bufio().readlines(None), [b"abc\n", b"d\n", b"ef"]) + def test_buffering(self): data = b"abcdefghi" dlen = len(data) @@ -1123,6 +1133,14 @@ self.assertEqual(pair.read(3), b"abc") self.assertEqual(pair.read(1), b"d") self.assertEqual(pair.read(), b"ef") + pair = self.tp(self.BytesIO(b"abc"), self.MockRawIO()) + self.assertEqual(pair.read(None), b"abc") + + def test_readlines(self): + pair = lambda: self.tp(self.BytesIO(b"abc\ndef\nh"), self.MockRawIO()) + self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"]) + self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"]) + self.assertEqual(pair().readlines(5), [b"abc\n", b"def\n"]) def test_read1(self): # .read1() is delegated to the underlying reader object, so this test @@ -1773,6 +1791,8 @@ self.assertEquals(f.read(), "abc") cookie = f.tell() self.assertEquals(f.seek(0), 0) + self.assertEquals(f.read(None), "abc") + f.seek(0) self.assertEquals(f.read(2), "ab") self.assertEquals(f.read(1), "c") self.assertEquals(f.read(1), "") @@ -1943,6 +1963,14 @@ reads += c self.assertEquals(reads, "AA\nBB") + def test_readlines(self): + txt = self.TextIOWrapper(self.BytesIO(b"AA\nBB\nCC")) + self.assertEqual(txt.readlines(), ["AA\n", "BB\n", "CC"]) + txt.seek(0) + self.assertEqual(txt.readlines(None), ["AA\n", "BB\n", "CC"]) + txt.seek(0) + self.assertEqual(txt.readlines(5), ["AA\n", "BB\n"]) + # read in amounts equal to TextIOWrapper._CHUNK_SIZE which is 128. def test_read_by_chunk(self): # make sure "\r\n" straddles 128 char boundary. Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Dec 13 20:30:15 2009 @@ -58,6 +58,10 @@ Library ------- +- Issue #7349: Make methods of file objects in the io module accept None as an + argument where file-like objects (ie StringIO and BytesIO) accept them to mean + the same as passing no argument. + - Issue #5949: added check for correct lineends in input from IMAP server in imaplib. Modified: python/branches/release31-maint/Modules/_io/_iomodule.c ============================================================================== --- python/branches/release31-maint/Modules/_io/_iomodule.c (original) +++ python/branches/release31-maint/Modules/_io/_iomodule.c Sun Dec 13 20:30:15 2009 @@ -561,6 +561,30 @@ return result; } + +/* Basically the "n" format code with the ability to turn None into -1. */ +int +_PyIO_ConvertSsize_t(PyObject *obj, void *result) { + Py_ssize_t limit; + if (obj == Py_None) { + limit = -1; + } + else if (PyNumber_Check(obj)) { + limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError); + if (limit == -1 && PyErr_Occurred()) + return 0; + } + else { + PyErr_Format(PyExc_TypeError, + "integer argument expected, got '%.200s'", + Py_TYPE(obj)->tp_name); + return 0; + } + *((Py_ssize_t *)result) = limit; + return 1; +} + + static int iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { _PyIO_State *state = IO_MOD_STATE(mod); @@ -574,6 +598,7 @@ return 0; } + static int iomodule_clear(PyObject *mod) { _PyIO_State *state = IO_MOD_STATE(mod); @@ -591,6 +616,7 @@ iomodule_clear(mod); } + /* * Module definition */ Modified: python/branches/release31-maint/Modules/_io/_iomodule.h ============================================================================== --- python/branches/release31-maint/Modules/_io/_iomodule.h (original) +++ python/branches/release31-maint/Modules/_io/_iomodule.h Sun Dec 13 20:30:15 2009 @@ -19,6 +19,9 @@ extern PyTypeObject PyTextIOWrapper_Type; extern PyTypeObject PyIncrementalNewlineDecoder_Type; + +extern int _PyIO_ConvertSsize_t(PyObject *, void *); + /* 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. Modified: python/branches/release31-maint/Modules/_io/bufferedio.c ============================================================================== --- python/branches/release31-maint/Modules/_io/bufferedio.c (original) +++ python/branches/release31-maint/Modules/_io/bufferedio.c Sun Dec 13 20:30:15 2009 @@ -716,7 +716,7 @@ PyObject *res; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|n:read", &n)) { + if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) { return NULL; } if (n < -1) { @@ -949,10 +949,8 @@ Py_ssize_t limit = -1; CHECK_INITIALIZED(self) - - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { + if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) return NULL; - } return _buffered_readline(self, limit); } Modified: python/branches/release31-maint/Modules/_io/fileio.c ============================================================================== --- python/branches/release31-maint/Modules/_io/fileio.c (original) +++ python/branches/release31-maint/Modules/_io/fileio.c Sun Dec 13 20:30:15 2009 @@ -602,7 +602,7 @@ if (!self->readable) return err_mode("reading"); - if (!PyArg_ParseTuple(args, "|n", &size)) + if (!PyArg_ParseTuple(args, "|O&", &_PyIO_ConvertSsize_t, &size)) return NULL; if (size < 0) { Modified: python/branches/release31-maint/Modules/_io/iobase.c ============================================================================== --- python/branches/release31-maint/Modules/_io/iobase.c (original) +++ python/branches/release31-maint/Modules/_io/iobase.c Sun Dec 13 20:30:15 2009 @@ -455,7 +455,7 @@ PyObject *buffer, *result; Py_ssize_t old_size = -1; - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { + if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) { return NULL; } @@ -577,16 +577,11 @@ iobase_readlines(PyObject *self, PyObject *args) { Py_ssize_t hint = -1, length = 0; - PyObject *hintobj = Py_None, *result; + PyObject *result; - if (!PyArg_ParseTuple(args, "|O:readlines", &hintobj)) { + if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) { 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) Modified: python/branches/release31-maint/Modules/_io/textio.c ============================================================================== --- python/branches/release31-maint/Modules/_io/textio.c (original) +++ python/branches/release31-maint/Modules/_io/textio.c Sun Dec 13 20:30:15 2009 @@ -1479,7 +1479,7 @@ CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|n:read", &n)) + if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) return NULL; CHECK_CLOSED(self); From python-checkins at python.org Sun Dec 13 21:03:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Dec 2009 20:03:21 -0000 Subject: [Python-checkins] r76810 - python/branches/py3k/Modules/_testcapimodule.c Message-ID: Author: mark.dickinson Date: Sun Dec 13 21:03:21 2009 New Revision: 76810 Log: Make sure that test_capsule always returns NULL on error; this may help diagnose the sporadic test_capi failures on Solaris. Modified: python/branches/py3k/Modules/_testcapimodule.c Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Sun Dec 13 21:03:21 2009 @@ -1298,6 +1298,21 @@ if (error) { return raiseTestError("test_capsule", error); } + /* 13/12/2009: something is causing test_capi to fail occasionally on + the Solaris buildbot, with the output: + + internal test_L_code + internal test_Z_code + internal test_bug_7414 + internal test_capsule + XXX undetected error + internaltest test_capi crashed -- : No module named datetime + + It seems possible that test_capsule is raising an exception but + failing to return NULL. Do a PyErr_Occurred check to find out. + */ + if (PyErr_Occurred()) + return NULL; Py_RETURN_NONE; #undef FAIL } From python-checkins at python.org Sun Dec 13 21:04:14 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Dec 2009 20:04:14 -0000 Subject: [Python-checkins] r76811 - in python/branches/release31-maint: Modules/_testcapimodule.c Message-ID: Author: mark.dickinson Date: Sun Dec 13 21:04:13 2009 New Revision: 76811 Log: Merged revisions 76810 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76810 | mark.dickinson | 2009-12-13 20:03:21 +0000 (Sun, 13 Dec 2009) | 4 lines Make sure that test_capsule always returns NULL on error; this may help diagnose the sporadic test_capi failures on Solaris. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Modules/_testcapimodule.c Modified: python/branches/release31-maint/Modules/_testcapimodule.c ============================================================================== --- python/branches/release31-maint/Modules/_testcapimodule.c (original) +++ python/branches/release31-maint/Modules/_testcapimodule.c Sun Dec 13 21:04:13 2009 @@ -1293,6 +1293,21 @@ if (error) { return raiseTestError("test_capsule", error); } + /* 13/12/2009: something is causing test_capi to fail occasionally on + the Solaris buildbot, with the output: + + internal test_L_code + internal test_Z_code + internal test_bug_7414 + internal test_capsule + XXX undetected error + internaltest test_capi crashed -- : No module named datetime + + It seems possible that test_capsule is raising an exception but + failing to return NULL. Do a PyErr_Occurred check to find out. + */ + if (PyErr_Occurred()) + return NULL; Py_RETURN_NONE; #undef FAIL } From python-checkins at python.org Sun Dec 13 22:04:16 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 21:04:16 -0000 Subject: [Python-checkins] r76812 - in python/branches/py3k/Doc/library: copyreg.rst shelve.rst Message-ID: Author: benjamin.peterson Date: Sun Dec 13 22:04:16 2009 New Revision: 76812 Log: remove references to cPickle Modified: python/branches/py3k/Doc/library/copyreg.rst python/branches/py3k/Doc/library/shelve.rst Modified: python/branches/py3k/Doc/library/copyreg.rst ============================================================================== --- python/branches/py3k/Doc/library/copyreg.rst (original) +++ python/branches/py3k/Doc/library/copyreg.rst Sun Dec 13 22:04:16 2009 @@ -7,14 +7,12 @@ .. index:: module: pickle - module: cPickle module: copy -The :mod:`copyreg` module provides support for the :mod:`pickle` and -:mod:`cPickle` modules. The :mod:`copy` module is likely to use this in the -future as well. It provides configuration information about object constructors -which are not classes. Such constructors may be factory functions or class -instances. +The :mod:`copyreg` module provides support for the :mod:`pickle` module. The +:mod:`copy` module is likely to use this in the future as well. It provides +configuration information about object constructors which are not classes. +Such constructors may be factory functions or class instances. .. function:: constructor(object) Modified: python/branches/py3k/Doc/library/shelve.rst ============================================================================== --- python/branches/py3k/Doc/library/shelve.rst (original) +++ python/branches/py3k/Doc/library/shelve.rst Sun Dec 13 22:04:16 2009 @@ -175,6 +175,3 @@ Module :mod:`pickle` Object serialization used by :mod:`shelve`. - Module :mod:`cPickle` - High-performance version of :mod:`pickle`. - From python-checkins at python.org Sun Dec 13 22:06:06 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Dec 2009 21:06:06 -0000 Subject: [Python-checkins] r76813 - in python/trunk: configure configure.in Message-ID: Author: mark.dickinson Date: Sun Dec 13 22:06:06 2009 New Revision: 76813 Log: Issue #7492: Autoconf tests were leaving semaphore files behind. Add sem_unlink calls to delete those semaphore files. Modified: python/trunk/configure python/trunk/configure.in Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Sun Dec 13 22:06:06 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76636 . +# From configure.in Revision: 76644 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -24474,6 +24474,7 @@ return 1; } sem_close(a); + sem_unlink("/autoconf"); return 0; } @@ -24548,7 +24549,7 @@ #include int main(void){ - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); int count; int res; if(a==SEM_FAILED){ @@ -24558,6 +24559,7 @@ } res = sem_getvalue(a, &count); sem_close(a); + sem_unlink("/autocftw"); return res==-1 ? 1 : 0; } Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Sun Dec 13 22:06:06 2009 @@ -3455,6 +3455,7 @@ return 1; } sem_close(a); + sem_unlink("/autoconf"); return 0; } ], ac_cv_posix_semaphores_enabled=yes, @@ -3479,7 +3480,7 @@ #include int main(void){ - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); int count; int res; if(a==SEM_FAILED){ @@ -3489,6 +3490,7 @@ } res = sem_getvalue(a, &count); sem_close(a); + sem_unlink("/autocftw"); return res==-1 ? 1 : 0; } ], ac_cv_broken_sem_getvalue=no, From python-checkins at python.org Sun Dec 13 22:06:19 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 21:06:19 -0000 Subject: [Python-checkins] r76814 - in python/branches/release31-maint: Doc/library/copyreg.rst Doc/library/shelve.rst Message-ID: Author: benjamin.peterson Date: Sun Dec 13 22:06:19 2009 New Revision: 76814 Log: Merged revisions 76812 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76812 | benjamin.peterson | 2009-12-13 15:04:16 -0600 (Sun, 13 Dec 2009) | 1 line remove references to cPickle ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/copyreg.rst python/branches/release31-maint/Doc/library/shelve.rst Modified: python/branches/release31-maint/Doc/library/copyreg.rst ============================================================================== --- python/branches/release31-maint/Doc/library/copyreg.rst (original) +++ python/branches/release31-maint/Doc/library/copyreg.rst Sun Dec 13 22:06:19 2009 @@ -7,14 +7,12 @@ .. index:: module: pickle - module: cPickle module: copy -The :mod:`copyreg` module provides support for the :mod:`pickle` and -:mod:`cPickle` modules. The :mod:`copy` module is likely to use this in the -future as well. It provides configuration information about object constructors -which are not classes. Such constructors may be factory functions or class -instances. +The :mod:`copyreg` module provides support for the :mod:`pickle` module. The +:mod:`copy` module is likely to use this in the future as well. It provides +configuration information about object constructors which are not classes. +Such constructors may be factory functions or class instances. .. function:: constructor(object) Modified: python/branches/release31-maint/Doc/library/shelve.rst ============================================================================== --- python/branches/release31-maint/Doc/library/shelve.rst (original) +++ python/branches/release31-maint/Doc/library/shelve.rst Sun Dec 13 22:06:19 2009 @@ -175,6 +175,3 @@ Module :mod:`pickle` Object serialization used by :mod:`shelve`. - Module :mod:`cPickle` - High-performance version of :mod:`pickle`. - From python-checkins at python.org Sun Dec 13 22:10:57 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Dec 2009 21:10:57 -0000 Subject: [Python-checkins] r76815 - in python/branches/py3k: configure configure.in Message-ID: Author: mark.dickinson Date: Sun Dec 13 22:10:57 2009 New Revision: 76815 Log: Merged revisions 76813 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76813 | mark.dickinson | 2009-12-13 21:06:06 +0000 (Sun, 13 Dec 2009) | 3 lines Issue #7492: Autoconf tests were leaving semaphore files behind. Add sem_unlink calls to delete those semaphore files. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/configure python/branches/py3k/configure.in Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sun Dec 13 22:10:57 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76645 . +# From configure.in Revision: 76779 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -23782,6 +23782,7 @@ return 1; } sem_close(a); + sem_unlink("/autoconf"); return 0; } @@ -23856,7 +23857,7 @@ #include int main(void){ - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); int count; int res; if(a==SEM_FAILED){ @@ -23866,6 +23867,7 @@ } res = sem_getvalue(a, &count); sem_close(a); + sem_unlink("/autocftw"); return res==-1 ? 1 : 0; } Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sun Dec 13 22:10:57 2009 @@ -3324,6 +3324,7 @@ return 1; } sem_close(a); + sem_unlink("/autoconf"); return 0; } ], ac_cv_posix_semaphores_enabled=yes, @@ -3348,7 +3349,7 @@ #include int main(void){ - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); int count; int res; if(a==SEM_FAILED){ @@ -3358,6 +3359,7 @@ } res = sem_getvalue(a, &count); sem_close(a); + sem_unlink("/autocftw"); return res==-1 ? 1 : 0; } ], ac_cv_broken_sem_getvalue=no, From python-checkins at python.org Sun Dec 13 22:11:54 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Dec 2009 21:11:54 -0000 Subject: [Python-checkins] r76816 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sun Dec 13 22:11:53 2009 New Revision: 76816 Log: Blocked revisions 76813 via svnmerge ........ r76813 | mark.dickinson | 2009-12-13 21:06:06 +0000 (Sun, 13 Dec 2009) | 3 lines Issue #7492: Autoconf tests were leaving semaphore files behind. Add sem_unlink calls to delete those semaphore files. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 13 22:12:29 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Dec 2009 21:12:29 -0000 Subject: [Python-checkins] r76817 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Dec 13 22:12:29 2009 New Revision: 76817 Log: Blocked revisions 76815 via svnmerge ................ r76815 | mark.dickinson | 2009-12-13 21:10:57 +0000 (Sun, 13 Dec 2009) | 10 lines Merged revisions 76813 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76813 | mark.dickinson | 2009-12-13 21:06:06 +0000 (Sun, 13 Dec 2009) | 3 lines Issue #7492: Autoconf tests were leaving semaphore files behind. Add sem_unlink calls to delete those semaphore files. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Dec 13 22:13:20 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Dec 2009 21:13:20 -0000 Subject: [Python-checkins] r76818 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Dec 13 22:13:19 2009 New Revision: 76818 Log: Unblocked revisions 76815 via svnmerge ................ r76815 | mark.dickinson | 2009-12-13 21:10:57 +0000 (Sun, 13 Dec 2009) | 10 lines Merged revisions 76813 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76813 | mark.dickinson | 2009-12-13 21:06:06 +0000 (Sun, 13 Dec 2009) | 3 lines Issue #7492: Autoconf tests were leaving semaphore files behind. Add sem_unlink calls to delete those semaphore files. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Dec 13 22:15:32 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 21:15:32 -0000 Subject: [Python-checkins] r76819 - python/trunk/Doc/faq/general.rst Message-ID: Author: benjamin.peterson Date: Sun Dec 13 22:15:31 2009 New Revision: 76819 Log: avoid having to update this statement all the time Modified: python/trunk/Doc/faq/general.rst Modified: python/trunk/Doc/faq/general.rst ============================================================================== --- python/trunk/Doc/faq/general.rst (original) +++ python/trunk/Doc/faq/general.rst Sun Dec 13 22:15:31 2009 @@ -309,13 +309,12 @@ guaranteed that interfaces will remain the same throughout a series of bugfix releases. -.. XXX this gets out of date pretty often - -The `2.6.4 release `_ is recommended -production-ready version at this point in time. Python 3.1 is also considered -production-ready, but may be less useful, since currently there is more third -party software available for Python 2 than for Python 3. Python 2 code will -generally not run unchanged in Python 3. +The latest stable releases can always be found on the `Python download page +`_. They are recommended production-ready version +at this point in time. At the moment, there are two branches of stable +releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since currently +there is more third party software available for Python 2 than for Python 3. +Python 2 code will generally not run unchanged in Python 3. How many people are using Python? From python-checkins at python.org Sun Dec 13 22:15:41 2009 From: python-checkins at python.org (brett.cannon) Date: Sun, 13 Dec 2009 21:15:41 -0000 Subject: [Python-checkins] r76820 - python/branches/py3k/Mac/README Message-ID: Author: brett.cannon Date: Sun Dec 13 22:15:41 2009 New Revision: 76820 Log: Make the example paths in Mac/README no longer directly refer to 2.6. Modified: python/branches/py3k/Mac/README Modified: python/branches/py3k/Mac/README ============================================================================== --- python/branches/py3k/Mac/README (original) +++ python/branches/py3k/Mac/README Sun Dec 13 22:15:41 2009 @@ -48,7 +48,8 @@ A second reason for using frameworks is that they put Python-related items in only two places: "/Library/Framework/Python.framework" and -"/Applications/MacPython 2.6". This simplifies matters for users installing +"/Applications/MacPython " where ```` can be e.g. "2.6", +"3.1", etc.. This simplifies matters for users installing Python from a binary distribution if they want to get rid of it again. Moreover, due to the way frameworks work a user without admin privileges can install a binary distribution in his or her home directory without recompilation. @@ -75,7 +76,7 @@ This directory contains a Makefile that will create a couple of python-related applications (fullblown OSX .app applications, that is) in -"/Applications/MacPython 2.6", and a hidden helper application Python.app +"/Applications/MacPython ", and a hidden helper application Python.app inside the Python.framework, and unix tools "python" and "pythonw" into /usr/local/bin. In addition it has a target "installmacsubtree" that installs the relevant portions of the Mac subtree into the Python.framework. @@ -90,16 +91,16 @@ 3. make install This sequence will put the framework in /Library/Framework/Python.framework, -the applications in "/Applications/MacPython 2.6" and the unix tools in +the applications in "/Applications/MacPython " and the unix tools in /usr/local/bin. Installing in another place, for instance $HOME/Library/Frameworks if you have no admin privileges on your machine, has only been tested very lightly. This can be done by configuring with --enable-framework=$HOME/Library/Frameworks. -The other two directories, "/Applications/MacPython-2.6" and /usr/local/bin, -will then also be deposited in $HOME. This is sub-optimal for the unix tools, -which you would want in $HOME/bin, but there is no easy way to fix this right -now. +The other two directories, "/Applications/MacPython-" and +/usr/local/bin, will then also be deposited in $HOME. This is sub-optimal for +the unix tools, which you would want in $HOME/bin, but there is no easy way to +fix this right now. If you want to install some part, but not all, read the main Makefile. The frameworkinstall is composed of a couple of sub-targets that install the @@ -107,7 +108,8 @@ There is an extra target frameworkinstallextras that is not part of the normal frameworkinstall which installs the Demo and Tools directories -into "/Applications/MacPython 2.6", this is useful for binary distributions. +into "/Applications/MacPython ", this is useful for binary +distributions. What do all these programs do? =============================== From python-checkins at python.org Sun Dec 13 22:18:16 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Dec 2009 21:18:16 -0000 Subject: [Python-checkins] r76821 - in python/branches/release31-maint: configure configure.in Message-ID: Author: mark.dickinson Date: Sun Dec 13 22:18:16 2009 New Revision: 76821 Log: Merged revisions 76815 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76815 | mark.dickinson | 2009-12-13 21:10:57 +0000 (Sun, 13 Dec 2009) | 10 lines Merged revisions 76813 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76813 | mark.dickinson | 2009-12-13 21:06:06 +0000 (Sun, 13 Dec 2009) | 3 lines Issue #7492: Autoconf tests were leaving semaphore files behind. Add sem_unlink calls to delete those semaphore files. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/configure python/branches/release31-maint/configure.in Modified: python/branches/release31-maint/configure ============================================================================== --- python/branches/release31-maint/configure (original) +++ python/branches/release31-maint/configure Sun Dec 13 22:18:16 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76406 . +# From configure.in Revision: 76567 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -22564,6 +22564,7 @@ return 1; } sem_close(a); + sem_unlink("/autoconf"); return 0; } @@ -22639,7 +22640,7 @@ #include int main(void){ - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); int count; int res; if(a==SEM_FAILED){ @@ -22649,6 +22650,7 @@ } res = sem_getvalue(a, &count); sem_close(a); + sem_unlink("/autocftw"); return res==-1 ? 1 : 0; } Modified: python/branches/release31-maint/configure.in ============================================================================== --- python/branches/release31-maint/configure.in (original) +++ python/branches/release31-maint/configure.in Sun Dec 13 22:18:16 2009 @@ -3359,6 +3359,7 @@ return 1; } sem_close(a); + sem_unlink("/autoconf"); return 0; } ], ac_cv_posix_semaphores_enabled=yes, @@ -3382,7 +3383,7 @@ #include int main(void){ - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); int count; int res; if(a==SEM_FAILED){ @@ -3392,6 +3393,7 @@ } res = sem_getvalue(a, &count); sem_close(a); + sem_unlink("/autocftw"); return res==-1 ? 1 : 0; } ] From python-checkins at python.org Sun Dec 13 22:21:43 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 21:21:43 -0000 Subject: [Python-checkins] r76822 - python/trunk/Include/datetime.h Message-ID: Author: benjamin.peterson Date: Sun Dec 13 22:21:43 2009 New Revision: 76822 Log: initialize to NULL Modified: python/trunk/Include/datetime.h Modified: python/trunk/Include/datetime.h ============================================================================== --- python/trunk/Include/datetime.h (original) +++ python/trunk/Include/datetime.h Sun Dec 13 22:21:43 2009 @@ -183,7 +183,7 @@ #else /* Define global variable for the C API and a macro for setting it. */ -static PyDateTime_CAPI *PyDateTimeAPI; +static PyDateTime_CAPI *PyDateTimeAPI = NULL; #define PyDateTime_IMPORT \ PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import("datetime", \ From python-checkins at python.org Sun Dec 13 22:25:29 2009 From: python-checkins at python.org (brett.cannon) Date: Sun, 13 Dec 2009 21:25:29 -0000 Subject: [Python-checkins] r76823 - python/branches/py3k/Lib/encodings/__init__.py Message-ID: Author: brett.cannon Date: Sun Dec 13 22:25:28 2009 New Revision: 76823 Log: Fix a minor grammatical error. Modified: python/branches/py3k/Lib/encodings/__init__.py Modified: python/branches/py3k/Lib/encodings/__init__.py ============================================================================== --- python/branches/py3k/Lib/encodings/__init__.py (original) +++ python/branches/py3k/Lib/encodings/__init__.py Sun Dec 13 22:25:28 2009 @@ -10,7 +10,7 @@ Each codec module must export the following interface: * getregentry() -> codecs.CodecInfo object - The getregentry() API must a CodecInfo object with encoder, decoder, + The getregentry() API must return a CodecInfo object with encoder, decoder, incrementalencoder, incrementaldecoder, streamwriter and streamreader atttributes which adhere to the Python Codec Interface Standard. From python-checkins at python.org Sun Dec 13 22:27:53 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 21:27:53 -0000 Subject: [Python-checkins] r76824 - python/trunk/Modules/_testcapimodule.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 22:27:53 2009 New Revision: 76824 Log: add a test of loading the datetime capi Modified: python/trunk/Modules/_testcapimodule.c Modified: python/trunk/Modules/_testcapimodule.c ============================================================================== --- python/trunk/Modules/_testcapimodule.c (original) +++ python/trunk/Modules/_testcapimodule.c Sun Dec 13 22:27:53 2009 @@ -8,6 +8,7 @@ #include "Python.h" #include #include "structmember.h" +#include "datetime.h" #ifdef WITH_THREAD #include "pythread.h" @@ -806,6 +807,20 @@ #ifdef WITH_THREAD +static PyObject * +test_datetime_capi(PyObject *self, PyObject *args) { + if (PyDateTimeAPI) { + PyErr_SetString(PyExc_AssertionError, + "PyDateTime_CAPI somehow initialized"); + return NULL; + } + PyDateTime_IMPORT; + if (PyDateTimeAPI) + Py_RETURN_NONE; + else + return NULL; +} + /* test_thread_state spawns a thread of its own, and that thread releases * `thread_done` when it's finished. The driver code has to know when the * thread finishes, because the thread uses a PyObject (the callable) that @@ -1012,6 +1027,7 @@ static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"test_config", (PyCFunction)test_config, METH_NOARGS}, + {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, {"test_list_api", (PyCFunction)test_list_api, METH_NOARGS}, {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, {"test_lazy_hash_inheritance", (PyCFunction)test_lazy_hash_inheritance,METH_NOARGS}, From python-checkins at python.org Sun Dec 13 22:30:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 13 Dec 2009 21:30:54 -0000 Subject: [Python-checkins] r76825 - in python/branches/py3k: Include/datetime.h Modules/_testcapimodule.c Message-ID: Author: benjamin.peterson Date: Sun Dec 13 22:30:54 2009 New Revision: 76825 Log: Merged revisions 76822,76824 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76822 | benjamin.peterson | 2009-12-13 15:21:43 -0600 (Sun, 13 Dec 2009) | 1 line initialize to NULL ........ r76824 | benjamin.peterson | 2009-12-13 15:27:53 -0600 (Sun, 13 Dec 2009) | 1 line add a test of loading the datetime capi ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/datetime.h python/branches/py3k/Modules/_testcapimodule.c Modified: python/branches/py3k/Include/datetime.h ============================================================================== --- python/branches/py3k/Include/datetime.h (original) +++ python/branches/py3k/Include/datetime.h Sun Dec 13 22:30:54 2009 @@ -182,7 +182,7 @@ #else /* Define global variable for the C API and a macro for setting it. */ -static PyDateTime_CAPI *PyDateTimeAPI; +static PyDateTime_CAPI *PyDateTimeAPI = NULL; #define PyDateTime_IMPORT \ PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0) Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Sun Dec 13 22:30:54 2009 @@ -10,6 +10,7 @@ #include "Python.h" #include #include "structmember.h" +#include "datetime.h" #ifdef WITH_THREAD #include "pythread.h" @@ -935,6 +936,20 @@ #ifdef WITH_THREAD +static PyObject * +test_datetime_capi(PyObject *self, PyObject *args) { + if (PyDateTimeAPI) { + PyErr_SetString(PyExc_AssertionError, + "PyDateTime_CAPI somehow initialized"); + return NULL; + } + PyDateTime_IMPORT; + if (PyDateTimeAPI) + Py_RETURN_NONE; + else + return NULL; +} + /* test_thread_state spawns a thread of its own, and that thread releases * `thread_done` when it's finished. The driver code has to know when the * thread finishes, because the thread uses a PyObject (the callable) that @@ -1531,6 +1546,7 @@ {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS}, {"test_config", (PyCFunction)test_config, METH_NOARGS}, + {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, {"test_list_api", (PyCFunction)test_list_api, METH_NOARGS}, {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, {"test_lazy_hash_inheritance", (PyCFunction)test_lazy_hash_inheritance,METH_NOARGS}, From python-checkins at python.org Mon Dec 14 00:24:13 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 13 Dec 2009 23:24:13 -0000 Subject: [Python-checkins] r76826 - in python/trunk/Doc/distutils: commandref.rst sourcedist.rst Message-ID: Author: tarek.ziade Date: Mon Dec 14 00:24:13 2009 New Revision: 76826 Log: reorganized the distutils doc a bit : the MANIFEST.in template system has its own section now. This is easier to find and follow Modified: python/trunk/Doc/distutils/commandref.rst python/trunk/Doc/distutils/sourcedist.rst Modified: python/trunk/Doc/distutils/commandref.rst ============================================================================== --- python/trunk/Doc/distutils/commandref.rst (original) +++ python/trunk/Doc/distutils/commandref.rst Mon Dec 14 00:24:13 2009 @@ -48,50 +48,6 @@ .. % \label{clean-cmd} -.. _sdist-cmd: - -Creating a source distribution: the :command:`sdist` command -============================================================ - -**\*\*** fragment moved down from above: needs context! **\*\*** - -The manifest template commands are: - -+-------------------------------------------+-----------------------------------------------+ -| Command | Description | -+===========================================+===============================================+ -| :command:`include pat1 pat2 ...` | include all files matching any of the listed | -| | patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed | -| | patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of | -| ...` | the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of | -| ...` | the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree | -| | matching --- & any of the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree | -| | matching --- & any of the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`prune dir` | exclude all files under *dir* | -+-------------------------------------------+-----------------------------------------------+ -| :command:`graft dir` | include all files under *dir* | -+-------------------------------------------+-----------------------------------------------+ - -The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of -regular filename characters, ``?`` matches any single regular filename -character, and ``[range]`` matches any of the characters in *range* (e.g., -``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename -character" is platform-specific: on Unix it is anything except slash; on Windows -anything except backslash or colon. - -**\*\*** Windows support not there yet **\*\*** - .. % \section{Creating a built distribution: the .. % \protect\command{bdist} command family} .. % \label{bdist-cmds} Modified: python/trunk/Doc/distutils/sourcedist.rst ============================================================================== --- python/trunk/Doc/distutils/sourcedist.rst (original) +++ python/trunk/Doc/distutils/sourcedist.rst Mon Dec 14 00:24:13 2009 @@ -111,9 +111,68 @@ :file:`MANIFEST`, you must specify everything: the default set of files described above does not apply in this case. +See :ref:`manifest_template` section for a syntax reference. + +.. _manifest-options: + +Manifest-related options +======================== + +The normal course of operations for the :command:`sdist` command is as follows: + +* if the manifest file, :file:`MANIFEST` doesn't exist, read :file:`MANIFEST.in` + and create the manifest + +* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest + with just the default file set + +* if either :file:`MANIFEST.in` or the setup script (:file:`setup.py`) are more + recent than :file:`MANIFEST`, recreate :file:`MANIFEST` by reading + :file:`MANIFEST.in` + +* use the list of files now in :file:`MANIFEST` (either just generated or read + in) to create the source distribution archive(s) + +There are a couple of options that modify this behaviour. First, use the +:option:`--no-defaults` and :option:`--no-prune` to disable the standard +"include" and "exclude" sets. + +Second, you might want to force the manifest to be regenerated---for example, if +you have added or removed files or directories that match an existing pattern in +the manifest template, you should regenerate the manifest:: + + python setup.py sdist --force-manifest + +Or, you might just want to (re)generate the manifest, but not create a source +distribution:: + + python setup.py sdist --manifest-only + +:option:`--manifest-only` implies :option:`--force-manifest`. :option:`-o` is a +shortcut for :option:`--manifest-only`, and :option:`-f` for +:option:`--force-manifest`. + +.. _manifest_template: + +The MANIFEST.in template +======================== + +A :file:`MANIFEST.in` file can be added in a project to define the list of +files to include in the distribution built by the :command:`sdist` command. + +When :command:`sdist` is run, it will look for the :file:`MANIFEST.in` file +and interpret it to generate the :file:`MANIFEST` file that contains the +list of files that will be included in the package. + +This mechanism can be used when the default list of files is not enough. +(See :ref:`manifest`). + +Principle +--------- + The manifest template has one command per line, where each command specifies a set of files to include or exclude from the source distribution. For an -example, again we turn to the Distutils' own manifest template:: +example, let's look at the Distutils' own manifest template:: include *.txt recursive-include examples *.txt *.py @@ -125,9 +184,7 @@ :file:`examples/sample?/build`. All of this is done *after* the standard include set, so you can exclude files from the standard set with explicit instructions in the manifest template. (Or, you can use the -:option:`--no-defaults` option to disable the standard set entirely.) There are -several other commands available in the manifest template mini-language; see -section :ref:`sdist-cmd`. +:option:`--no-defaults` option to disable the standard set entirely.) The order of commands in the manifest template matters: initially, we have the list of default files as described above, and each command in the template adds @@ -181,44 +238,41 @@ them to the standard representation on your platform. That way, the manifest template is portable across operating systems. +Commands +-------- -.. _manifest-options: - -Manifest-related options -======================== - -The normal course of operations for the :command:`sdist` command is as follows: - -* if the manifest file, :file:`MANIFEST` doesn't exist, read :file:`MANIFEST.in` - and create the manifest - -* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest - with just the default file set - -* if either :file:`MANIFEST.in` or the setup script (:file:`setup.py`) are more - recent than :file:`MANIFEST`, recreate :file:`MANIFEST` by reading - :file:`MANIFEST.in` - -* use the list of files now in :file:`MANIFEST` (either just generated or read - in) to create the source distribution archive(s) - -There are a couple of options that modify this behaviour. First, use the -:option:`--no-defaults` and :option:`--no-prune` to disable the standard -"include" and "exclude" sets. - -Second, you might want to force the manifest to be regenerated---for example, if -you have added or removed files or directories that match an existing pattern in -the manifest template, you should regenerate the manifest:: - - python setup.py sdist --force-manifest - -Or, you might just want to (re)generate the manifest, but not create a source -distribution:: - - python setup.py sdist --manifest-only - -:option:`--manifest-only` implies :option:`--force-manifest`. :option:`-o` is a -shortcut for :option:`--manifest-only`, and :option:`-f` for -:option:`--force-manifest`. +The manifest template commands are: ++-------------------------------------------+-----------------------------------------------+ +| Command | Description | ++===========================================+===============================================+ +| :command:`include pat1 pat2 ...` | include all files matching any of the listed | +| | patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed | +| | patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of | +| ...` | the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of | +| ...` | the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree | +| | matching --- & any of the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree | +| | matching --- & any of the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`prune dir` | exclude all files under *dir* | ++-------------------------------------------+-----------------------------------------------+ +| :command:`graft dir` | include all files under *dir* | ++-------------------------------------------+-----------------------------------------------+ + +The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of +regular filename characters, ``?`` matches any single regular filename +character, and ``[range]`` matches any of the characters in *range* (e.g., +``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename +character" is platform-specific: on Unix it is anything except slash; on Windows +anything except backslash or colon. From python-checkins at python.org Mon Dec 14 00:25:09 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 13 Dec 2009 23:25:09 -0000 Subject: [Python-checkins] r76827 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Mon Dec 14 00:25:09 2009 New Revision: 76827 Log: Blocked revisions 76826 via svnmerge ........ r76826 | tarek.ziade | 2009-12-14 00:24:13 +0100 (Mon, 14 Dec 2009) | 1 line reorganized the distutils doc a bit : the MANIFEST.in template system has its own section now. This is easier to find and follow ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 14 00:26:18 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 13 Dec 2009 23:26:18 -0000 Subject: [Python-checkins] r76828 - in python/branches/py3k: Doc/distutils/commandref.rst Doc/distutils/sourcedist.rst Message-ID: Author: tarek.ziade Date: Mon Dec 14 00:26:18 2009 New Revision: 76828 Log: Merged revisions 76826 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76826 | tarek.ziade | 2009-12-14 00:24:13 +0100 (Mon, 14 Dec 2009) | 1 line reorganized the distutils doc a bit : the MANIFEST.in template system has its own section now. This is easier to find and follow ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/distutils/commandref.rst python/branches/py3k/Doc/distutils/sourcedist.rst Modified: python/branches/py3k/Doc/distutils/commandref.rst ============================================================================== --- python/branches/py3k/Doc/distutils/commandref.rst (original) +++ python/branches/py3k/Doc/distutils/commandref.rst Mon Dec 14 00:26:18 2009 @@ -48,50 +48,6 @@ .. % \label{clean-cmd} -.. _sdist-cmd: - -Creating a source distribution: the :command:`sdist` command -============================================================ - -**\*\*** fragment moved down from above: needs context! **\*\*** - -The manifest template commands are: - -+-------------------------------------------+-----------------------------------------------+ -| Command | Description | -+===========================================+===============================================+ -| :command:`include pat1 pat2 ...` | include all files matching any of the listed | -| | patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed | -| | patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of | -| ...` | the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of | -| ...` | the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree | -| | matching --- & any of the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree | -| | matching --- & any of the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`prune dir` | exclude all files under *dir* | -+-------------------------------------------+-----------------------------------------------+ -| :command:`graft dir` | include all files under *dir* | -+-------------------------------------------+-----------------------------------------------+ - -The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of -regular filename characters, ``?`` matches any single regular filename -character, and ``[range]`` matches any of the characters in *range* (e.g., -``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename -character" is platform-specific: on Unix it is anything except slash; on Windows -anything except backslash or colon. - -**\*\*** Windows support not there yet **\*\*** - .. % \section{Creating a built distribution: the .. % \protect\command{bdist} command family} .. % \label{bdist-cmds} Modified: python/branches/py3k/Doc/distutils/sourcedist.rst ============================================================================== --- python/branches/py3k/Doc/distutils/sourcedist.rst (original) +++ python/branches/py3k/Doc/distutils/sourcedist.rst Mon Dec 14 00:26:18 2009 @@ -111,9 +111,68 @@ :file:`MANIFEST`, you must specify everything: the default set of files described above does not apply in this case. +See :ref:`manifest_template` section for a syntax reference. + +.. _manifest-options: + +Manifest-related options +======================== + +The normal course of operations for the :command:`sdist` command is as follows: + +* if the manifest file, :file:`MANIFEST` doesn't exist, read :file:`MANIFEST.in` + and create the manifest + +* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest + with just the default file set + +* if either :file:`MANIFEST.in` or the setup script (:file:`setup.py`) are more + recent than :file:`MANIFEST`, recreate :file:`MANIFEST` by reading + :file:`MANIFEST.in` + +* use the list of files now in :file:`MANIFEST` (either just generated or read + in) to create the source distribution archive(s) + +There are a couple of options that modify this behaviour. First, use the +:option:`--no-defaults` and :option:`--no-prune` to disable the standard +"include" and "exclude" sets. + +Second, you might want to force the manifest to be regenerated---for example, if +you have added or removed files or directories that match an existing pattern in +the manifest template, you should regenerate the manifest:: + + python setup.py sdist --force-manifest + +Or, you might just want to (re)generate the manifest, but not create a source +distribution:: + + python setup.py sdist --manifest-only + +:option:`--manifest-only` implies :option:`--force-manifest`. :option:`-o` is a +shortcut for :option:`--manifest-only`, and :option:`-f` for +:option:`--force-manifest`. + +.. _manifest_template: + +The MANIFEST.in template +======================== + +A :file:`MANIFEST.in` file can be added in a project to define the list of +files to include in the distribution built by the :command:`sdist` command. + +When :command:`sdist` is run, it will look for the :file:`MANIFEST.in` file +and interpret it to generate the :file:`MANIFEST` file that contains the +list of files that will be included in the package. + +This mechanism can be used when the default list of files is not enough. +(See :ref:`manifest`). + +Principle +--------- + The manifest template has one command per line, where each command specifies a set of files to include or exclude from the source distribution. For an -example, again we turn to the Distutils' own manifest template:: +example, let's look at the Distutils' own manifest template:: include *.txt recursive-include examples *.txt *.py @@ -125,9 +184,7 @@ :file:`examples/sample?/build`. All of this is done *after* the standard include set, so you can exclude files from the standard set with explicit instructions in the manifest template. (Or, you can use the -:option:`--no-defaults` option to disable the standard set entirely.) There are -several other commands available in the manifest template mini-language; see -section :ref:`sdist-cmd`. +:option:`--no-defaults` option to disable the standard set entirely.) The order of commands in the manifest template matters: initially, we have the list of default files as described above, and each command in the template adds @@ -181,44 +238,41 @@ them to the standard representation on your platform. That way, the manifest template is portable across operating systems. +Commands +-------- -.. _manifest-options: - -Manifest-related options -======================== - -The normal course of operations for the :command:`sdist` command is as follows: - -* if the manifest file, :file:`MANIFEST` doesn't exist, read :file:`MANIFEST.in` - and create the manifest - -* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest - with just the default file set - -* if either :file:`MANIFEST.in` or the setup script (:file:`setup.py`) are more - recent than :file:`MANIFEST`, recreate :file:`MANIFEST` by reading - :file:`MANIFEST.in` - -* use the list of files now in :file:`MANIFEST` (either just generated or read - in) to create the source distribution archive(s) - -There are a couple of options that modify this behaviour. First, use the -:option:`--no-defaults` and :option:`--no-prune` to disable the standard -"include" and "exclude" sets. - -Second, you might want to force the manifest to be regenerated---for example, if -you have added or removed files or directories that match an existing pattern in -the manifest template, you should regenerate the manifest:: - - python setup.py sdist --force-manifest - -Or, you might just want to (re)generate the manifest, but not create a source -distribution:: - - python setup.py sdist --manifest-only - -:option:`--manifest-only` implies :option:`--force-manifest`. :option:`-o` is a -shortcut for :option:`--manifest-only`, and :option:`-f` for -:option:`--force-manifest`. +The manifest template commands are: ++-------------------------------------------+-----------------------------------------------+ +| Command | Description | ++===========================================+===============================================+ +| :command:`include pat1 pat2 ...` | include all files matching any of the listed | +| | patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed | +| | patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of | +| ...` | the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of | +| ...` | the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree | +| | matching --- & any of the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree | +| | matching --- & any of the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`prune dir` | exclude all files under *dir* | ++-------------------------------------------+-----------------------------------------------+ +| :command:`graft dir` | include all files under *dir* | ++-------------------------------------------+-----------------------------------------------+ + +The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of +regular filename characters, ``?`` matches any single regular filename +character, and ``[range]`` matches any of the characters in *range* (e.g., +``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename +character" is platform-specific: on Unix it is anything except slash; on Windows +anything except backslash or colon. From python-checkins at python.org Mon Dec 14 00:27:36 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 13 Dec 2009 23:27:36 -0000 Subject: [Python-checkins] r76829 - python/branches/release31-maint Message-ID: Author: tarek.ziade Date: Mon Dec 14 00:27:36 2009 New Revision: 76829 Log: Blocked revisions 76828 via svnmerge ................ r76828 | tarek.ziade | 2009-12-14 00:26:18 +0100 (Mon, 14 Dec 2009) | 9 lines Merged revisions 76826 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76826 | tarek.ziade | 2009-12-14 00:24:13 +0100 (Mon, 14 Dec 2009) | 1 line reorganized the distutils doc a bit : the MANIFEST.in template system has its own section now. This is easier to find and follow ........ ................ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Mon Dec 14 00:49:49 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 14 Dec 2009 00:49:49 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76825): sum=0 Message-ID: <20091213234949.4B68A17722@ns6635.ovh.net> py3k results for svn r76825 (hg cset a042e3c841ba) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogtNSpX5', '-x', 'test_httpservers'] From python-checkins at python.org Mon Dec 14 03:50:32 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 02:50:32 -0000 Subject: [Python-checkins] r76830 - python/trunk/Doc/faq/general.rst Message-ID: Author: r.david.murray Date: Mon Dec 14 03:50:32 2009 New Revision: 76830 Log: Clarify phrasing that explains that there are currently two branches. Modified: python/trunk/Doc/faq/general.rst Modified: python/trunk/Doc/faq/general.rst ============================================================================== --- python/trunk/Doc/faq/general.rst (original) +++ python/trunk/Doc/faq/general.rst Mon Dec 14 03:50:32 2009 @@ -310,11 +310,11 @@ releases. The latest stable releases can always be found on the `Python download page -`_. They are recommended production-ready version -at this point in time. At the moment, there are two branches of stable -releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since currently -there is more third party software available for Python 2 than for Python 3. -Python 2 code will generally not run unchanged in Python 3. +`_. There are two recommended production-ready +versions at this point in time, because at the moment there are two branches of +stable releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since +currently there is more third party software available for Python 2 than for +Python 3. Python 2 code will generally not run unchanged in Python 3. How many people are using Python? From python-checkins at python.org Mon Dec 14 17:28:26 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 16:28:26 -0000 Subject: [Python-checkins] r76831 - in python/trunk: Lib/test/test_unicode.py Misc/NEWS Objects/unicodeobject.c Message-ID: Author: r.david.murray Date: Mon Dec 14 17:28:26 2009 New Revision: 76831 Log: Issue #1680159: unicode coercion during an 'in' operation was masking any errors that might occur during coercion of the left operand and turning them into a TypeError with a message text that was confusing in the given context. This patch lets any errors through, as was already done during coercion of the right hand side. Modified: python/trunk/Lib/test/test_unicode.py python/trunk/Misc/NEWS python/trunk/Objects/unicodeobject.c Modified: python/trunk/Lib/test/test_unicode.py ============================================================================== --- python/trunk/Lib/test/test_unicode.py (original) +++ python/trunk/Lib/test/test_unicode.py Mon Dec 14 17:28:26 2009 @@ -344,7 +344,8 @@ # If the following fails either # the contains operator does not propagate UnicodeErrors or # someone has changed the default encoding - self.assertRaises(UnicodeError, 'g\xe2teau'.__contains__, u'\xe2') + self.assertRaises(UnicodeDecodeError, 'g\xe2teau'.__contains__, u'\xe2') + self.assertRaises(UnicodeDecodeError, u'g\xe2teau'.__contains__, '\xe2') self.assertTrue(u'' in '') self.assertTrue('' in u'') @@ -375,6 +376,7 @@ self.assertTrue(u'asdf' not in u'') self.assertRaises(TypeError, u"abc".__contains__) + self.assertRaises(TypeError, u"abc".__contains__, object()) def test_formatting(self): string_tests.MixinStrUnicodeUserStringTest.test_formatting(self) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Dec 14 17:28:26 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #1680159: unicode coercion during an 'in' operation no longer masks + the underlying error when the coercion fails for the left hand operand. + - Issue #7491: Metaclass's __cmp__ method was ignored. - Issue #7466: segmentation fault when the garbage collector is called Modified: python/trunk/Objects/unicodeobject.c ============================================================================== --- python/trunk/Objects/unicodeobject.c (original) +++ python/trunk/Objects/unicodeobject.c Mon Dec 14 17:28:26 2009 @@ -6502,8 +6502,6 @@ /* Coerce the two arguments */ sub = PyUnicode_FromObject(element); if (!sub) { - PyErr_SetString(PyExc_TypeError, - "'in ' requires string as left operand"); return -1; } From python-checkins at python.org Mon Dec 14 18:11:00 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 17:11:00 -0000 Subject: [Python-checkins] r76832 - python/branches/py3k Message-ID: Author: r.david.murray Date: Mon Dec 14 18:11:00 2009 New Revision: 76832 Log: Blocked revisions 76831 via svnmerge ........ r76831 | r.david.murray | 2009-12-14 11:28:26 -0500 (Mon, 14 Dec 2009) | 6 lines Issue #1680159: unicode coercion during an 'in' operation was masking any errors that might occur during coercion of the left operand and turning them into a TypeError with a message text that was confusing in the given context. This patch lets any errors through, as was already done during coercion of the right hand side. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Dec 14 18:24:36 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 17:24:36 -0000 Subject: [Python-checkins] r76833 - in python/branches/release26-maint: Doc/faq/general.rst Message-ID: Author: r.david.murray Date: Mon Dec 14 18:24:36 2009 New Revision: 76833 Log: Merged revisions 76819,76830 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76819 | benjamin.peterson | 2009-12-13 16:15:31 -0500 (Sun, 13 Dec 2009) | 1 line avoid having to update this statement all the time ........ r76830 | r.david.murray | 2009-12-13 21:50:32 -0500 (Sun, 13 Dec 2009) | 2 lines Clarify phrasing that explains that there are currently two branches. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/faq/general.rst Modified: python/branches/release26-maint/Doc/faq/general.rst ============================================================================== --- python/branches/release26-maint/Doc/faq/general.rst (original) +++ python/branches/release26-maint/Doc/faq/general.rst Mon Dec 14 18:24:36 2009 @@ -309,13 +309,12 @@ guaranteed that interfaces will remain the same throughout a series of bugfix releases. -.. XXX this gets out of date pretty often - -The `2.6.4 release `_ is recommended -production-ready version at this point in time. Python 3.1 is also considered -production-ready, but may be less useful, since currently there is more third -party software available for Python 2 than for Python 3. Python 2 code will -generally not run unchanged in Python 3. +The latest stable releases can always be found on the `Python download page +`_. There are two recommended production-ready +versions at this point in time, because at the moment there are two branches of +stable releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since +currently there is more third party software available for Python 2 than for +Python 3. Python 2 code will generally not run unchanged in Python 3. How many people are using Python? From python-checkins at python.org Mon Dec 14 18:27:08 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 17:27:08 -0000 Subject: [Python-checkins] r76834 - in python/branches/py3k: Doc/faq/general.rst Message-ID: Author: r.david.murray Date: Mon Dec 14 18:27:08 2009 New Revision: 76834 Log: Merged revisions 76819,76830 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76819 | benjamin.peterson | 2009-12-13 16:15:31 -0500 (Sun, 13 Dec 2009) | 1 line avoid having to update this statement all the time ........ r76830 | r.david.murray | 2009-12-13 21:50:32 -0500 (Sun, 13 Dec 2009) | 2 lines Clarify phrasing that explains that there are currently two branches. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/faq/general.rst Modified: python/branches/py3k/Doc/faq/general.rst ============================================================================== --- python/branches/py3k/Doc/faq/general.rst (original) +++ python/branches/py3k/Doc/faq/general.rst Mon Dec 14 18:27:08 2009 @@ -309,13 +309,12 @@ guaranteed that interfaces will remain the same throughout a series of bugfix releases. -.. XXX this gets out of date pretty often - -The `2.6.4 release `_ is recommended -production-ready version at this point in time. Python 3.1 is also considered -production-ready, but may be less useful, since currently there is more third -party software available for Python 2 than for Python 3. Python 2 code will -generally not run unchanged in Python 3. +The latest stable releases can always be found on the `Python download page +`_. There are two recommended production-ready +versions at this point in time, because at the moment there are two branches of +stable releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since +currently there is more third party software available for Python 2 than for +Python 3. Python 2 code will generally not run unchanged in Python 3. How many people are using Python? From python-checkins at python.org Mon Dec 14 18:31:22 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 17:31:22 -0000 Subject: [Python-checkins] r76835 - in python/branches/release31-maint: Doc/faq/general.rst Message-ID: Author: r.david.murray Date: Mon Dec 14 18:31:22 2009 New Revision: 76835 Log: Merged revisions 76834 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76834 | r.david.murray | 2009-12-14 12:27:08 -0500 (Mon, 14 Dec 2009) | 13 lines Merged revisions 76819,76830 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76819 | benjamin.peterson | 2009-12-13 16:15:31 -0500 (Sun, 13 Dec 2009) | 1 line avoid having to update this statement all the time ........ r76830 | r.david.murray | 2009-12-13 21:50:32 -0500 (Sun, 13 Dec 2009) | 2 lines Clarify phrasing that explains that there are currently two branches. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/faq/general.rst Modified: python/branches/release31-maint/Doc/faq/general.rst ============================================================================== --- python/branches/release31-maint/Doc/faq/general.rst (original) +++ python/branches/release31-maint/Doc/faq/general.rst Mon Dec 14 18:31:22 2009 @@ -309,13 +309,12 @@ guaranteed that interfaces will remain the same throughout a series of bugfix releases. -.. XXX this gets out of date pretty often - -The `2.6.4 release `_ is recommended -production-ready version at this point in time. Python 3.1 is also considered -production-ready, but may be less useful, since currently there is more third -party software available for Python 2 than for Python 3. Python 2 code will -generally not run unchanged in Python 3. +The latest stable releases can always be found on the `Python download page +`_. There are two recommended production-ready +versions at this point in time, because at the moment there are two branches of +stable releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since +currently there is more third party software available for Python 2 than for +Python 3. Python 2 code will generally not run unchanged in Python 3. How many people are using Python? From python-checkins at python.org Mon Dec 14 19:00:06 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 14 Dec 2009 18:00:06 -0000 Subject: [Python-checkins] r76836 - in python/branches/py3k: Lib/gzip.py Lib/tarfile.py Lib/test/test_zlib.py Misc/NEWS Modules/zlibmodule.c Message-ID: Author: antoine.pitrou Date: Mon Dec 14 19:00:06 2009 New Revision: 76836 Log: Issue #4757: `zlib.compress` and other methods in the zlib module now raise a TypeError when given an `str` object (rather than a `bytes`-like object). Patch by Victor Stinner and Florent Xicluna. Modified: python/branches/py3k/Lib/gzip.py python/branches/py3k/Lib/tarfile.py python/branches/py3k/Lib/test/test_zlib.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/zlibmodule.c Modified: python/branches/py3k/Lib/gzip.py ============================================================================== --- python/branches/py3k/Lib/gzip.py (original) +++ python/branches/py3k/Lib/gzip.py Mon Dec 14 19:00:06 2009 @@ -147,7 +147,7 @@ def _init_write(self, filename): self.name = filename - self.crc = zlib.crc32("") & 0xffffffff + self.crc = zlib.crc32(b"") & 0xffffffff self.size = 0 self.writebuf = [] self.bufsize = 0 @@ -178,7 +178,7 @@ self.fileobj.write(fname + b'\000') def _init_read(self): - self.crc = zlib.crc32("") & 0xffffffff + self.crc = zlib.crc32(b"") & 0xffffffff self.size = 0 def _read_gzip_header(self): Modified: python/branches/py3k/Lib/tarfile.py ============================================================================== --- python/branches/py3k/Lib/tarfile.py (original) +++ python/branches/py3k/Lib/tarfile.py Mon Dec 14 19:00:06 2009 @@ -410,7 +410,7 @@ except ImportError: raise CompressionError("zlib module is not available") self.zlib = zlib - self.crc = zlib.crc32("") + self.crc = zlib.crc32(b"") if mode == "r": self._init_read_gz() else: 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 Mon Dec 14 19:00:06 2009 @@ -41,12 +41,12 @@ self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1)) def test_crc32_adler32_unsigned(self): - foo = 'abcdefghijklmnop' + foo = b'abcdefghijklmnop' # explicitly test signed behavior self.assertEqual(zlib.crc32(foo), 2486878355) - self.assertEqual(zlib.crc32('spam'), 1138425661) + self.assertEqual(zlib.crc32(b'spam'), 1138425661) self.assertEqual(zlib.adler32(foo+foo), 3573550353) - self.assertEqual(zlib.adler32('spam'), 72286642) + self.assertEqual(zlib.adler32(b'spam'), 72286642) def test_same_as_binascii_crc32(self): foo = b'abcdefghijklmnop' @@ -63,7 +63,18 @@ # specifying compression level out of range causes an error # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib # accepts 0 too) - self.assertRaises(zlib.error, zlib.compress, 'ERROR', 10) + self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10) + + def test_badargs(self): + self.assertRaises(TypeError, zlib.adler32) + self.assertRaises(TypeError, zlib.crc32) + self.assertRaises(TypeError, zlib.compress) + self.assertRaises(TypeError, zlib.decompress) + for arg in (42, None, '', 'abc', (), []): + self.assertRaises(TypeError, zlib.adler32, arg) + self.assertRaises(TypeError, zlib.crc32, arg) + self.assertRaises(TypeError, zlib.compress, arg) + self.assertRaises(TypeError, zlib.decompress, arg) def test_badcompressobj(self): # verify failure on building compress object with bad params @@ -93,8 +104,9 @@ # compress more data data = HAMLET_SCENE * 128 x = zlib.compress(data) - self.assertEqual(zlib.decompress(x), data) - + self.assertEqual(zlib.compress(bytearray(data)), x) + for ob in x, bytearray(x): + self.assertEqual(zlib.decompress(ob), data) @@ -102,17 +114,22 @@ # Test compression object def test_pair(self): # straightforward compress/decompress objects - data = HAMLET_SCENE * 128 - co = zlib.compressobj() - x1 = co.compress(data) - x2 = co.flush() - self.assertRaises(zlib.error, co.flush) # second flush should not work - dco = zlib.decompressobj() - y1 = dco.decompress(x1 + x2) - y2 = dco.flush() - self.assertEqual(data, y1 + y2) - self.assertTrue(isinstance(dco.unconsumed_tail, bytes)) - self.assertTrue(isinstance(dco.unused_data, bytes)) + datasrc = HAMLET_SCENE * 128 + datazip = zlib.compress(datasrc) + # should compress both bytes and bytearray data + for data in (datasrc, bytearray(datasrc)): + co = zlib.compressobj() + x1 = co.compress(data) + x2 = co.flush() + self.assertRaises(zlib.error, co.flush) # second flush should not work + self.assertEqual(x1 + x2, datazip) + for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))): + dco = zlib.decompressobj() + y1 = dco.decompress(v1 + v2) + y2 = dco.flush() + self.assertEqual(data, y1 + y2) + self.assertIsInstance(dco.unconsumed_tail, bytes) + self.assertIsInstance(dco.unused_data, bytes) def test_compressoptions(self): # specify lots of options to compressobj() @@ -173,7 +190,7 @@ bufs.append(dco.flush()) else: while True: - chunk = dco.decompress('') + chunk = dco.decompress(b'') if chunk: bufs.append(chunk) else: @@ -241,7 +258,7 @@ bufs.append(dco.flush()) else: while chunk: - chunk = dco.decompress('', max_length) + chunk = dco.decompress(b'', max_length) self.assertFalse(len(chunk) > max_length, 'chunk too big (%d>%d)' % (len(chunk),max_length)) bufs.append(chunk) @@ -253,7 +270,7 @@ def test_maxlenmisc(self): # Misc tests of max_length dco = zlib.decompressobj() - self.assertRaises(ValueError, dco.decompress, "", -1) + self.assertRaises(ValueError, dco.decompress, b"", -1) self.assertEqual(b'', dco.unconsumed_tail) def test_flushes(self): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Dec 14 19:00:06 2009 @@ -157,6 +157,10 @@ Library ------- +- Issue #4757: `zlib.compress` and other methods in the zlib module now + raise a TypeError when given an `str` object (rather than a `bytes`-like + object). Patch by Victor Stinner and Florent Xicluna. + - Issue #7349: Make methods of file objects in the io module accept None as an argument where file-like objects (ie StringIO and BytesIO) accept them to mean the same as passing no argument. Modified: python/branches/py3k/Modules/zlibmodule.c ============================================================================== --- python/branches/py3k/Modules/zlibmodule.c (original) +++ python/branches/py3k/Modules/zlibmodule.c Mon Dec 14 19:00:06 2009 @@ -107,7 +107,7 @@ z_stream zst; /* require Python string object, optional 'level' arg */ - if (!PyArg_ParseTuple(args, "s*|i:compress", &pinput, &level)) + if (!PyArg_ParseTuple(args, "y*|i:compress", &pinput, &level)) return NULL; input = pinput.buf; length = pinput.len; @@ -190,7 +190,7 @@ Py_ssize_t r_strlen=DEFAULTALLOC; z_stream zst; - if (!PyArg_ParseTuple(args, "s*|in:decompress", + if (!PyArg_ParseTuple(args, "y*|in:decompress", &pinput, &wsize, &r_strlen)) return NULL; input = pinput.buf; @@ -402,7 +402,7 @@ Byte *input; unsigned long start_total_out; - if (!PyArg_ParseTuple(args, "s*:compress", &pinput)) + if (!PyArg_ParseTuple(args, "y*:compress", &pinput)) return NULL; input = pinput.buf; inplen = pinput.len; @@ -484,7 +484,7 @@ Byte *input; unsigned long start_total_out; - if (!PyArg_ParseTuple(args, "s*|i:decompress", &pinput, + if (!PyArg_ParseTuple(args, "y*|i:decompress", &pinput, &max_length)) return NULL; input = pinput.buf; @@ -912,8 +912,8 @@ unsigned int adler32val = 1; /* adler32(0L, Z_NULL, 0) */ Py_buffer pbuf; - if (!PyArg_ParseTuple(args, "s*|I:adler32", &pbuf, &adler32val)) - return NULL; + if (!PyArg_ParseTuple(args, "y*|I:adler32", &pbuf, &adler32val)) + return NULL; /* Releasing the GIL for very small buffers is inefficient and may lower performance */ if (pbuf.len > 1024*5) { @@ -921,7 +921,7 @@ adler32val = adler32(adler32val, pbuf.buf, pbuf.len); Py_END_ALLOW_THREADS } else { - adler32val = adler32(adler32val, pbuf.buf, pbuf.len); + adler32val = adler32(adler32val, pbuf.buf, pbuf.len); } PyBuffer_Release(&pbuf); return PyLong_FromUnsignedLong(adler32val & 0xffffffffU); @@ -940,7 +940,7 @@ Py_buffer pbuf; int signed_val; - if (!PyArg_ParseTuple(args, "s*|I:crc32", &pbuf, &crc32val)) + if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val)) return NULL; /* Releasing the GIL for very small buffers is inefficient and may lower performance */ From python-checkins at python.org Mon Dec 14 19:03:09 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 18:03:09 -0000 Subject: [Python-checkins] r76837 - python/branches/release26-maint Message-ID: Author: r.david.murray Date: Mon Dec 14 19:03:08 2009 New Revision: 76837 Log: Blocked revisions 76831 via svnmerge ........ r76831 | r.david.murray | 2009-12-14 11:28:26 -0500 (Mon, 14 Dec 2009) | 6 lines Issue #1680159: unicode coercion during an 'in' operation was masking any errors that might occur during coercion of the left operand and turning them into a TypeError with a message text that was confusing in the given context. This patch lets any errors through, as was already done during coercion of the right hand side. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 14 19:23:31 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 14 Dec 2009 18:23:31 -0000 Subject: [Python-checkins] r76838 - in python/branches/release31-maint: Lib/gzip.py Lib/tarfile.py Lib/test/test_zlib.py Misc/NEWS Modules/zlibmodule.c Message-ID: Author: antoine.pitrou Date: Mon Dec 14 19:23:30 2009 New Revision: 76838 Log: Merged revisions 76836 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76836 | antoine.pitrou | 2009-12-14 19:00:06 +0100 (lun., 14 d?c. 2009) | 5 lines Issue #4757: `zlib.compress` and other methods in the zlib module now raise a TypeError when given an `str` object (rather than a `bytes`-like object). Patch by Victor Stinner and Florent Xicluna. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/gzip.py python/branches/release31-maint/Lib/tarfile.py python/branches/release31-maint/Lib/test/test_zlib.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/zlibmodule.c Modified: python/branches/release31-maint/Lib/gzip.py ============================================================================== --- python/branches/release31-maint/Lib/gzip.py (original) +++ python/branches/release31-maint/Lib/gzip.py Mon Dec 14 19:23:30 2009 @@ -147,7 +147,7 @@ def _init_write(self, filename): self.name = filename - self.crc = zlib.crc32("") & 0xffffffff + self.crc = zlib.crc32(b"") & 0xffffffff self.size = 0 self.writebuf = [] self.bufsize = 0 @@ -177,7 +177,7 @@ self.fileobj.write(fname + b'\000') def _init_read(self): - self.crc = zlib.crc32("") & 0xffffffff + self.crc = zlib.crc32(b"") & 0xffffffff self.size = 0 def _read_gzip_header(self): Modified: python/branches/release31-maint/Lib/tarfile.py ============================================================================== --- python/branches/release31-maint/Lib/tarfile.py (original) +++ python/branches/release31-maint/Lib/tarfile.py Mon Dec 14 19:23:30 2009 @@ -400,7 +400,7 @@ except ImportError: raise CompressionError("zlib module is not available") self.zlib = zlib - self.crc = zlib.crc32("") + self.crc = zlib.crc32(b"") if mode == "r": self._init_read_gz() else: Modified: python/branches/release31-maint/Lib/test/test_zlib.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_zlib.py (original) +++ python/branches/release31-maint/Lib/test/test_zlib.py Mon Dec 14 19:23:30 2009 @@ -41,12 +41,12 @@ self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1)) def test_crc32_adler32_unsigned(self): - foo = 'abcdefghijklmnop' + foo = b'abcdefghijklmnop' # explicitly test signed behavior self.assertEqual(zlib.crc32(foo), 2486878355) - self.assertEqual(zlib.crc32('spam'), 1138425661) + self.assertEqual(zlib.crc32(b'spam'), 1138425661) self.assertEqual(zlib.adler32(foo+foo), 3573550353) - self.assertEqual(zlib.adler32('spam'), 72286642) + self.assertEqual(zlib.adler32(b'spam'), 72286642) def test_same_as_binascii_crc32(self): foo = b'abcdefghijklmnop' @@ -63,7 +63,18 @@ # specifying compression level out of range causes an error # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib # accepts 0 too) - self.assertRaises(zlib.error, zlib.compress, 'ERROR', 10) + self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10) + + def test_badargs(self): + self.assertRaises(TypeError, zlib.adler32) + self.assertRaises(TypeError, zlib.crc32) + self.assertRaises(TypeError, zlib.compress) + self.assertRaises(TypeError, zlib.decompress) + for arg in (42, None, '', 'abc', (), []): + self.assertRaises(TypeError, zlib.adler32, arg) + self.assertRaises(TypeError, zlib.crc32, arg) + self.assertRaises(TypeError, zlib.compress, arg) + self.assertRaises(TypeError, zlib.decompress, arg) def test_badcompressobj(self): # verify failure on building compress object with bad params @@ -93,8 +104,9 @@ # compress more data data = HAMLET_SCENE * 128 x = zlib.compress(data) - self.assertEqual(zlib.decompress(x), data) - + self.assertEqual(zlib.compress(bytearray(data)), x) + for ob in x, bytearray(x): + self.assertEqual(zlib.decompress(ob), data) @@ -102,17 +114,22 @@ # Test compression object def test_pair(self): # straightforward compress/decompress objects - data = HAMLET_SCENE * 128 - co = zlib.compressobj() - x1 = co.compress(data) - x2 = co.flush() - self.assertRaises(zlib.error, co.flush) # second flush should not work - dco = zlib.decompressobj() - y1 = dco.decompress(x1 + x2) - y2 = dco.flush() - self.assertEqual(data, y1 + y2) - self.assertTrue(isinstance(dco.unconsumed_tail, bytes)) - self.assertTrue(isinstance(dco.unused_data, bytes)) + datasrc = HAMLET_SCENE * 128 + datazip = zlib.compress(datasrc) + # should compress both bytes and bytearray data + for data in (datasrc, bytearray(datasrc)): + co = zlib.compressobj() + x1 = co.compress(data) + x2 = co.flush() + self.assertRaises(zlib.error, co.flush) # second flush should not work + self.assertEqual(x1 + x2, datazip) + for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))): + dco = zlib.decompressobj() + y1 = dco.decompress(v1 + v2) + y2 = dco.flush() + self.assertEqual(data, y1 + y2) + self.assertTrue(isinstance(dco.unconsumed_tail, bytes)) + self.assertTrue(isinstance(dco.unused_data, bytes)) def test_compressoptions(self): # specify lots of options to compressobj() @@ -173,7 +190,7 @@ bufs.append(dco.flush()) else: while True: - chunk = dco.decompress('') + chunk = dco.decompress(b'') if chunk: bufs.append(chunk) else: @@ -241,7 +258,7 @@ bufs.append(dco.flush()) else: while chunk: - chunk = dco.decompress('', max_length) + chunk = dco.decompress(b'', max_length) self.assertFalse(len(chunk) > max_length, 'chunk too big (%d>%d)' % (len(chunk),max_length)) bufs.append(chunk) @@ -253,7 +270,7 @@ def test_maxlenmisc(self): # Misc tests of max_length dco = zlib.decompressobj() - self.assertRaises(ValueError, dco.decompress, "", -1) + self.assertRaises(ValueError, dco.decompress, b"", -1) self.assertEqual(b'', dco.unconsumed_tail) def test_flushes(self): Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Dec 14 19:23:30 2009 @@ -58,6 +58,10 @@ Library ------- +- Issue #4757: `zlib.compress` and other methods in the zlib module now + raise a TypeError when given an `str` object (rather than a `bytes`-like + object). Patch by Victor Stinner and Florent Xicluna. + - Issue #7349: Make methods of file objects in the io module accept None as an argument where file-like objects (ie StringIO and BytesIO) accept them to mean the same as passing no argument. Modified: python/branches/release31-maint/Modules/zlibmodule.c ============================================================================== --- python/branches/release31-maint/Modules/zlibmodule.c (original) +++ python/branches/release31-maint/Modules/zlibmodule.c Mon Dec 14 19:23:30 2009 @@ -107,7 +107,7 @@ z_stream zst; /* require Python string object, optional 'level' arg */ - if (!PyArg_ParseTuple(args, "s*|i:compress", &pinput, &level)) + if (!PyArg_ParseTuple(args, "y*|i:compress", &pinput, &level)) return NULL; input = pinput.buf; length = pinput.len; @@ -190,7 +190,7 @@ Py_ssize_t r_strlen=DEFAULTALLOC; z_stream zst; - if (!PyArg_ParseTuple(args, "s*|in:decompress", + if (!PyArg_ParseTuple(args, "y*|in:decompress", &pinput, &wsize, &r_strlen)) return NULL; input = pinput.buf; @@ -402,7 +402,7 @@ Byte *input; unsigned long start_total_out; - if (!PyArg_ParseTuple(args, "s*:compress", &pinput)) + if (!PyArg_ParseTuple(args, "y*:compress", &pinput)) return NULL; input = pinput.buf; inplen = pinput.len; @@ -484,7 +484,7 @@ Byte *input; unsigned long start_total_out; - if (!PyArg_ParseTuple(args, "s*|i:decompress", &pinput, + if (!PyArg_ParseTuple(args, "y*|i:decompress", &pinput, &max_length)) return NULL; input = pinput.buf; @@ -912,8 +912,8 @@ unsigned int adler32val = 1; /* adler32(0L, Z_NULL, 0) */ Py_buffer pbuf; - if (!PyArg_ParseTuple(args, "s*|I:adler32", &pbuf, &adler32val)) - return NULL; + if (!PyArg_ParseTuple(args, "y*|I:adler32", &pbuf, &adler32val)) + return NULL; /* Releasing the GIL for very small buffers is inefficient and may lower performance */ if (pbuf.len > 1024*5) { @@ -921,7 +921,7 @@ adler32val = adler32(adler32val, pbuf.buf, pbuf.len); Py_END_ALLOW_THREADS } else { - adler32val = adler32(adler32val, pbuf.buf, pbuf.len); + adler32val = adler32(adler32val, pbuf.buf, pbuf.len); } PyBuffer_Release(&pbuf); return PyLong_FromUnsignedLong(adler32val & 0xffffffffU); @@ -940,7 +940,7 @@ Py_buffer pbuf; int signed_val; - if (!PyArg_ParseTuple(args, "s*|I:crc32", &pbuf, &crc32val)) + if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val)) return NULL; /* Releasing the GIL for very small buffers is inefficient and may lower performance */ From python-checkins at python.org Mon Dec 14 19:43:05 2009 From: python-checkins at python.org (steven.bethard) Date: Mon, 14 Dec 2009 18:43:05 -0000 Subject: [Python-checkins] r76839 - peps/trunk/pep-0389.txt Message-ID: Author: steven.bethard Date: Mon Dec 14 19:43:04 2009 New Revision: 76839 Log: Ian Bicking's suggested rewording. Modified: peps/trunk/pep-0389.txt Modified: peps/trunk/pep-0389.txt ============================================================================== --- peps/trunk/pep-0389.txt (original) +++ peps/trunk/pep-0389.txt Mon Dec 14 19:43:04 2009 @@ -142,8 +142,8 @@ * Python 2.7+ and 3.2+ -- The following note will be added to the optparse documentation: - The optparse module is deprecated, and has been replaced by the - argparse module. + The optparse module is deprecated and will not be developed + further; development will continue with the argparse module. * Python 2.7+ -- If the Python 3 compatibility flag, ``-3``, is provided at the command line, then importing optparse will issue a From python-checkins at python.org Mon Dec 14 22:57:39 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 21:57:39 -0000 Subject: [Python-checkins] r76840 - in python/trunk: Lib/test/test_multiprocessing.py Misc/NEWS Message-ID: Author: r.david.murray Date: Mon Dec 14 22:57:39 2009 New Revision: 76840 Log: Issue #7498: make test_multiprocessing use test_support.find_unused_port instead of a hard coded port number in test_rapid_restart. Modified: python/trunk/Lib/test/test_multiprocessing.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_multiprocessing.py ============================================================================== --- python/trunk/Lib/test/test_multiprocessing.py (original) +++ python/trunk/Lib/test/test_multiprocessing.py Mon Dec 14 22:57:39 2009 @@ -1212,8 +1212,9 @@ def test_rapid_restart(self): authkey = os.urandom(32) + port = test_support.find_unused_port() manager = QueueManager( - address=('localhost', 9999), authkey=authkey, serializer=SERIALIZER) + address=('localhost', port), authkey=authkey, serializer=SERIALIZER) manager.start() p = self.Process(target=self._putter, args=(manager.address, authkey)) @@ -1223,7 +1224,7 @@ del queue manager.shutdown() manager = QueueManager( - address=('localhost', 9999), authkey=authkey, serializer=SERIALIZER) + address=('localhost', port), authkey=authkey, serializer=SERIALIZER) manager.start() manager.shutdown() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Dec 14 22:57:39 2009 @@ -20,6 +20,7 @@ - Issue #7466: segmentation fault when the garbage collector is called in the middle of populating a tuple. Patch by Florent Xicluna. + Library ------- @@ -42,6 +43,14 @@ distutils.dist.DistributionMetadata. +Tests +----- + +- Issue #7498: test_multiprocessing now uses test_support.find_unused_port + instead of a hardcoded port number in test_rapid_restart. + + + What's New in Python 2.7 alpha 1 ================================ From python-checkins at python.org Mon Dec 14 23:18:57 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 22:18:57 -0000 Subject: [Python-checkins] r76842 - in python/branches/release26-maint: Lib/test/test_multiprocessing.py Misc/NEWS Message-ID: Author: r.david.murray Date: Mon Dec 14 23:18:57 2009 New Revision: 76842 Log: Merged revisions 76840 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76840 | r.david.murray | 2009-12-14 16:57:39 -0500 (Mon, 14 Dec 2009) | 3 lines Issue #7498: make test_multiprocessing use test_support.find_unused_port instead of a hard coded port number in test_rapid_restart. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_multiprocessing.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_multiprocessing.py (original) +++ python/branches/release26-maint/Lib/test/test_multiprocessing.py Mon Dec 14 23:18:57 2009 @@ -18,6 +18,7 @@ import random import logging from StringIO import StringIO +from test import test_support # Work around broken sem_open implementations @@ -1204,8 +1205,9 @@ def test_rapid_restart(self): authkey = os.urandom(32) + port = test_support.find_unused_port() manager = QueueManager( - address=('localhost', 9999), authkey=authkey, serializer=SERIALIZER) + address=('localhost', port), authkey=authkey, serializer=SERIALIZER) manager.start() p = self.Process(target=self._putter, args=(manager.address, authkey)) @@ -1215,7 +1217,7 @@ del queue manager.shutdown() manager = QueueManager( - address=('localhost', 9999), authkey=authkey, serializer=SERIALIZER) + address=('localhost', port), authkey=authkey, serializer=SERIALIZER) manager.start() manager.shutdown() Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Dec 14 23:18:57 2009 @@ -118,6 +118,9 @@ Tests ----- +- Issue #7498: test_multiprocessing now uses test_support.find_unused_port + instead of a hardcoded port number in test_rapid_restart. + - Issue #7431: use TESTFN in test_linecache instead of trying to create a file in the Lib/test directory, which might be read-only for the user running the tests. From python-checkins at python.org Mon Dec 14 23:45:16 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 22:45:16 -0000 Subject: [Python-checkins] r76843 - in python/branches/py3k: Lib/test/test_multiprocessing.py Misc/NEWS Message-ID: Author: r.david.murray Date: Mon Dec 14 23:45:15 2009 New Revision: 76843 Log: Merged revisions 76840 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76840 | r.david.murray | 2009-12-14 16:57:39 -0500 (Mon, 14 Dec 2009) | 3 lines Issue #7498: make test_multiprocessing use test_support.find_unused_port instead of a hard coded port number in test_rapid_restart. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_multiprocessing.py python/branches/py3k/Misc/NEWS 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 Mon Dec 14 23:45:15 2009 @@ -1213,8 +1213,9 @@ def test_rapid_restart(self): authkey = os.urandom(32) + port = test.support.find_unused_port() manager = QueueManager( - address=('localhost', 9999), authkey=authkey, serializer=SERIALIZER) + address=('localhost', port), authkey=authkey, serializer=SERIALIZER) manager.start() p = self.Process(target=self._putter, args=(manager.address, authkey)) @@ -1224,7 +1225,7 @@ del queue manager.shutdown() manager = QueueManager( - address=('localhost', 9999), authkey=authkey, serializer=SERIALIZER) + address=('localhost', port), authkey=authkey, serializer=SERIALIZER) manager.start() manager.shutdown() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Dec 14 23:45:15 2009 @@ -508,6 +508,9 @@ Tests ----- +- Issue #7498: test_multiprocessing now uses test_support.find_unused_port + instead of a hardcoded port number in test_rapid_restart. + - Issue #7431: use TESTFN in test_linecache instead of trying to create a file in the Lib/test directory, which might be read-only for the user running the tests. From python-checkins at python.org Mon Dec 14 23:57:04 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 22:57:04 -0000 Subject: [Python-checkins] r76844 - in python/branches/release31-maint: Lib/test/test_multiprocessing.py Misc/NEWS Message-ID: Author: r.david.murray Date: Mon Dec 14 23:57:04 2009 New Revision: 76844 Log: Merged revisions 76843 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76843 | r.david.murray | 2009-12-14 17:45:15 -0500 (Mon, 14 Dec 2009) | 10 lines Merged revisions 76840 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76840 | r.david.murray | 2009-12-14 16:57:39 -0500 (Mon, 14 Dec 2009) | 3 lines Issue #7498: make test_multiprocessing use test_support.find_unused_port instead of a hard coded port number in test_rapid_restart. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_multiprocessing.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_multiprocessing.py (original) +++ python/branches/release31-maint/Lib/test/test_multiprocessing.py Mon Dec 14 23:57:04 2009 @@ -1213,8 +1213,9 @@ def test_rapid_restart(self): authkey = os.urandom(32) + port = test.support.find_unused_port() manager = QueueManager( - address=('localhost', 9999), authkey=authkey, serializer=SERIALIZER) + address=('localhost', port), authkey=authkey, serializer=SERIALIZER) manager.start() p = self.Process(target=self._putter, args=(manager.address, authkey)) @@ -1224,7 +1225,7 @@ del queue manager.shutdown() manager = QueueManager( - address=('localhost', 9999), authkey=authkey, serializer=SERIALIZER) + address=('localhost', port), authkey=authkey, serializer=SERIALIZER) manager.start() manager.shutdown() Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Dec 14 23:57:04 2009 @@ -214,6 +214,9 @@ Tests ----- +- Issue #7498: test_multiprocessing now uses test.support.find_unused_port + instead of a hardcoded port number in test_rapid_restart. + - Issue #7431: use TESTFN in test_linecache instead of trying to create a file in the Lib/test directory, which might be read-only for the user running the tests. From python-checkins at python.org Tue Dec 15 00:06:11 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 23:06:11 -0000 Subject: [Python-checkins] r76845 - python/branches/py3k/Misc/NEWS Message-ID: Author: r.david.murray Date: Tue Dec 15 00:06:11 2009 New Revision: 76845 Log: Fix typo in NEWS item for Issue 7498. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Dec 15 00:06:11 2009 @@ -508,7 +508,7 @@ Tests ----- -- Issue #7498: test_multiprocessing now uses test_support.find_unused_port +- Issue #7498: test_multiprocessing now uses test.support.find_unused_port instead of a hardcoded port number in test_rapid_restart. - Issue #7431: use TESTFN in test_linecache instead of trying to create a From python-checkins at python.org Tue Dec 15 00:07:16 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 14 Dec 2009 23:07:16 -0000 Subject: [Python-checkins] r76846 - python/branches/release31-maint Message-ID: Author: r.david.murray Date: Tue Dec 15 00:07:16 2009 New Revision: 76846 Log: Recorded merge of revisions 76845 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76845 | r.david.murray | 2009-12-14 18:06:11 -0500 (Mon, 14 Dec 2009) | 2 lines Fix typo in NEWS item for Issue 7498. ........ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Tue Dec 15 00:49:30 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 15 Dec 2009 00:49:30 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76836): sum=0 Message-ID: <20091214234930.990B117722@ns6635.ovh.net> py3k results for svn r76836 (hg cset 8e1ebee64de5) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogAT_agj', '-x', 'test_httpservers'] From python-checkins at python.org Tue Dec 15 04:25:27 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 15 Dec 2009 03:25:27 -0000 Subject: [Python-checkins] r76847 - python/trunk/Doc/library/ctypes.rst Message-ID: Author: benjamin.peterson Date: Tue Dec 15 04:25:27 2009 New Revision: 76847 Log: adverb Modified: python/trunk/Doc/library/ctypes.rst Modified: python/trunk/Doc/library/ctypes.rst ============================================================================== --- python/trunk/Doc/library/ctypes.rst (original) +++ python/trunk/Doc/library/ctypes.rst Tue Dec 15 04:25:27 2009 @@ -1007,7 +1007,7 @@ >>> It is funny to see that on linux the sort function seems to work much more -efficient, it is doing less comparisons:: +efficiently, it is doing less comparisons:: >>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +LINUX py_cmp_func 5 1 From python-checkins at python.org Tue Dec 15 04:28:18 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 15 Dec 2009 03:28:18 -0000 Subject: [Python-checkins] r76848 - in python/branches/release26-maint: Doc/library/ctypes.rst Message-ID: Author: benjamin.peterson Date: Tue Dec 15 04:28:17 2009 New Revision: 76848 Log: Merged revisions 76847 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76847 | benjamin.peterson | 2009-12-14 21:25:27 -0600 (Mon, 14 Dec 2009) | 1 line adverb ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/ctypes.rst Modified: python/branches/release26-maint/Doc/library/ctypes.rst ============================================================================== --- python/branches/release26-maint/Doc/library/ctypes.rst (original) +++ python/branches/release26-maint/Doc/library/ctypes.rst Tue Dec 15 04:28:17 2009 @@ -1007,7 +1007,7 @@ >>> It is funny to see that on linux the sort function seems to work much more -efficient, it is doing less comparisons:: +efficiently, it is doing less comparisons:: >>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +LINUX py_cmp_func 5 1 From python-checkins at python.org Tue Dec 15 07:29:19 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 15 Dec 2009 06:29:19 -0000 Subject: [Python-checkins] r76849 - python/trunk/Lib/distutils/command/install_data.py Message-ID: Author: tarek.ziade Date: Tue Dec 15 07:29:19 2009 New Revision: 76849 Log: cleaned up the module (PEP 8 + old fashion test removal) Modified: python/trunk/Lib/distutils/command/install_data.py Modified: python/trunk/Lib/distutils/command/install_data.py ============================================================================== --- python/trunk/Lib/distutils/command/install_data.py (original) +++ python/trunk/Lib/distutils/command/install_data.py Tue Dec 15 07:29:19 2009 @@ -8,7 +8,6 @@ __revision__ = "$Id$" import os -from types import StringType from distutils.core import Command from distutils.util import change_root, convert_path @@ -35,7 +34,7 @@ self.data_files = self.distribution.data_files self.warn_dir = 1 - def finalize_options (self): + def finalize_options(self): self.set_undefined_options('install', ('install_data', 'install_dir'), ('root', 'root'), @@ -45,7 +44,7 @@ def run(self): self.mkpath(self.install_dir) for f in self.data_files: - if type(f) is StringType: + if isinstance(f, str): # it's a simple file, so copy it f = convert_path(f) if self.warn_dir: From python-checkins at python.org Tue Dec 15 07:30:35 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 15 Dec 2009 06:30:35 -0000 Subject: [Python-checkins] r76850 - python/branches/py3k Message-ID: Author: tarek.ziade Date: Tue Dec 15 07:30:35 2009 New Revision: 76850 Log: Blocked revisions 76849 via svnmerge ........ r76849 | tarek.ziade | 2009-12-15 07:29:19 +0100 (Tue, 15 Dec 2009) | 1 line cleaned up the module (PEP 8 + old fashion test removal) ........ Modified: python/branches/py3k/ (props changed) From solipsis at pitrou.net Wed Dec 16 00:47:34 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 16 Dec 2009 00:47:34 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76845): sum=0 Message-ID: <20091215234734.CE25117722@ns6635.ovh.net> py3k results for svn r76845 (hg cset 8edad1acc164) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogdoiktZ', '-x', 'test_httpservers'] From python-checkins at python.org Wed Dec 16 04:28:53 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 16 Dec 2009 03:28:53 -0000 Subject: [Python-checkins] r76851 - python/trunk/Lib/test/regrtest.py Message-ID: Author: benjamin.peterson Date: Wed Dec 16 04:28:52 2009 New Revision: 76851 Log: remove lib2to3 resource 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 Wed Dec 16 04:28:52 2009 @@ -113,8 +113,6 @@ curses - Tests that use curses and will modify the terminal's state and output modes. - lib2to3 - Run the tests for 2to3 (They take a while.) - largefile - It is okay to run some test that may create huge files. These tests can take a long time and may consume >2GB of disk space temporarily. From python-checkins at python.org Wed Dec 16 04:36:23 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 16 Dec 2009 03:36:23 -0000 Subject: [Python-checkins] r76852 - python/trunk/Objects/typeobject.c Message-ID: Author: benjamin.peterson Date: Wed Dec 16 04:36:22 2009 New Revision: 76852 Log: remove type_compare, since type_richcompare does the same trick Modified: python/trunk/Objects/typeobject.c Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Wed Dec 16 04:36:22 2009 @@ -610,15 +610,6 @@ {0} }; -static int -type_compare(PyObject *v, PyObject *w) -{ - /* This is called with type objects only. So we - can just compare the addresses. */ - Py_uintptr_t vv = (Py_uintptr_t)v; - Py_uintptr_t ww = (Py_uintptr_t)w; - return (vv < ww) ? -1 : (vv > ww) ? 1 : 0; -} static PyObject* type_richcompare(PyObject *v, PyObject *w, int op) @@ -2745,7 +2736,7 @@ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - type_compare, /* tp_compare */ + 0, /* tp_compare */ (reprfunc)type_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ From python-checkins at python.org Wed Dec 16 04:45:28 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 16 Dec 2009 03:45:28 -0000 Subject: [Python-checkins] r76853 - in python/branches/release26-maint: Objects/typeobject.c Message-ID: Author: benjamin.peterson Date: Wed Dec 16 04:45:28 2009 New Revision: 76853 Log: Merged revisions 76852 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76852 | benjamin.peterson | 2009-12-15 21:36:22 -0600 (Tue, 15 Dec 2009) | 1 line remove type_compare, since type_richcompare does the same trick ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Objects/typeobject.c Modified: python/branches/release26-maint/Objects/typeobject.c ============================================================================== --- python/branches/release26-maint/Objects/typeobject.c (original) +++ python/branches/release26-maint/Objects/typeobject.c Wed Dec 16 04:45:28 2009 @@ -627,15 +627,6 @@ {0} }; -static int -type_compare(PyObject *v, PyObject *w) -{ - /* This is called with type objects only. So we - can just compare the addresses. */ - Py_uintptr_t vv = (Py_uintptr_t)v; - Py_uintptr_t ww = (Py_uintptr_t)w; - return (vv < ww) ? -1 : (vv > ww) ? 1 : 0; -} static PyObject* type_richcompare(PyObject *v, PyObject *w, int op) @@ -2747,7 +2738,7 @@ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - type_compare, /* tp_compare */ + 0, /* tp_compare */ (reprfunc)type_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ From python-checkins at python.org Wed Dec 16 05:27:27 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 16 Dec 2009 04:27:27 -0000 Subject: [Python-checkins] r76854 - python/branches/release26-maint/Lib/test/test_descr.py Message-ID: Author: benjamin.peterson Date: Wed Dec 16 05:27:27 2009 New Revision: 76854 Log: backport change from trunk Modified: python/branches/release26-maint/Lib/test/test_descr.py 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 Wed Dec 16 05:27:27 2009 @@ -1776,6 +1776,8 @@ # Safety test for __cmp__ def unsafecmp(a, b): + if not hasattr(a.__class__, "__cmp__"): + return try: a.__class__.__cmp__(a, b) except TypeError: From python-checkins at python.org Wed Dec 16 11:50:44 2009 From: python-checkins at python.org (kristjan.jonsson) Date: Wed, 16 Dec 2009 10:50:44 -0000 Subject: [Python-checkins] r76855 - in python/branches/py3k: Lib/test/test_xmlrpc.py Lib/xmlrpc/server.py Message-ID: Author: kristjan.jonsson Date: Wed Dec 16 11:50:44 2009 New Revision: 76855 Log: Merged revisions 74558 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r74558 | kristjan.jonsson | 2009-08-27 23:13:18 +0000 (fim., 27 ??g??. 2009) | 2 lines Issue 6654 Allow the XML-RPC server to use the HTTP request path when dispatching. Added a MultiPathXMLRPCServer class that uses the feature, plus unit tests. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_xmlrpc.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 Dec 16 11:50:44 2009 @@ -303,6 +303,66 @@ PORT = None evt.set() +def http_multi_server(evt, numrequests, requestHandler=None): + class TestInstanceClass: + def div(self, x, y): + return x // y + + def _methodHelp(self, name): + if name == 'div': + return 'This is the div function' + + def my_function(): + '''This is my function''' + return True + + class MyXMLRPCServer(xmlrpc.server.MultiPathXMLRPCServer): + def get_request(self): + # Ensure the socket is always non-blocking. On Linux, socket + # attributes are not inherited like they are on *BSD and Windows. + s, port = self.socket.accept() + s.setblocking(True) + return s, port + + if not requestHandler: + requestHandler = xmlrpc.server.SimpleXMLRPCRequestHandler + class MyRequestHandler(requestHandler): + rpc_paths = [] + + serv = MyXMLRPCServer(("localhost", 0), MyRequestHandler, + logRequests=False, bind_and_activate=False) + serv.socket.settimeout(3) + serv.server_bind() + try: + global ADDR, PORT, URL + ADDR, PORT = serv.socket.getsockname() + #connect to IP address directly. This avoids socket.create_connection() + #trying to connect to to "localhost" using all address families, which + #causes slowdown e.g. on vista which supports AF_INET6. The server listens + #on AF_INET only. + URL = "http://%s:%d"%(ADDR, PORT) + serv.server_activate() + paths = ["/foo", "/foo/bar"] + for path in paths: + d = serv.add_dispatcher(path, xmlrpc.server.SimpleXMLRPCDispatcher()) + d.register_introspection_functions() + d.register_multicall_functions() + serv.get_dispatcher(paths[0]).register_function(pow) + serv.get_dispatcher(paths[1]).register_function(lambda x,y: x+y, 'add') + evt.set() + + # handle up to 'numrequests' requests + while numrequests > 0: + serv.handle_request() + numrequests -= 1 + + except socket.timeout: + pass + finally: + serv.socket.close() + PORT = None + evt.set() + # This function prevents errors like: # def is_unavailable_exception(e): @@ -325,6 +385,7 @@ class BaseServerTestCase(unittest.TestCase): requestHandler = None request_count = 1 + threadFunc = staticmethod(http_server) def setUp(self): # enable traceback reporting xmlrpc.server.SimpleXMLRPCServer._send_traceback_header = True @@ -332,7 +393,7 @@ self.evt = threading.Event() # start server thread to handle requests serv_args = (self.evt, self.request_count, self.requestHandler) - threading.Thread(target=http_server, args=serv_args).start() + threading.Thread(target=self.threadFunc, args=serv_args).start() # wait for the server to be ready self.evt.wait() @@ -485,6 +546,18 @@ # This avoids waiting for the socket timeout. self.test_simple1() +class MultiPathServerTestCase(BaseServerTestCase): + threadFunc = staticmethod(http_multi_server) + request_count = 2 + def test_path1(self): + p = xmlrpclib.ServerProxy(URL+"/foo") + self.assertEqual(p.pow(6,8), 6**8) + self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + def test_path2(self): + p = xmlrpclib.ServerProxy(URL+"/foo/bar") + self.assertEqual(p.add(6,8), 6+8) + self.assertRaises(xmlrpclib.Fault, p.pow, 6, 8) + #A test case that verifies that a server using the HTTP/1.1 keep-alive mechanism #does indeed serve subsequent requests on the same connection class BaseKeepaliveServerTestCase(BaseServerTestCase): @@ -810,6 +883,7 @@ xmlrpc_tests.append(GzipServerTestCase) except ImportError: pass #gzip not supported in this build + xmlrpc_tests.append(MultiPathServerTestCase) xmlrpc_tests.append(ServerProxyTestCase) xmlrpc_tests.append(FailingServerTestCase) xmlrpc_tests.append(CGIHandlerTestCase) Modified: python/branches/py3k/Lib/xmlrpc/server.py ============================================================================== --- python/branches/py3k/Lib/xmlrpc/server.py (original) +++ python/branches/py3k/Lib/xmlrpc/server.py Wed Dec 16 11:50:44 2009 @@ -155,8 +155,9 @@ """Mix-in class that dispatches XML-RPC requests. This class is used to register XML-RPC method handlers - and then to dispatch them. There should never be any - reason to instantiate this class directly. + and then to dispatch them. This class doesn't need to be + instanced directly when used by SimpleXMLRPCServer but it + can be instanced when used by the MultiPathXMLRPCServer """ def __init__(self, allow_none=False, encoding=None): @@ -231,7 +232,7 @@ self.funcs.update({'system.multicall' : self.system_multicall}) - def _marshaled_dispatch(self, data, dispatch_method = None): + def _marshaled_dispatch(self, data, dispatch_method = None, path = None): """Dispatches an XML-RPC method from marshalled (XML) data. XML-RPC methods are dispatched from the marshalled (XML) data @@ -488,7 +489,7 @@ # check to see if a subclass implements _dispatch and dispatch # using that method if present. response = self.server._marshaled_dispatch( - data, getattr(self, '_dispatch', None) + data, getattr(self, '_dispatch', None), self.path ) except Exception as e: # This should only happen if the module is buggy # internal error, report as HTTP server error @@ -584,6 +585,44 @@ flags |= fcntl.FD_CLOEXEC fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags) +class MultiPathXMLRPCServer(SimpleXMLRPCServer): + """Multipath XML-RPC Server + This specialization of SimpleXMLRPCServer allows the user to create + multiple Dispatcher instances and assign them to different + HTTP request paths. This makes it possible to run two or more + 'virtual XML-RPC servers' at the same port. + Make sure that the requestHandler accepts the paths in question. + """ + def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler, + logRequests=True, allow_none=False, encoding=None, bind_and_activate=True): + + SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests, allow_none, + encoding, bind_and_activate) + self.dispatchers = {} + self.allow_none = allow_none + self.encoding = encoding + + def add_dispatcher(self, path, dispatcher): + self.dispatchers[path] = dispatcher + return dispatcher + + def get_dispatcher(self, path): + return self.dispatchers[path] + + def _marshaled_dispatch(self, data, dispatch_method = None, path = None): + try: + response = self.dispatchers[path]._marshaled_dispatch( + data, dispatch_method, path) + except: + # report low level exception back to server + # (each dispatcher should have handled their own + # exceptions) + exc_type, exc_value = sys.exc_info()[:2] + response = xmlrpclib.dumps( + xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)), + encoding=self.encoding, allow_none=self.allow_none) + return response + class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): """Simple handler for XML-RPC data passed through CGI.""" From python-checkins at python.org Wed Dec 16 12:49:47 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Dec 2009 11:49:47 -0000 Subject: [Python-checkins] r76856 - in python/trunk: Lib/test/regrtest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Wed Dec 16 12:49:46 2009 New Revision: 76856 Log: Issue #7396: fix -s, which was broken by the -j enhancement. Modified: python/trunk/Lib/test/regrtest.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/regrtest.py ============================================================================== --- python/trunk/Lib/test/regrtest.py (original) +++ python/trunk/Lib/test/regrtest.py Wed Dec 16 12:49:46 2009 @@ -406,9 +406,14 @@ stdtests.remove(arg) nottests[:0] = args args = [] - tests = tests or args or findtests(testdir, stdtests, nottests) + alltests = findtests(testdir, stdtests, nottests) + tests = tests or args or alltests if single: tests = tests[:1] + try: + next_single_test = alltests[alltests.index(tests[0])+1] + except IndexError: + next_single_test = None if randomize: random.seed(random_seed) print "Using random seed", random_seed @@ -613,16 +618,9 @@ raise if single: - alltests = findtests(testdir, stdtests, nottests) - for i in range(len(alltests)): - if tests[0] == alltests[i]: - if i == len(alltests) - 1: - os.unlink(filename) - else: - fp = open(filename, 'w') - fp.write(alltests[i+1] + '\n') - fp.close() - break + if next_single_test: + with open(filename, 'w') as fp: + fp.write(next_single_test + '\n') else: os.unlink(filename) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Dec 16 12:49:46 2009 @@ -46,6 +46,8 @@ Tests ----- +- Issue #7396: fix regrtest -s, which was broken by the -j enhancement. + - Issue #7498: test_multiprocessing now uses test_support.find_unused_port instead of a hardcoded port number in test_rapid_restart. From python-checkins at python.org Wed Dec 16 16:19:28 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Dec 2009 15:19:28 -0000 Subject: [Python-checkins] r76857 - in python/branches/py3k: Lib/test/regrtest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Wed Dec 16 16:19:27 2009 New Revision: 76857 Log: Merged revisions 76856 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76856 | r.david.murray | 2009-12-16 06:49:46 -0500 (Wed, 16 Dec 2009) | 2 lines Issue #7396: fix -s, which was broken by the -j enhancement. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Wed Dec 16 16:19:27 2009 @@ -434,9 +434,14 @@ stdtests.remove(arg) nottests.add(arg) args = [] - tests = tests or args or findtests(testdir, stdtests, nottests) + alltests = findtests(testdir, stdtests, nottests) + tests = tests or args or alltests if single: tests = tests[:1] + try: + next_single_test = alltests[alltests.index(tests[0])+1] + except IndexError: + next_single_test = None # Remove all the tests that precede start if it's set. if start: try: @@ -650,16 +655,9 @@ raise if single: - alltests = findtests(testdir, stdtests, nottests) - for i in range(len(alltests)): - if tests[0] == alltests[i]: - if i == len(alltests) - 1: - os.unlink(filename) - else: - fp = open(filename, 'w') - fp.write(alltests[i+1] + '\n') - fp.close() - break + if next_single_test: + with open(filename, 'w') as fp: + fp.write(next_single_test + '\n') else: os.unlink(filename) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 16 16:19:27 2009 @@ -508,6 +508,8 @@ Tests ----- +- Issue #7396: fix regrtest -s, which was broken by the -j enhancement. + - Issue #7498: test_multiprocessing now uses test.support.find_unused_port instead of a hardcoded port number in test_rapid_restart. From python-checkins at python.org Wed Dec 16 16:19:57 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Dec 2009 15:19:57 -0000 Subject: [Python-checkins] r76858 - python/branches/release26-maint Message-ID: Author: r.david.murray Date: Wed Dec 16 16:19:57 2009 New Revision: 76858 Log: Blocked revisions 76856 via svnmerge ........ r76856 | r.david.murray | 2009-12-16 06:49:46 -0500 (Wed, 16 Dec 2009) | 2 lines Issue #7396: fix -s, which was broken by the -j enhancement. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Dec 16 16:21:44 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Dec 2009 15:21:44 -0000 Subject: [Python-checkins] r76859 - python/branches/release31-maint Message-ID: Author: r.david.murray Date: Wed Dec 16 16:21:43 2009 New Revision: 76859 Log: Blocked revisions 76857 via svnmerge ................ r76857 | r.david.murray | 2009-12-16 10:19:27 -0500 (Wed, 16 Dec 2009) | 9 lines Merged revisions 76856 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76856 | r.david.murray | 2009-12-16 06:49:46 -0500 (Wed, 16 Dec 2009) | 2 lines Issue #7396: fix -s, which was broken by the -j enhancement. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Wed Dec 16 16:52:13 2009 From: python-checkins at python.org (barry.warsaw) Date: Wed, 16 Dec 2009 15:52:13 -0000 Subject: [Python-checkins] r76860 - peps/trunk/pep0/pep.py Message-ID: Author: barry.warsaw Date: Wed Dec 16 16:52:12 2009 New Revision: 76860 Log: Add missing exception. Modified: peps/trunk/pep0/pep.py Modified: peps/trunk/pep0/pep.py ============================================================================== --- peps/trunk/pep0/pep.py (original) +++ peps/trunk/pep0/pep.py Wed Dec 16 16:52:12 2009 @@ -24,6 +24,11 @@ return "(%s): %r" % (self.filename, error_msg) +class PEPParseError(PEPError): + + pass + + class Author(object): """Represent PEP authors. From python-checkins at python.org Wed Dec 16 21:13:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 16 Dec 2009 20:13:41 -0000 Subject: [Python-checkins] r76861 - in python/trunk: Doc/library/math.rst Lib/test/math_testcases.txt Lib/test/test_math.py Misc/NEWS Modules/Setup.dist Modules/_math.c Modules/_math.h Modules/mathmodule.c PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj PC/VS8.0/pythoncore.vcproj PCbuild/pythoncore.vcproj setup.py Message-ID: Author: mark.dickinson Date: Wed Dec 16 21:13:40 2009 New Revision: 76861 Log: Issue #3366: Add expm1 function to math module. Thanks Eric Smith for testing on Windows. Added: python/trunk/Modules/_math.c python/trunk/Modules/_math.h Modified: python/trunk/Doc/library/math.rst python/trunk/Lib/test/math_testcases.txt python/trunk/Lib/test/test_math.py python/trunk/Misc/NEWS python/trunk/Modules/Setup.dist python/trunk/Modules/mathmodule.c 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 python/trunk/setup.py Modified: python/trunk/Doc/library/math.rst ============================================================================== --- python/trunk/Doc/library/math.rst (original) +++ python/trunk/Doc/library/math.rst Wed Dec 16 21:13:40 2009 @@ -164,6 +164,20 @@ Return ``e**x``. +.. function:: expm1(x) + + Return ``e**x - 1``. For small floats *x*, the subtraction in + ``exp(x) - 1`` can result in a significant loss of precision; the + :func:`expm1` function provides a way to compute this quantity to + full precision:: + + >>> from math import exp, expm1 + >>> exp(1e-5) - 1 # gives result accurate to 11 places + 1.0000050000069649e-05 + >>> expm1(1e-5) # result accurate to full precision + 1.0000050000166668e-05 + + .. function:: log(x[, base]) With one argument, return the natural logarithm of *x* (to base *e*). Modified: python/trunk/Lib/test/math_testcases.txt ============================================================================== --- python/trunk/Lib/test/math_testcases.txt (original) +++ python/trunk/Lib/test/math_testcases.txt Wed Dec 16 21:13:40 2009 @@ -249,3 +249,73 @@ -- thanks to loss of accuracy in 1-x gam0140 gamma -63.349078729022985 -> 4.1777971677761880e-88 gam0141 gamma -127.45117632943295 -> 1.1831110896236810e-214 + +----------------------------------------------------------- +-- expm1: exp(x) - 1, without precision loss for small x -- +----------------------------------------------------------- + +-- special values +expm10000 expm1 0.0 -> 0.0 +expm10001 expm1 -0.0 -> -0.0 +expm10002 expm1 inf -> inf +expm10003 expm1 -inf -> -1.0 +expm10004 expm1 nan -> nan + +-- expm1(x) ~ x for tiny x +expm10010 expm1 5e-324 -> 5e-324 +expm10011 expm1 1e-320 -> 1e-320 +expm10012 expm1 1e-300 -> 1e-300 +expm10013 expm1 1e-150 -> 1e-150 +expm10014 expm1 1e-20 -> 1e-20 + +expm10020 expm1 -5e-324 -> -5e-324 +expm10021 expm1 -1e-320 -> -1e-320 +expm10022 expm1 -1e-300 -> -1e-300 +expm10023 expm1 -1e-150 -> -1e-150 +expm10024 expm1 -1e-20 -> -1e-20 + +-- moderate sized values, where direct evaluation runs into trouble +expm10100 expm1 1e-10 -> 1.0000000000500000e-10 +expm10101 expm1 -9.9999999999999995e-08 -> -9.9999995000000163e-8 +expm10102 expm1 3.0000000000000001e-05 -> 3.0000450004500034e-5 +expm10103 expm1 -0.0070000000000000001 -> -0.0069755570667648951 +expm10104 expm1 -0.071499208740094633 -> -0.069002985744820250 +expm10105 expm1 -0.063296004180116799 -> -0.061334416373633009 +expm10106 expm1 0.02390954035597756 -> 0.024197665143819942 +expm10107 expm1 0.085637352649044901 -> 0.089411184580357767 +expm10108 expm1 0.5966174947411006 -> 0.81596588596501485 +expm10109 expm1 0.30247206212075139 -> 0.35319987035848677 +expm10110 expm1 0.74574727375889516 -> 1.1080161116737459 +expm10111 expm1 0.97767512926555711 -> 1.6582689207372185 +expm10112 expm1 0.8450154566787712 -> 1.3280137976535897 +expm10113 expm1 -0.13979260323125264 -> -0.13046144381396060 +expm10114 expm1 -0.52899322039643271 -> -0.41080213643695923 +expm10115 expm1 -0.74083261478900631 -> -0.52328317124797097 +expm10116 expm1 -0.93847766984546055 -> -0.60877704724085946 +expm10117 expm1 10.0 -> 22025.465794806718 +expm10118 expm1 27.0 -> 532048240600.79865 +expm10119 expm1 123 -> 2.6195173187490626e+53 +expm10120 expm1 -12.0 -> -0.99999385578764666 +expm10121 expm1 -35.100000000000001 -> -0.99999999999999944 + +-- extreme negative values +expm10201 expm1 -37.0 -> -0.99999999999999989 +expm10200 expm1 -38.0 -> -1.0 +expm10210 expm1 -710.0 -> -1.0 +-- the formula expm1(x) = 2 * sinh(x/2) * exp(x/2) doesn't work so +-- well when exp(x/2) is subnormal or underflows to zero; check we're +-- not using it! +expm10211 expm1 -1420.0 -> -1.0 +expm10212 expm1 -1450.0 -> -1.0 +expm10213 expm1 -1500.0 -> -1.0 +expm10214 expm1 -1e50 -> -1.0 +expm10215 expm1 -1.79e308 -> -1.0 + +-- extreme positive values +expm10300 expm1 300 -> 1.9424263952412558e+130 +expm10301 expm1 700 -> 1.0142320547350045e+304 +expm10302 expm1 709.78271289328393 -> 1.7976931346824240e+308 +expm10303 expm1 709.78271289348402 -> inf overflow +expm10304 expm1 1000 -> inf overflow +expm10305 expm1 1e50 -> inf overflow +expm10306 expm1 1.79e308 -> inf overflow Modified: python/trunk/Lib/test/test_math.py ============================================================================== --- python/trunk/Lib/test/test_math.py (original) +++ python/trunk/Lib/test/test_math.py Wed Dec 16 21:13:40 2009 @@ -987,17 +987,16 @@ if math.isnan(expected) and math.isnan(got): continue if not math.isnan(expected) and not math.isnan(got): - # we use different closeness criteria for - # different functions. - if fn == 'gamma': - accuracy_failure = ulps_check(expected, got, 20) - elif fn == 'lgamma': + if fn == 'lgamma': + # we use a weaker accuracy test for lgamma; + # lgamma only achieves an absolute error of + # a few multiples of the machine accuracy, in + # general. accuracy_failure = acc_check(expected, got, rel_err = 5e-15, abs_err = 5e-15) else: - raise ValueError("don't know how to check accuracy " - "for this function") + accuracy_failure = ulps_check(expected, got, 20) if accuracy_failure is None: continue Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Dec 16 21:13:40 2009 @@ -1683,7 +1683,7 @@ - Issue #7078: Set struct.__doc__ from _struct.__doc__. -- Issue #3366: Add gamma, lgamma functions to math module. +- Issue #3366: Add expm1, gamma, lgamma functions to math module. - Issue #6823: Allow time.strftime() to accept a tuple with a isdst field outside of the range of [-1, 1] by normalizing the value to within that Modified: python/trunk/Modules/Setup.dist ============================================================================== --- python/trunk/Modules/Setup.dist (original) +++ python/trunk/Modules/Setup.dist Wed Dec 16 21:13:40 2009 @@ -169,7 +169,7 @@ #array arraymodule.c # array objects #cmath cmathmodule.c # -lm # complex math library functions -#math mathmodule.c # -lm # math library functions, e.g. sin() +#math mathmodule.c _math.c # -lm # math library functions, e.g. sin() #_struct _struct.c # binary structure packing/unpacking #time timemodule.c # -lm # time operations and variables #operator operator.c # operator.add() and similar goodies Added: python/trunk/Modules/_math.c ============================================================================== --- (empty file) +++ python/trunk/Modules/_math.c Wed Dec 16 21:13:40 2009 @@ -0,0 +1,31 @@ +/* Definitions of some C99 math library functions, for those platforms + that don't implement these functions already. */ + +#include +#include + +/* Mathematically, expm1(x) = exp(x) - 1. The expm1 function is designed + to avoid the significant loss of precision that arises from direct + evaluation of the expression exp(x) - 1, for x near 0. */ + +double +_Py_expm1(double x) +{ + /* For abs(x) >= log(2), it's safe to evaluate exp(x) - 1 directly; this + also works fine for infinities and nans. + + For smaller x, we can use a method due to Kahan that achieves close to + full accuracy. + */ + + if (fabs(x) < 0.7) { + double u; + u = exp(x); + if (u == 1.0) + return x; + else + return (u - 1.0) * x / log(u); + } + else + return exp(x) - 1.0; +} Added: python/trunk/Modules/_math.h ============================================================================== --- (empty file) +++ python/trunk/Modules/_math.h Wed Dec 16 21:13:40 2009 @@ -0,0 +1,9 @@ +double _Py_expm1(double x); + +#ifdef HAVE_EXPM1 +#define m_expm1 expm1 +#else +/* if the system doesn't have expm1, use the substitute + function defined in Modules/_math.c. */ +#define m_expm1 _Py_expm1 +#endif Modified: python/trunk/Modules/mathmodule.c ============================================================================== --- python/trunk/Modules/mathmodule.c (original) +++ python/trunk/Modules/mathmodule.c Wed Dec 16 21:13:40 2009 @@ -53,6 +53,7 @@ */ #include "Python.h" +#include "_math.h" #include "longintrepr.h" /* just for SHIFT */ #ifdef _OSF_SOURCE @@ -686,6 +687,10 @@ "cosh(x)\n\nReturn the hyperbolic cosine of x.") FUNC1(exp, exp, 1, "exp(x)\n\nReturn e raised to the power of x.") +FUNC1(expm1, m_expm1, 1, + "expm1(x)\n\nReturn exp(x)-1.\n" + "This function avoids the loss of precision involved in the direct " + "evaluation of exp(x)-1 for small x.") FUNC1(fabs, fabs, 0, "fabs(x)\n\nReturn the absolute value of the float x.") FUNC1(floor, floor, 0, @@ -1420,6 +1425,7 @@ {"cosh", math_cosh, METH_O, math_cosh_doc}, {"degrees", math_degrees, METH_O, math_degrees_doc}, {"exp", math_exp, METH_O, math_exp_doc}, + {"expm1", math_expm1, METH_O, math_expm1_doc}, {"fabs", math_fabs, METH_O, math_fabs_doc}, {"factorial", math_factorial, METH_O, math_factorial_doc}, {"floor", math_floor, METH_O, math_floor_doc}, Modified: python/trunk/PC/VC6/pythoncore.dsp ============================================================================== --- python/trunk/PC/VC6/pythoncore.dsp (original) +++ python/trunk/PC/VC6/pythoncore.dsp Wed Dec 16 21:13:40 2009 @@ -161,6 +161,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Modules\_math.c +# End Source File +# Begin Source File + SOURCE=..\..\Modules\_randommodule.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 Wed Dec 16 21:13:40 2009 @@ -389,6 +389,9 @@ RelativePath="..\..\Modules\_lsprof.c"> + + + + + + Modified: python/trunk/PCbuild/pythoncore.vcproj ============================================================================== --- python/trunk/PCbuild/pythoncore.vcproj (original) +++ python/trunk/PCbuild/pythoncore.vcproj Wed Dec 16 21:13:40 2009 @@ -1027,6 +1027,14 @@ > + + + + Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Wed Dec 16 21:13:40 2009 @@ -414,7 +414,7 @@ libraries=math_libs) ) # math library functions, e.g. sin() - exts.append( Extension('math', ['mathmodule.c'], + exts.append( Extension('math', ['mathmodule.c', '_math.c'], libraries=math_libs) ) # fast string operations implemented in C exts.append( Extension('strop', ['stropmodule.c']) ) From python-checkins at python.org Wed Dec 16 21:14:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 16 Dec 2009 20:14:47 -0000 Subject: [Python-checkins] r76862 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Wed Dec 16 21:14:46 2009 New Revision: 76862 Log: Blocked revisions 76861 via svnmerge ........ r76861 | mark.dickinson | 2009-12-16 20:13:40 +0000 (Wed, 16 Dec 2009) | 3 lines Issue #3366: Add expm1 function to math module. Thanks Eric Smith for testing on Windows. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Dec 16 21:23:43 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 16 Dec 2009 20:23:43 -0000 Subject: [Python-checkins] r76863 - in python/branches/py3k: Doc/library/math.rst Lib/test/math_testcases.txt Lib/test/test_math.py Misc/NEWS Modules/Setup.dist Modules/_math.c Modules/_math.h Modules/mathmodule.c PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj PC/VS8.0/pythoncore.vcproj PCbuild/pythoncore.vcproj setup.py Message-ID: Author: mark.dickinson Date: Wed Dec 16 21:23:42 2009 New Revision: 76863 Log: Merged revisions 76861 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76861 | mark.dickinson | 2009-12-16 20:13:40 +0000 (Wed, 16 Dec 2009) | 3 lines Issue #3366: Add expm1 function to math module. Thanks Eric Smith for testing on Windows. ........ Added: python/branches/py3k/Modules/_math.c - copied unchanged from r76861, /python/trunk/Modules/_math.c python/branches/py3k/Modules/_math.h - copied unchanged from r76861, /python/trunk/Modules/_math.h Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/math.rst python/branches/py3k/Lib/test/math_testcases.txt python/branches/py3k/Lib/test/test_math.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/Setup.dist python/branches/py3k/Modules/mathmodule.c 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 python/branches/py3k/setup.py Modified: python/branches/py3k/Doc/library/math.rst ============================================================================== --- python/branches/py3k/Doc/library/math.rst (original) +++ python/branches/py3k/Doc/library/math.rst Wed Dec 16 21:23:42 2009 @@ -148,6 +148,20 @@ Return ``e**x``. +.. function:: expm1(x) + + Return ``e**x - 1``. For small floats *x*, the subtraction in + ``exp(x) - 1`` can result in a significant loss of precision; the + :func:`expm1` function provides a way to compute this quantity to + full precision:: + + >>> from math import exp, expm1 + >>> exp(1e-5) - 1 # gives result accurate to 11 places + 1.0000050000069649e-05 + >>> expm1(1e-5) # result accurate to full precision + 1.0000050000166668e-05 + + .. function:: log(x[, base]) With one argument, return the natural logarithm of *x* (to base *e*). Modified: python/branches/py3k/Lib/test/math_testcases.txt ============================================================================== --- python/branches/py3k/Lib/test/math_testcases.txt (original) +++ python/branches/py3k/Lib/test/math_testcases.txt Wed Dec 16 21:23:42 2009 @@ -249,3 +249,73 @@ -- thanks to loss of accuracy in 1-x gam0140 gamma -63.349078729022985 -> 4.1777971677761880e-88 gam0141 gamma -127.45117632943295 -> 1.1831110896236810e-214 + +----------------------------------------------------------- +-- expm1: exp(x) - 1, without precision loss for small x -- +----------------------------------------------------------- + +-- special values +expm10000 expm1 0.0 -> 0.0 +expm10001 expm1 -0.0 -> -0.0 +expm10002 expm1 inf -> inf +expm10003 expm1 -inf -> -1.0 +expm10004 expm1 nan -> nan + +-- expm1(x) ~ x for tiny x +expm10010 expm1 5e-324 -> 5e-324 +expm10011 expm1 1e-320 -> 1e-320 +expm10012 expm1 1e-300 -> 1e-300 +expm10013 expm1 1e-150 -> 1e-150 +expm10014 expm1 1e-20 -> 1e-20 + +expm10020 expm1 -5e-324 -> -5e-324 +expm10021 expm1 -1e-320 -> -1e-320 +expm10022 expm1 -1e-300 -> -1e-300 +expm10023 expm1 -1e-150 -> -1e-150 +expm10024 expm1 -1e-20 -> -1e-20 + +-- moderate sized values, where direct evaluation runs into trouble +expm10100 expm1 1e-10 -> 1.0000000000500000e-10 +expm10101 expm1 -9.9999999999999995e-08 -> -9.9999995000000163e-8 +expm10102 expm1 3.0000000000000001e-05 -> 3.0000450004500034e-5 +expm10103 expm1 -0.0070000000000000001 -> -0.0069755570667648951 +expm10104 expm1 -0.071499208740094633 -> -0.069002985744820250 +expm10105 expm1 -0.063296004180116799 -> -0.061334416373633009 +expm10106 expm1 0.02390954035597756 -> 0.024197665143819942 +expm10107 expm1 0.085637352649044901 -> 0.089411184580357767 +expm10108 expm1 0.5966174947411006 -> 0.81596588596501485 +expm10109 expm1 0.30247206212075139 -> 0.35319987035848677 +expm10110 expm1 0.74574727375889516 -> 1.1080161116737459 +expm10111 expm1 0.97767512926555711 -> 1.6582689207372185 +expm10112 expm1 0.8450154566787712 -> 1.3280137976535897 +expm10113 expm1 -0.13979260323125264 -> -0.13046144381396060 +expm10114 expm1 -0.52899322039643271 -> -0.41080213643695923 +expm10115 expm1 -0.74083261478900631 -> -0.52328317124797097 +expm10116 expm1 -0.93847766984546055 -> -0.60877704724085946 +expm10117 expm1 10.0 -> 22025.465794806718 +expm10118 expm1 27.0 -> 532048240600.79865 +expm10119 expm1 123 -> 2.6195173187490626e+53 +expm10120 expm1 -12.0 -> -0.99999385578764666 +expm10121 expm1 -35.100000000000001 -> -0.99999999999999944 + +-- extreme negative values +expm10201 expm1 -37.0 -> -0.99999999999999989 +expm10200 expm1 -38.0 -> -1.0 +expm10210 expm1 -710.0 -> -1.0 +-- the formula expm1(x) = 2 * sinh(x/2) * exp(x/2) doesn't work so +-- well when exp(x/2) is subnormal or underflows to zero; check we're +-- not using it! +expm10211 expm1 -1420.0 -> -1.0 +expm10212 expm1 -1450.0 -> -1.0 +expm10213 expm1 -1500.0 -> -1.0 +expm10214 expm1 -1e50 -> -1.0 +expm10215 expm1 -1.79e308 -> -1.0 + +-- extreme positive values +expm10300 expm1 300 -> 1.9424263952412558e+130 +expm10301 expm1 700 -> 1.0142320547350045e+304 +expm10302 expm1 709.78271289328393 -> 1.7976931346824240e+308 +expm10303 expm1 709.78271289348402 -> inf overflow +expm10304 expm1 1000 -> inf overflow +expm10305 expm1 1e50 -> inf overflow +expm10306 expm1 1.79e308 -> inf overflow 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 Wed Dec 16 21:23:42 2009 @@ -984,17 +984,16 @@ if math.isnan(expected) and math.isnan(got): continue if not math.isnan(expected) and not math.isnan(got): - # we use different closeness criteria for - # different functions. - if fn == 'gamma': - accuracy_failure = ulps_check(expected, got, 20) - elif fn == 'lgamma': + if fn == 'lgamma': + # we use a weaker accuracy test for lgamma; + # lgamma only achieves an absolute error of + # a few multiples of the machine accuracy, in + # general. accuracy_failure = acc_check(expected, got, rel_err = 5e-15, abs_err = 5e-15) else: - raise ValueError("don't know how to check accuracy " - "for this function") + accuracy_failure = ulps_check(expected, got, 20) if accuracy_failure is None: continue Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 16 21:23:42 2009 @@ -457,7 +457,7 @@ - Issue #7078: Set struct.__doc__ from _struct.__doc__. -- Issue #3366: Add gamma, lgamma functions to math module. +- Issue #3366: Add expm1, gamma, lgamma functions to math module. - Issue #6877: It is now possible to link the readline extension to the libedit readline emulation on OSX 10.5 or later. Modified: python/branches/py3k/Modules/Setup.dist ============================================================================== --- python/branches/py3k/Modules/Setup.dist (original) +++ python/branches/py3k/Modules/Setup.dist Wed Dec 16 21:23:42 2009 @@ -158,7 +158,7 @@ #array arraymodule.c # array objects #cmath cmathmodule.c # -lm # complex math library functions -#math mathmodule.c # -lm # math library functions, e.g. sin() +#math mathmodule.c _math.c # -lm # math library functions, e.g. sin() #_struct _struct.c # binary structure packing/unpacking #time timemodule.c # -lm # time operations and variables #operator operator.c # operator.add() and similar goodies Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Wed Dec 16 21:23:42 2009 @@ -53,6 +53,7 @@ */ #include "Python.h" +#include "_math.h" #include "longintrepr.h" /* just for SHIFT */ #ifdef _OSF_SOURCE @@ -722,6 +723,10 @@ "cosh(x)\n\nReturn the hyperbolic cosine of x.") FUNC1(exp, exp, 1, "exp(x)\n\nReturn e raised to the power of x.") +FUNC1(expm1, m_expm1, 1, + "expm1(x)\n\nReturn exp(x)-1.\n" + "This function avoids the loss of precision involved in the direct " + "evaluation of exp(x)-1 for small x.") FUNC1(fabs, fabs, 0, "fabs(x)\n\nReturn the absolute value of the float x.") @@ -1493,6 +1498,7 @@ {"cosh", math_cosh, METH_O, math_cosh_doc}, {"degrees", math_degrees, METH_O, math_degrees_doc}, {"exp", math_exp, METH_O, math_exp_doc}, + {"expm1", math_expm1, METH_O, math_expm1_doc}, {"fabs", math_fabs, METH_O, math_fabs_doc}, {"factorial", math_factorial, METH_O, math_factorial_doc}, {"floor", math_floor, METH_O, math_floor_doc}, Modified: python/branches/py3k/PC/VC6/pythoncore.dsp ============================================================================== --- python/branches/py3k/PC/VC6/pythoncore.dsp (original) +++ python/branches/py3k/PC/VC6/pythoncore.dsp Wed Dec 16 21:23:42 2009 @@ -157,6 +157,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Modules\_math.c +# End Source File +# Begin Source File + SOURCE=..\..\Modules\_pickle.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 Wed Dec 16 21:23:42 2009 @@ -409,6 +409,9 @@ RelativePath="..\..\Modules\_lsprof.c"> + + + + + + Modified: python/branches/py3k/PCbuild/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PCbuild/pythoncore.vcproj (original) +++ python/branches/py3k/PCbuild/pythoncore.vcproj Wed Dec 16 21:23:42 2009 @@ -1012,6 +1012,14 @@ > + + + + Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Wed Dec 16 21:23:42 2009 @@ -398,7 +398,7 @@ libraries=math_libs) ) # math library functions, e.g. sin() - exts.append( Extension('math', ['mathmodule.c'], + exts.append( Extension('math', ['mathmodule.c', '_math.c'], libraries=math_libs) ) # time operations and variables exts.append( Extension('time', ['timemodule.c'], From python-checkins at python.org Wed Dec 16 21:24:26 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 16 Dec 2009 20:24:26 -0000 Subject: [Python-checkins] r76864 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Wed Dec 16 21:24:25 2009 New Revision: 76864 Log: Blocked revisions 76863 via svnmerge ................ r76863 | mark.dickinson | 2009-12-16 20:23:42 +0000 (Wed, 16 Dec 2009) | 10 lines Merged revisions 76861 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76861 | mark.dickinson | 2009-12-16 20:13:40 +0000 (Wed, 16 Dec 2009) | 3 lines Issue #3366: Add expm1 function to math module. Thanks Eric Smith for testing on Windows. ........ ................ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Thu Dec 17 00:48:50 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 17 Dec 2009 00:48:50 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76863): sum=24 Message-ID: <20091216234850.B14D717722@ns6635.ovh.net> py3k results for svn r76863 (hg cset 974fc91e1066) -------------------------------------------------- test_multiprocessing leaked [24, 0, 0] references, sum=24 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogWuPRIa', '-x', 'test_httpservers'] From python-checkins at python.org Thu Dec 17 09:33:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 17 Dec 2009 08:33:56 -0000 Subject: [Python-checkins] r76865 - python/trunk/setup.py Message-ID: Author: mark.dickinson Date: Thu Dec 17 09:33:56 2009 New Revision: 76865 Log: Add _math.h to math module dependencies in setup.py. Modified: python/trunk/setup.py Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Thu Dec 17 09:33:56 2009 @@ -415,6 +415,7 @@ # math library functions, e.g. sin() exts.append( Extension('math', ['mathmodule.c', '_math.c'], + depends=['_math.h'], libraries=math_libs) ) # fast string operations implemented in C exts.append( Extension('strop', ['stropmodule.c']) ) From python-checkins at python.org Thu Dec 17 09:34:54 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 17 Dec 2009 08:34:54 -0000 Subject: [Python-checkins] r76866 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Thu Dec 17 09:34:53 2009 New Revision: 76866 Log: Blocked revisions 76865 via svnmerge ........ r76865 | mark.dickinson | 2009-12-17 08:33:56 +0000 (Thu, 17 Dec 2009) | 1 line Add _math.h to math module dependencies in setup.py. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Dec 17 09:35:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 17 Dec 2009 08:35:56 -0000 Subject: [Python-checkins] r76867 - in python/branches/py3k: setup.py Message-ID: Author: mark.dickinson Date: Thu Dec 17 09:35:56 2009 New Revision: 76867 Log: Merged revisions 76865 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76865 | mark.dickinson | 2009-12-17 08:33:56 +0000 (Thu, 17 Dec 2009) | 1 line Add _math.h to math module dependencies in setup.py. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/setup.py Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Thu Dec 17 09:35:56 2009 @@ -399,6 +399,7 @@ # math library functions, e.g. sin() exts.append( Extension('math', ['mathmodule.c', '_math.c'], + depends=['_math.h'], libraries=math_libs) ) # time operations and variables exts.append( Extension('time', ['timemodule.c'], From python-checkins at python.org Thu Dec 17 09:36:46 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 17 Dec 2009 08:36:46 -0000 Subject: [Python-checkins] r76868 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Thu Dec 17 09:36:46 2009 New Revision: 76868 Log: Blocked revisions 76867 via svnmerge ................ r76867 | mark.dickinson | 2009-12-17 08:35:56 +0000 (Thu, 17 Dec 2009) | 9 lines Merged revisions 76865 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76865 | mark.dickinson | 2009-12-17 08:33:56 +0000 (Thu, 17 Dec 2009) | 1 line Add _math.h to math module dependencies in setup.py. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Thu Dec 17 15:52:00 2009 From: python-checkins at python.org (vinay.sajip) Date: Thu, 17 Dec 2009 14:52:00 -0000 Subject: [Python-checkins] r76869 - python/trunk/Doc/library/logging.rst Message-ID: Author: vinay.sajip Date: Thu Dec 17 15:52:00 2009 New Revision: 76869 Log: Issue #7529: logging: Minor correction to documentation. 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 Thu Dec 17 15:52:00 2009 @@ -1681,6 +1681,8 @@ and :meth:`flush` methods). +.. currentmodule:: logging + .. class:: StreamHandler([stream]) Returns a new instance of the :class:`StreamHandler` class. If *stream* is From python-checkins at python.org Fri Dec 18 00:36:28 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 17 Dec 2009 23:36:28 -0000 Subject: [Python-checkins] r76870 - in python/branches/tarek_sysconfig: Lib/distutils/command/bdist.py Lib/distutils/command/bdist_dumb.py Lib/distutils/command/bdist_rpm.py Lib/distutils/command/bdist_wininst.py Lib/distutils/command/build.py Lib/distutils/command/build_ext.py Lib/distutils/command/build_scripts.py Lib/distutils/command/install.py Lib/distutils/extension.py Lib/distutils/sysconfig.py Lib/distutils/tests/support.py Lib/distutils/tests/test_build.py Lib/distutils/tests/test_build_ext.py Lib/distutils/tests/test_extension.py Lib/distutils/tests/test_sysconfig.py Lib/distutils/tests/test_unixccompiler.py Lib/distutils/tests/test_util.py Lib/distutils/unixccompiler.py Lib/distutils/util.py Lib/sysconfig.py Lib/test/test_sysconfig.py Makefile.pre.in Message-ID: Author: tarek.ziade Date: Fri Dec 18 00:36:27 2009 New Revision: 76870 Log: removed functions that where just moved (no deprecation anymore) and fixed usage and distutils tests Modified: python/branches/tarek_sysconfig/Lib/distutils/command/bdist.py python/branches/tarek_sysconfig/Lib/distutils/command/bdist_dumb.py python/branches/tarek_sysconfig/Lib/distutils/command/bdist_rpm.py python/branches/tarek_sysconfig/Lib/distutils/command/bdist_wininst.py python/branches/tarek_sysconfig/Lib/distutils/command/build.py python/branches/tarek_sysconfig/Lib/distutils/command/build_ext.py python/branches/tarek_sysconfig/Lib/distutils/command/build_scripts.py python/branches/tarek_sysconfig/Lib/distutils/command/install.py python/branches/tarek_sysconfig/Lib/distutils/extension.py python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py python/branches/tarek_sysconfig/Lib/distutils/tests/support.py python/branches/tarek_sysconfig/Lib/distutils/tests/test_build.py python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_ext.py python/branches/tarek_sysconfig/Lib/distutils/tests/test_extension.py python/branches/tarek_sysconfig/Lib/distutils/tests/test_sysconfig.py python/branches/tarek_sysconfig/Lib/distutils/tests/test_unixccompiler.py python/branches/tarek_sysconfig/Lib/distutils/tests/test_util.py python/branches/tarek_sysconfig/Lib/distutils/unixccompiler.py python/branches/tarek_sysconfig/Lib/distutils/util.py python/branches/tarek_sysconfig/Lib/sysconfig.py python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py python/branches/tarek_sysconfig/Makefile.pre.in Modified: python/branches/tarek_sysconfig/Lib/distutils/command/bdist.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/command/bdist.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/command/bdist.py Fri Dec 18 00:36:27 2009 @@ -7,10 +7,10 @@ import os from types import * +from sysconfig import get_platform + from distutils.core import Command from distutils.errors import * -from distutils.util import get_platform - def show_formats(): """Print list of available formats (arguments to "--format" option). Modified: python/branches/tarek_sysconfig/Lib/distutils/command/bdist_dumb.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/command/bdist_dumb.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/command/bdist_dumb.py Fri Dec 18 00:36:27 2009 @@ -8,11 +8,11 @@ import os +from sysconfig import get_python_version, get_platform + from distutils.core import Command -from distutils.util import get_platform from distutils.dir_util import remove_tree, ensure_relative from distutils.errors import DistutilsPlatformError -from distutils.sysconfig import get_python_version from distutils import log class bdist_dumb (Command): Modified: python/branches/tarek_sysconfig/Lib/distutils/command/bdist_rpm.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/command/bdist_rpm.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/command/bdist_rpm.py Fri Dec 18 00:36:27 2009 @@ -7,12 +7,12 @@ import sys, os, string from types import * +from sysconfig import get_platform, get_python_version + from distutils.core import Command from distutils.debug import DEBUG -from distutils.util import get_platform from distutils.file_util import write_file from distutils.errors import * -from distutils.sysconfig import get_python_version from distutils import log class bdist_rpm (Command): Modified: python/branches/tarek_sysconfig/Lib/distutils/command/bdist_wininst.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/command/bdist_wininst.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/command/bdist_wininst.py Fri Dec 18 00:36:27 2009 @@ -6,11 +6,11 @@ __revision__ = "$Id$" import sys, os, string +from sysconfig import get_python_version, get_platform + from distutils.core import Command -from distutils.util import get_platform from distutils.dir_util import create_tree, remove_tree from distutils.errors import * -from distutils.sysconfig import get_python_version from distutils import log class bdist_wininst (Command): Modified: python/branches/tarek_sysconfig/Lib/distutils/command/build.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/command/build.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/command/build.py Fri Dec 18 00:36:27 2009 @@ -5,9 +5,10 @@ __revision__ = "$Id$" import sys, os +from sysconfig import get_platform + from distutils.core import Command from distutils.errors import DistutilsOptionError -from distutils.util import get_platform def show_compilers(): from distutils.ccompiler import show_compilers Modified: python/branches/tarek_sysconfig/Lib/distutils/command/build_ext.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/command/build_ext.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/command/build_ext.py Fri Dec 18 00:36:27 2009 @@ -9,12 +9,14 @@ import sys, os, re from warnings import warn +from sysconfig import get_platform + from distutils.core import Command from distutils.errors import * -from distutils.sysconfig import customize_compiler, get_python_version +from distutils.sysconfig import customize_compiler from distutils.dep_util import newer_group from distutils.extension import Extension -from distutils.util import get_platform + from distutils import log # this keeps compatibility from 2.3 to 2.5 @@ -172,8 +174,7 @@ self.user = None def finalize_options(self): - from distutils import sysconfig - + _sysconfig = __import__('sysconfig') self.set_undefined_options('build', ('build_lib', 'build_lib'), ('build_temp', 'build_temp'), @@ -190,8 +191,8 @@ # Make sure Python's include directories (for Python.h, pyconfig.h, # etc.) are in the include search path. - py_include = sysconfig.get_python_inc() - plat_py_include = sysconfig.get_python_inc(plat_specific=1) + py_include = _sysconfig.get_path('include') + plat_py_include = _sysconfig.get_path('platinclude') if self.include_dirs is None: self.include_dirs = self.distribution.include_dirs or [] if isinstance(self.include_dirs, str): @@ -269,7 +270,7 @@ if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): # building third party extensions self.library_dirs.append(os.path.join(sys.prefix, "lib", - "python" + get_python_version(), + "python" + _sysconfig.get_python_version(), "config")) else: # building python standard extensions @@ -277,13 +278,13 @@ # for extensions under Linux or Solaris with a shared Python library, # Python's library directory must be appended to library_dirs - sysconfig.get_config_var('Py_ENABLE_SHARED') + _sysconfig.get_config_var('Py_ENABLE_SHARED') if ((sys.platform.startswith('linux') or sys.platform.startswith('gnu') or sys.platform.startswith('sunos')) - and sysconfig.get_config_var('Py_ENABLE_SHARED')): + and _sysconfig.get_config_var('Py_ENABLE_SHARED')): if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): # building third party extensions - self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) + self.library_dirs.append(_sysconfig.get_config_var('LIBDIR')) else: # building python standard extensions self.library_dirs.append('.') @@ -718,13 +719,13 @@ of the file from which it will be loaded (eg. "foo/bar.so", or "foo\bar.pyd"). """ - from distutils.sysconfig import get_config_var + _sysconfig = __import__('sysconfig') ext_path = ext_name.split('.') # OS/2 has an 8 character module (extension) limit :-( if os.name == "os2": ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8] # extensions in debug_mode are named 'module_d.pyd' under windows - so_ext = get_config_var('SO') + so_ext = _sysconfig.get_config_var('SO') if os.name == 'nt' and self.debug: return os.path.join(*ext_path) + '_d' + so_ext return os.path.join(*ext_path) + so_ext @@ -784,14 +785,13 @@ # extensions, it is a reference to the original list return ext.libraries + [pythonlib] elif sys.platform[:6] == "atheos": - from distutils import sysconfig - + _sysconfig = __import__('sysconfig') template = "python%d.%d" pythonlib = (template % (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) # Get SHLIBS from Makefile extra = [] - for lib in sysconfig.get_config_var('SHLIBS').split(): + for lib in _sysconfig.get_config_var('SHLIBS').split(): if lib.startswith('-l'): extra.append(lib[2:]) else: @@ -805,8 +805,8 @@ return ext.libraries else: - from distutils import sysconfig - if sysconfig.get_config_var('Py_ENABLE_SHARED'): + _sysconfig = __import__('sysconfig') + if _sysconfig.get_config_var('Py_ENABLE_SHARED'): template = "python%d.%d" pythonlib = (template % (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) Modified: python/branches/tarek_sysconfig/Lib/distutils/command/build_scripts.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/command/build_scripts.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/command/build_scripts.py Fri Dec 18 00:36:27 2009 @@ -6,7 +6,6 @@ import os, re from stat import ST_MODE -from distutils import sysconfig from distutils.core import Command from distutils.dep_util import newer from distutils.util import convert_path @@ -57,6 +56,7 @@ ie. starts with "\#!" and contains "python"), then adjust the first line to refer to the current Python interpreter as we copy. """ + _sysconfig = __import__('sysconfig') self.mkpath(self.build_dir) outfiles = [] for script in self.scripts: @@ -94,16 +94,16 @@ self.build_dir) if not self.dry_run: outf = open(outfile, "w") - if not sysconfig.python_build: + if not _sysconfig.is_python_build(): outf.write("#!%s%s\n" % (self.executable, post_interp)) else: outf.write("#!%s%s\n" % (os.path.join( - sysconfig.get_config_var("BINDIR"), - "python%s%s" % (sysconfig.get_config_var("VERSION"), - sysconfig.get_config_var("EXE"))), + _sysconfig.get_config_var("BINDIR"), + "python%s%s" % (_sysconfig.get_config_var("VERSION"), + _sysconfig.get_config_var("EXE"))), post_interp)) outf.writelines(f.readlines()) outf.close() Modified: python/branches/tarek_sysconfig/Lib/distutils/command/install.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/command/install.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/command/install.py Fri Dec 18 00:36:27 2009 @@ -7,14 +7,14 @@ import sys import os +from sysconfig import get_config_vars, get_platform + from distutils import log from distutils.core import Command from distutils.debug import DEBUG -from distutils.sysconfig import get_config_vars from distutils.errors import DistutilsPlatformError from distutils.file_util import write_file from distutils.util import convert_path, subst_vars, change_root -from distutils.util import get_platform from distutils.errors import DistutilsOptionError # this keeps compatibility from 2.3 to 2.5 Modified: python/branches/tarek_sysconfig/Lib/distutils/extension.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/extension.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/extension.py Fri Dec 18 00:36:27 2009 @@ -135,14 +135,17 @@ def read_setup_file(filename): """Reads a Setup file and returns Extension instances.""" - from distutils.sysconfig import (parse_makefile, expand_makefile_vars, + warnings.warn('distutils.extensions.read_setup_file is deprecated. ' + 'It will be removed in the next Python release.') + _sysconfig = __import__('sysconfig') + from distutils.sysconfig import (expand_makefile_vars, _variable_rx) from distutils.text_file import TextFile from distutils.util import split_quoted # First pass over the file to gather "VAR = VALUE" assignments. - vars = parse_makefile(filename) + vars = _sysconfig._parse_makefile(filename) # Second pass to gobble up the real content: lines of the form # ... [ ...] [ ...] [ ...] @@ -162,7 +165,10 @@ file.warn("'%s' lines not handled yet" % line) continue - line = expand_makefile_vars(line, vars) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + line = expand_makefile_vars(line, vars) + words = split_quoted(line) # NB. this parses a slightly different syntax than the old Modified: python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py Fri Dec 18 00:36:27 2009 @@ -32,8 +32,9 @@ """ if compiler.compiler_type == "unix": (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ - get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO', 'AR', 'ARFLAGS') + _sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', + 'CCSHARED', 'LDSHARED', 'SO', 'AR', + 'ARFLAGS') if 'CC' in os.environ: cc = os.environ['CC'] @@ -91,20 +92,10 @@ return super(_DeprecatedBool, self).__nonzero__() def _python_build(): - return _DeprecatedBool(_sysconfig._PYTHON_BUILD) + return _DeprecatedBool(_sysconfig.is_python_build()) python_build = _python_build() -def get_python_version(): - """This function is deprecated. - - Return a string containing the major and minor Python version, - leaving off the patchlevel. Sample return values could be '1.5' - or '2.2'. - """ - warn(_DEPRECATION_MSG % 'get_python_version', DeprecationWarning) - return _sysconfig.get_python_version() - def get_python_inc(plat_specific=0, prefix=None): """This function is deprecated. @@ -125,7 +116,7 @@ vars = {'base': prefix} return get_path('include', vars=vars) - if plat_specific: + if not plat_specific: return get_path('include') else: return get_path('platinclude') @@ -241,28 +232,3 @@ else: break return s - -def get_config_vars(*args): - """This function is deprecated. - - With no arguments, return a dictionary of all configuration - variables relevant for the current platform. Generally this includes - everything needed to build extensions and install both pure modules and - extensions. On Unix, this means every variable defined in Python's - installed Makefile; on Windows and Mac OS it's a much smaller set. - - With arguments, return a list of values that result from looking up - each argument in the configuration variable dictionary. - """ - warn(_DEPRECATION_MSG % 'get_config_vars', DeprecationWarning) - return _sysconfig.get_config_vars(*args) - -def get_config_var(name): - """This function is deprecated. - - Return the value of a single variable using the dictionary - returned by 'get_config_vars()'. Equivalent to - get_config_vars().get(name) - """ - warn(_DEPRECATION_MSG % 'get_config_var', DeprecationWarning) - return _sysconfig.get_config_var(name) Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/support.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/support.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/support.py Fri Dec 18 00:36:27 2009 @@ -3,11 +3,19 @@ import shutil import tempfile from copy import deepcopy +import warnings from distutils import log from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils.core import Distribution +def capture_warnings(func): + def _capture_warnings(*args, **kw): + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + return func(*args, **kw) + return _capture_warnings + class LoggingSilencer(object): def setUp(self): Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/test_build.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/test_build.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/test_build.py Fri Dec 18 00:36:27 2009 @@ -5,7 +5,7 @@ from distutils.command.build import build from distutils.tests import support -from distutils.util import get_platform +from sysconfig import get_platform class BuildTestCase(support.TempdirManager, support.LoggingSilencer, Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_ext.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_ext.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_ext.py Fri Dec 18 00:36:27 2009 @@ -177,11 +177,10 @@ cmd = build_ext(dist) cmd.finalize_options() - from distutils import sysconfig - py_include = sysconfig.get_python_inc() + py_include = sysconfig.get_path('include') self.assertTrue(py_include in cmd.include_dirs) - plat_py_include = sysconfig.get_python_inc(plat_specific=1) + plat_py_include = sysconfig.get_path('platinclude') self.assertTrue(plat_py_include in cmd.include_dirs) # make sure cmd.libraries is turned into a list Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/test_extension.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/test_extension.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/test_extension.py Fri Dec 18 00:36:27 2009 @@ -5,9 +5,11 @@ from test.test_support import check_warnings from distutils.extension import read_setup_file, Extension +from distutils.tests import support class ExtensionTestCase(unittest.TestCase): + @support.capture_warnings def test_read_setup_file(self): # trying to read a Setup file # (sample extracted from the PyGame project) Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/test_sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/test_sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/test_sysconfig.py Fri Dec 18 00:36:27 2009 @@ -27,10 +27,12 @@ elif os.path.isdir(path): shutil.rmtree(path) + @support.capture_warnings def test_get_config_h_filename(self): config_h = sysconfig.get_config_h_filename() self.assertTrue(os.path.isfile(config_h), config_h) + @support.capture_warnings def test_get_python_lib(self): lib_dir = sysconfig.get_python_lib() # XXX doesn't work on Linux when Python was never installed before @@ -39,20 +41,17 @@ self.assertNotEqual(sysconfig.get_python_lib(), sysconfig.get_python_lib(prefix=TESTFN)) + @support.capture_warnings def test_get_python_inc(self): inc_dir = sysconfig.get_python_inc() # This is not much of a test. We make sure Python.h exists # in the directory returned by get_python_inc() but we don't know # it is the correct file. + self.assertTrue(os.path.isdir(inc_dir), inc_dir) python_h = os.path.join(inc_dir, "Python.h") self.assertTrue(os.path.isfile(python_h), python_h) - def test_get_config_vars(self): - cvars = sysconfig.get_config_vars() - self.assertTrue(isinstance(cvars, dict)) - self.assertTrue(cvars) - def test_customize_compiler(self): # not testing if default compiler is not unix @@ -73,6 +72,7 @@ sysconfig.customize_compiler(comp) self.assertEquals(comp.exes['archiver'], 'my_ar -arflags') + @support.capture_warnings def test_parse_makefile_base(self): self.makefile = test.test_support.TESTFN fd = open(self.makefile, 'w') Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/test_unixccompiler.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/test_unixccompiler.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/test_unixccompiler.py Fri Dec 18 00:36:27 2009 @@ -2,7 +2,7 @@ import sys import unittest -from distutils import sysconfig +import sysconfig from distutils.unixccompiler import UnixCCompiler class UnixCCompilerTestCase(unittest.TestCase): Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/test_util.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/test_util.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/test_util.py Fri Dec 18 00:36:27 2009 @@ -6,15 +6,14 @@ from StringIO import StringIO import subprocess +from sysconfig import get_config_vars, get_platform from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError -from distutils.util import (get_platform, convert_path, change_root, +from distutils.util import (convert_path, change_root, check_environ, split_quoted, strtobool, rfc822_escape, get_compiler_versions, _find_exe_version, _MAC_OS_X_LD_VERSION, byte_compile) from distutils import util -from distutils.sysconfig import get_config_vars -from distutils import sysconfig from distutils.tests import support from distutils.version import LooseVersion Modified: python/branches/tarek_sysconfig/Lib/distutils/unixccompiler.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/unixccompiler.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/unixccompiler.py Fri Dec 18 00:36:27 2009 @@ -17,8 +17,9 @@ import os, sys from types import StringType, NoneType +sysconfig = __import__('sysconfig') +#import sysconfig -from distutils import sysconfig from distutils.dep_util import newer from distutils.ccompiler import \ CCompiler, gen_preprocess_options, gen_lib_options @@ -75,7 +76,7 @@ if 'ARCHFLAGS' in os.environ and not stripArch: # User specified different -arch flags in the environ, - # see also distutils.sysconfig + # see also sysconfig compiler_so = compiler_so + os.environ['ARCHFLAGS'].split() if stripSysroot: Modified: python/branches/tarek_sysconfig/Lib/distutils/util.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/util.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/util.py Fri Dec 18 00:36:27 2009 @@ -18,38 +18,6 @@ _sysconfig = __import__('sysconfig') -def get_platform(): - """This function is deprecated. - - Return a string that identifies the current platform. - - This is used mainly to distinguish platform-specific build directories and - platform-specific built distributions. Typically includes the OS name - and version and the architecture (as supplied by 'os.uname()'), - although the exact information included depends on the OS; eg. for IRIX - the architecture isn't particularly important (IRIX only runs on SGI - hardware), but for Linux the kernel version isn't particularly - important. - - Examples of returned values: - linux-i586 - linux-alpha (?) - solaris-2.6-sun4u - irix-5.3 - irix64-6.2 - - Windows will return one of: - win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) - win-ia64 (64bit Windows on Itanium) - win32 (all others - specifically, sys.platform is returned) - - For other non-POSIX platforms, currently just returns 'sys.platform'. - """ - msg = ("distutils.sysconfig.get_platform is deprecated. " - "Use sysconfig.get_platform instead.") - warn(msg, DeprecationWarning) - return _sysconfig.get_platform() - def convert_path(pathname): """Return 'pathname' as a name that will work on the native filesystem. @@ -136,7 +104,7 @@ os.environ['HOME'] = pwd.getpwuid(os.getuid())[5] if 'PLAT' not in os.environ: - os.environ['PLAT'] = get_platform() + os.environ['PLAT'] = _sysconfig.get_platform() _environ_checked = 1 Modified: python/branches/tarek_sysconfig/Lib/sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/sysconfig.py Fri Dec 18 00:36:27 2009 @@ -56,10 +56,10 @@ 'data' : '$userbase', }, 'nt_user': { - 'stdlib': '$userbase/Python/$py_version_nodot', - 'platstdlib': '$userbase/Python/$py_version_nodot', - 'purelib': '$userbase/Python/$py_version_nodot/site-packages', - 'platlib': '$userbase/Python/$py_version_nodot/site-packages', + 'stdlib': '$userbase/Python$py_version_nodot', + 'platstdlib': '$userbase/Python$py_version_nodot', + 'purelib': '$userbase/Python$py_version_nodot/site-packages', + 'platlib': '$userbase/Python$py_version_nodot/site-packages', 'include': '$userbase/Python$py_version_nodot/Include', 'scripts': '$userbase/Scripts', 'data' : '$userbase', @@ -95,18 +95,18 @@ if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): _PROJECT_BASE = abspath(os.path.join(_PROJECT_BASE, pardir, pardir)) -def _python_build(): +def is_python_build(): for fn in ("Setup.dist", "Setup.local"): if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): return True return False -_PYTHON_BUILD = _python_build() +_PYTHON_BUILD = is_python_build() if _PYTHON_BUILD: for scheme in ('posix_prefix', 'posix_home'): - _INSTALL_SCHEMES[scheme]['include'] = '$projectbase' - _INSTALL_SCHEMES[scheme]['platinclude'] = '$srcdir/Include' + _INSTALL_SCHEMES[scheme]['include'] = '$projectbase/Include' + _INSTALL_SCHEMES[scheme]['platinclude'] = '$srcdir' def _subst_vars(s, local_vars): import re Modified: python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py Fri Dec 18 00:36:27 2009 @@ -90,8 +90,8 @@ # XXX make it os independant scheme = get_paths() wanted = [('data', '/usr/local'), - ('include', '/Users/tarek/Dev/svn.python.org/tarek_sysconfig'), - ('platinclude', './Include'), + ('include', '/Users/tarek/Dev/svn.python.org/tarek_sysconfig/Include'), + ('platinclude', '.'), ('platlib', '/usr/local/lib/python'), ('platstdlib', '/usr/local/lib/python'), ('purelib', '/usr/local/lib/python'), Modified: python/branches/tarek_sysconfig/Makefile.pre.in ============================================================================== --- python/branches/tarek_sysconfig/Makefile.pre.in (original) +++ python/branches/tarek_sysconfig/Makefile.pre.in Fri Dec 18 00:36:27 2009 @@ -393,7 +393,7 @@ $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) platform: $(BUILDPYTHON) - $(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from distutils.util import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform + $(RUNSHARED) ./$(BUILDPYTHON) -E -c 'import sys ; from sysconfig import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform # Build the shared modules From solipsis at pitrou.net Fri Dec 18 00:48:44 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 18 Dec 2009 00:48:44 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76867): sum=0 Message-ID: <20091217234845.1B4B017722@ns6635.ovh.net> py3k results for svn r76867 (hg cset e3f72d6d79c3) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogfSGGUI', '-x', 'test_httpservers'] From python-checkins at python.org Fri Dec 18 03:49:21 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 18 Dec 2009 02:49:21 -0000 Subject: [Python-checkins] r76871 - in sandbox/trunk/2to3/lib2to3: main.py tests/test_main.py Message-ID: Author: benjamin.peterson Date: Fri Dec 18 03:49:21 2009 New Revision: 76871 Log: handle unencodable diffs gracefully #5093 Added: sandbox/trunk/2to3/lib2to3/tests/test_main.py Modified: sandbox/trunk/2to3/lib2to3/main.py Modified: sandbox/trunk/2to3/lib2to3/main.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/main.py (original) +++ sandbox/trunk/2to3/lib2to3/main.py Fri Dec 18 03:49:21 2009 @@ -60,8 +60,14 @@ else: self.log_message("Refactored %s", filename) if self.show_diffs: - for line in diff_texts(old, new, filename): - print line + diff_lines = diff_texts(old, new, filename) + try: + for line in diff_lines: + print line + except UnicodeEncodeError: + warn("couldn't encode %s's diff for your terminal" % + (filename,)) + return def warn(msg): Added: sandbox/trunk/2to3/lib2to3/tests/test_main.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/lib2to3/tests/test_main.py Fri Dec 18 03:49:21 2009 @@ -0,0 +1,36 @@ +# coding: utf-8 +import sys +import codecs +import StringIO +import unittest + +from lib2to3 import main + + +class TestMain(unittest.TestCase): + + def run_2to3_capture(self, args, in_capture, out_capture, err_capture): + save_stdin = sys.stdin + save_stdout = sys.stdout + save_stderr = sys.stderr + sys.stdin = in_capture + sys.stdout = out_capture + sys.stderr = err_capture + try: + return main.main("lib2to3.fixes", args) + finally: + sys.stdin = save_stdin + sys.stdout = save_stdout + sys.stderr = save_stderr + + def test_unencodable_diff(self): + input_stream = StringIO.StringIO(u"print 'nothing'\nprint u'?ber'\n") + out = StringIO.StringIO() + out_enc = codecs.getwriter("ascii")(out) + err = StringIO.StringIO() + ret = self.run_2to3_capture(["-"], input_stream, out_enc, err) + self.assertEqual(ret, 0) + output = out.getvalue() + self.assertTrue("-print 'nothing'" in output) + self.assertTrue("WARNING: couldn't encode 's diff for " + "your terminal" in err.getvalue()) From python-checkins at python.org Fri Dec 18 03:51:37 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 18 Dec 2009 02:51:37 -0000 Subject: [Python-checkins] r76872 - sandbox/trunk/2to3/lib2to3/tests/test_main.py Message-ID: Author: benjamin.peterson Date: Fri Dec 18 03:51:37 2009 New Revision: 76872 Log: fix emacs header Modified: sandbox/trunk/2to3/lib2to3/tests/test_main.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_main.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_main.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_main.py Fri Dec 18 03:51:37 2009 @@ -1,4 +1,4 @@ -# coding: utf-8 +# -*- coding: utf-8 -*- import sys import codecs import StringIO From nnorwitz at gmail.com Fri Dec 18 08:35:18 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 18 Dec 2009 07:35:18 -0000 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091126212443.GA28582@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 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_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 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_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn 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 [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_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 [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization 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_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 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 [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_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 /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import 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 339 tests OK. 1 test failed: test_threading_local 36 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_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [881221 refs] From nnorwitz at gmail.com Tue Dec 15 23:55:55 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 15 Dec 2009 17:55:55 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091215225555.GA27076@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [-91, 0, 0] references, sum=-91 Less important issues: ---------------------- From nnorwitz at gmail.com Tue Dec 15 11:55:58 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 15 Dec 2009 05:55:58 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (2) Message-ID: <20091215105558.GA28798@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [0, 0, 91] references, sum=91 test_itertools leaked [0, 0, 32] references, sum=32 Less important issues: ---------------------- From nnorwitz at gmail.com Sun Dec 13 22:28:08 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 13 Dec 2009 16:28:08 -0500 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20091213212808.GA17941@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_ftplib 36 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_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 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_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn fetching http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml ... fetching http://people.freebsd.org/~perky/i18n/EUC-CN.TXT ... fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT ... test_codecmaps_hk fetching http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT ... test_codecmaps_jp fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT ... fetching http://people.freebsd.org/~perky/i18n/EUC-JISX0213.TXT ... fetching http://people.freebsd.org/~perky/i18n/EUC-JP.TXT ... fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT ... fetching http://people.freebsd.org/~perky/i18n/SHIFT_JISX0213.TXT ... test_codecmaps_kr fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT ... fetching http://people.freebsd.org/~perky/i18n/EUC-KR.TXT ... fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT ... test_codecmaps_tw fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT ... fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT ... test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test test_ftplib failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_ftplib.py", line 495, in test_storlines self.client.storlines('stor foo', f, callback=lambda x: flag.append(None)) File "/tmp/python-test/local/lib/python2.7/ftplib.py", line 749, in storlines return self.voidresp() File "/tmp/python-test/local/lib/python2.7/ftplib.py", line 224, in voidresp resp = self.getresp() File "/tmp/python-test/local/lib/python2.7/ftplib.py", line 210, in getresp resp = self.getmultiline() File "/tmp/python-test/local/lib/python2.7/ftplib.py", line 196, in getmultiline line = self.getline() File "/tmp/python-test/local/lib/python2.7/ftplib.py", line 183, in getline line = self.file.readline() File "/tmp/python-test/local/lib/python2.7/socket.py", line 444, in readline data = self._sock.recv(self._rbufsize) File "/tmp/python-test/local/lib/python2.7/ssl.py", line 96, in self.recv = lambda buflen=1024, flags=0: SSLSocket.recv(self, buflen, flags) File "/tmp/python-test/local/lib/python2.7/ssl.py", line 222, in recv raise x SSLError: The read operation timed out 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 [15429 refs] [15429 refs] [15429 refs] [25455 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization fetching http://www.unicode.org/Public/5.1.0/ucd/NormalizationTest.txt ... 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_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 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 [20940 refs] [20940 refs] [20940 refs] [20940 refs] [20940 refs] [20939 refs] [20939 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20320 refs] [20134 refs] [20134 refs] [20134 refs] [20134 refs] test_threading_local test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_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 /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import 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 339 tests OK. 1 test failed: test_ftplib 36 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_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [866075 refs] From python-checkins at python.org Fri Dec 18 15:30:10 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 18 Dec 2009 14:30:10 -0000 Subject: [Python-checkins] r76873 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Fri Dec 18 15:30:10 2009 New Revision: 76873 Log: added a not about environment markers on the intro Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Fri Dec 18 15:30:10 2009 @@ -29,8 +29,7 @@ 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". - +Maintainer-email". This new version also adds `environment markers`. Fields ====== From python-checkins at python.org Fri Dec 18 16:30:51 2009 From: python-checkins at python.org (ezio.melotti) Date: Fri, 18 Dec 2009 15:30:51 -0000 Subject: [Python-checkins] r76874 - in python/branches/release26-maint: Lib/test/test_strptime.py Message-ID: Author: ezio.melotti Date: Fri Dec 18 16:30:51 2009 New Revision: 76874 Log: Merged revisions 76804 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76804 | ezio.melotti | 2009-12-13 20:54:53 +0200 (Sun, 13 Dec 2009) | 1 line #7342: make sure that the datetime object in test_fraction always has a number of microseconds != 0 ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_strptime.py Modified: python/branches/release26-maint/Lib/test/test_strptime.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_strptime.py (original) +++ python/branches/release26-maint/Lib/test/test_strptime.py Fri Dec 18 16:30:51 2009 @@ -274,10 +274,11 @@ self.helper('S', 5) def test_fraction(self): + # Test microseconds import datetime - now = datetime.datetime.now() - tup, frac = _strptime._strptime(str(now), format="%Y-%m-%d %H:%M:%S.%f") - self.assertEqual(frac, now.microsecond) + d = datetime.datetime(2012, 12, 20, 12, 34, 56, 78987) + tup, frac = _strptime._strptime(str(d), format="%Y-%m-%d %H:%M:%S.%f") + self.assertEqual(frac, d.microsecond) def test_weekday(self): # Test weekday directives From python-checkins at python.org Fri Dec 18 16:35:27 2009 From: python-checkins at python.org (ezio.melotti) Date: Fri, 18 Dec 2009 15:35:27 -0000 Subject: [Python-checkins] r76875 - in python/branches/py3k: Lib/test/test_strptime.py Message-ID: Author: ezio.melotti Date: Fri Dec 18 16:35:27 2009 New Revision: 76875 Log: Merged revisions 76804 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76804 | ezio.melotti | 2009-12-13 20:54:53 +0200 (Sun, 13 Dec 2009) | 1 line #7342: make sure that the datetime object in test_fraction always has a number of microseconds != 0 ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_strptime.py Modified: python/branches/py3k/Lib/test/test_strptime.py ============================================================================== --- python/branches/py3k/Lib/test/test_strptime.py (original) +++ python/branches/py3k/Lib/test/test_strptime.py Fri Dec 18 16:35:27 2009 @@ -274,10 +274,11 @@ self.helper('S', 5) def test_fraction(self): + # Test microseconds import datetime - now = datetime.datetime.now() - tup, frac = _strptime._strptime(str(now), format="%Y-%m-%d %H:%M:%S.%f") - self.assertEqual(frac, now.microsecond) + d = datetime.datetime(2012, 12, 20, 12, 34, 56, 78987) + tup, frac = _strptime._strptime(str(d), format="%Y-%m-%d %H:%M:%S.%f") + self.assertEqual(frac, d.microsecond) def test_weekday(self): # Test weekday directives From python-checkins at python.org Fri Dec 18 16:37:49 2009 From: python-checkins at python.org (ezio.melotti) Date: Fri, 18 Dec 2009 15:37:49 -0000 Subject: [Python-checkins] r76876 - in python/branches/release31-maint: Lib/test/test_strptime.py Message-ID: Author: ezio.melotti Date: Fri Dec 18 16:37:48 2009 New Revision: 76876 Log: Merged revisions 76875 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76875 | ezio.melotti | 2009-12-18 17:35:27 +0200 (Fri, 18 Dec 2009) | 9 lines Merged revisions 76804 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76804 | ezio.melotti | 2009-12-13 20:54:53 +0200 (Sun, 13 Dec 2009) | 1 line #7342: make sure that the datetime object in test_fraction always has a number of microseconds != 0 ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_strptime.py Modified: python/branches/release31-maint/Lib/test/test_strptime.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_strptime.py (original) +++ python/branches/release31-maint/Lib/test/test_strptime.py Fri Dec 18 16:37:48 2009 @@ -274,10 +274,11 @@ self.helper('S', 5) def test_fraction(self): + # Test microseconds import datetime - now = datetime.datetime.now() - tup, frac = _strptime._strptime(str(now), format="%Y-%m-%d %H:%M:%S.%f") - self.assertEqual(frac, now.microsecond) + d = datetime.datetime(2012, 12, 20, 12, 34, 56, 78987) + tup, frac = _strptime._strptime(str(d), format="%Y-%m-%d %H:%M:%S.%f") + self.assertEqual(frac, d.microsecond) def test_weekday(self): # Test weekday directives From python-checkins at python.org Fri Dec 18 21:23:25 2009 From: python-checkins at python.org (ezio.melotti) Date: Fri, 18 Dec 2009 20:23:25 -0000 Subject: [Python-checkins] r76877 - in python/branches/release26-maint: Lib/test/test_cpickle.py Message-ID: Author: ezio.melotti Date: Fri Dec 18 21:23:24 2009 New Revision: 76877 Log: Merged revisions 70531 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70531 | benjamin.peterson | 2009-03-23 00:24:58 +0200 (Mon, 23 Mar 2009) | 1 line AttributeError can be thrown during recursion errors ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_cpickle.py Modified: python/branches/release26-maint/Lib/test/test_cpickle.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_cpickle.py (original) +++ python/branches/release26-maint/Lib/test/test_cpickle.py Fri Dec 18 21:23:24 2009 @@ -107,7 +107,7 @@ for n in nodes: n.connections = list(nodes) n.connections.remove(n) - self.assertRaises(RuntimeError, cPickle.dumps, n) + self.assertRaises((AttributeError, RuntimeError), cPickle.dumps, n) def test_issue3179(self): # Safe test, because I broke this case when fixing the From solipsis at pitrou.net Sat Dec 19 00:48:07 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 19 Dec 2009 00:48:07 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76875): sum=0 Message-ID: <20091218234807.6C67317722@ns6635.ovh.net> py3k results for svn r76875 (hg cset 9b8588434e3d) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogzmiv0d', '-x', 'test_httpservers'] From python-checkins at python.org Sat Dec 19 12:07:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 19 Dec 2009 11:07:23 -0000 Subject: [Python-checkins] r76878 - in python/trunk: Doc/library/math.rst Lib/test/math_testcases.txt Misc/NEWS Modules/mathmodule.c Message-ID: Author: mark.dickinson Date: Sat Dec 19 12:07:23 2009 New Revision: 76878 Log: Issue #3366: Add error function and complementary error function to math module. Modified: python/trunk/Doc/library/math.rst python/trunk/Lib/test/math_testcases.txt python/trunk/Misc/NEWS python/trunk/Modules/mathmodule.c Modified: python/trunk/Doc/library/math.rst ============================================================================== --- python/trunk/Doc/library/math.rst (original) +++ python/trunk/Doc/library/math.rst Sat Dec 19 12:07:23 2009 @@ -177,6 +177,8 @@ >>> expm1(1e-5) # result accurate to full precision 1.0000050000166668e-05 + .. versionadded:: 2.7 + .. function:: log(x[, base]) @@ -325,6 +327,20 @@ Special functions ----------------- +.. function:: erf(x) + + Return the error function at *x*. + + .. versionadded:: 2.7 + + +.. function:: erfc(x) + + Return the complementary error function at *x*. + + .. versionadded:: 2.7 + + .. function:: gamma(x) Return the Gamma function at *x*. Modified: python/trunk/Lib/test/math_testcases.txt ============================================================================== --- python/trunk/Lib/test/math_testcases.txt (original) +++ python/trunk/Lib/test/math_testcases.txt Sat Dec 19 12:07:23 2009 @@ -47,6 +47,87 @@ -- MPFR homepage at http://www.mpfr.org for more information about the -- MPFR project. + +------------------------- +-- erf: error function -- +------------------------- + +erf0000 erf 0.0 -> 0.0 +erf0001 erf -0.0 -> -0.0 +erf0002 erf inf -> 1.0 +erf0003 erf -inf -> -1.0 +erf0004 erf nan -> nan + +-- tiny values +erf0010 erf 1e-308 -> 1.1283791670955125e-308 +erf0011 erf 5e-324 -> 4.9406564584124654e-324 +erf0012 erf 1e-10 -> 1.1283791670955126e-10 + +-- small integers +erf0020 erf 1 -> 0.84270079294971489 +erf0021 erf 2 -> 0.99532226501895271 +erf0022 erf 3 -> 0.99997790950300136 +erf0023 erf 4 -> 0.99999998458274209 +erf0024 erf 5 -> 0.99999999999846256 +erf0025 erf 6 -> 1.0 + +erf0030 erf -1 -> -0.84270079294971489 +erf0031 erf -2 -> -0.99532226501895271 +erf0032 erf -3 -> -0.99997790950300136 +erf0033 erf -4 -> -0.99999998458274209 +erf0034 erf -5 -> -0.99999999999846256 +erf0035 erf -6 -> -1.0 + +-- huge values should all go to +/-1, depending on sign +erf0040 erf -40 -> -1.0 +erf0041 erf 1e16 -> 1.0 +erf0042 erf -1e150 -> -1.0 +erf0043 erf 1.7e308 -> 1.0 + + +---------------------------------------- +-- erfc: complementary error function -- +---------------------------------------- + +erfc0000 erfc 0.0 -> 1.0 +erfc0001 erfc -0.0 -> 1.0 +erfc0002 erfc inf -> 0.0 +erfc0003 erfc -inf -> 2.0 +erfc0004 erfc nan -> nan + +-- tiny values +erfc0010 erfc 1e-308 -> 1.0 +erfc0011 erfc 5e-324 -> 1.0 +erfc0012 erfc 1e-10 -> 0.99999999988716204 + +-- small integers +erfc0020 erfc 1 -> 0.15729920705028513 +erfc0021 erfc 2 -> 0.0046777349810472662 +erfc0022 erfc 3 -> 2.2090496998585441e-05 +erfc0023 erfc 4 -> 1.541725790028002e-08 +erfc0024 erfc 5 -> 1.5374597944280349e-12 +erfc0025 erfc 6 -> 2.1519736712498913e-17 + +erfc0030 erfc -1 -> 1.8427007929497148 +erfc0031 erfc -2 -> 1.9953222650189528 +erfc0032 erfc -3 -> 1.9999779095030015 +erfc0033 erfc -4 -> 1.9999999845827421 +erfc0034 erfc -5 -> 1.9999999999984626 +erfc0035 erfc -6 -> 2.0 + +-- as x -> infinity, erfc(x) behaves like exp(-x*x)/x/sqrt(pi) +erfc0040 erfc 20 -> 5.3958656116079012e-176 +erfc0041 erfc 25 -> 8.3001725711965228e-274 +erfc0042 erfc 27 -> 5.2370464393526292e-319 +erfc0043 erfc 28 -> 0.0 + +-- huge values +erfc0050 erfc -40 -> 2.0 +erfc0051 erfc 1e16 -> 0.0 +erfc0052 erfc -1e150 -> 2.0 +erfc0053 erfc 1.7e308 -> 0.0 + + --------------------------------------------------------- -- lgamma: log of absolute value of the gamma function -- --------------------------------------------------------- @@ -250,6 +331,7 @@ gam0140 gamma -63.349078729022985 -> 4.1777971677761880e-88 gam0141 gamma -127.45117632943295 -> 1.1831110896236810e-214 + ----------------------------------------------------------- -- expm1: exp(x) - 1, without precision loss for small x -- ----------------------------------------------------------- Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Dec 19 12:07:23 2009 @@ -1683,7 +1683,8 @@ - Issue #7078: Set struct.__doc__ from _struct.__doc__. -- Issue #3366: Add expm1, gamma, lgamma functions to math module. +- Issue #3366: Add erf, erfc, expm1, gamma, lgamma functions to math + module. - Issue #6823: Allow time.strftime() to accept a tuple with a isdst field outside of the range of [-1, 1] by normalizing the value to within that Modified: python/trunk/Modules/mathmodule.c ============================================================================== --- python/trunk/Modules/mathmodule.c (original) +++ python/trunk/Modules/mathmodule.c Sat Dec 19 12:07:23 2009 @@ -69,6 +69,7 @@ */ static const double pi = 3.141592653589793238462643383279502884197; +static const double sqrtpi = 1.772453850905516027298167483341145182798; static double sinpi(double x) @@ -375,6 +376,141 @@ return r; } +/* + Implementations of the error function erf(x) and the complementary error + function erfc(x). + + Method: following 'Numerical Recipes' by Flannery, Press et. al. (2nd ed., + Cambridge University Press), we use a series approximation for erf for + small x, and a continued fraction approximation for erfc(x) for larger x; + combined with the relations erf(-x) = -erf(x) and erfc(x) = 1.0 - erf(x), + this gives us erf(x) and erfc(x) for all x. + + The series expansion used is: + + erf(x) = x*exp(-x*x)/sqrt(pi) * [ + 2/1 + 4/3 x**2 + 8/15 x**4 + 16/105 x**6 + ...] + + The coefficient of x**(2k-2) here is 4**k*factorial(k)/factorial(2*k). + This series converges well for smallish x, but slowly for larger x. + + The continued fraction expansion used is: + + erfc(x) = x*exp(-x*x)/sqrt(pi) * [1/(0.5 + x**2 -) 0.5/(2.5 + x**2 - ) + 3.0/(4.5 + x**2 - ) 7.5/(6.5 + x**2 - ) ...] + + after the first term, the general term has the form: + + k*(k-0.5)/(2*k+0.5 + x**2 - ...). + + This expansion converges fast for larger x, but convergence becomes + infinitely slow as x approaches 0.0. The (somewhat naive) continued + fraction evaluation algorithm used below also risks overflow for large x; + but for large x, erfc(x) == 0.0 to within machine precision. (For + example, erfc(30.0) is approximately 2.56e-393). + + Parameters: use series expansion for abs(x) < ERF_SERIES_CUTOFF and + continued fraction expansion for ERF_SERIES_CUTOFF <= abs(x) < + ERFC_CONTFRAC_CUTOFF. ERFC_SERIES_TERMS and ERFC_CONTFRAC_TERMS are the + numbers of terms to use for the relevant expansions. */ + +#define ERF_SERIES_CUTOFF 1.5 +#define ERF_SERIES_TERMS 25 +#define ERFC_CONTFRAC_CUTOFF 30.0 +#define ERFC_CONTFRAC_TERMS 50 + +/* + Error function, via power series. + + Given a finite float x, return an approximation to erf(x). + Converges reasonably fast for small x. +*/ + +static double +m_erf_series(double x) +{ + double x2, acc, fk; + int i; + + x2 = x * x; + acc = 0.0; + fk = (double)ERF_SERIES_TERMS + 0.5; + for (i = 0; i < ERF_SERIES_TERMS; i++) { + acc = 2.0 + x2 * acc / fk; + fk -= 1.0; + } + return acc * x * exp(-x2) / sqrtpi; +} + +/* + Complementary error function, via continued fraction expansion. + + Given a positive float x, return an approximation to erfc(x). Converges + reasonably fast for x large (say, x > 2.0), and should be safe from + overflow if x and nterms are not too large. On an IEEE 754 machine, with x + <= 30.0, we're safe up to nterms = 100. For x >= 30.0, erfc(x) is smaller + than the smallest representable nonzero float. */ + +static double +m_erfc_contfrac(double x) +{ + double x2, a, da, p, p_last, q, q_last, b; + int i; + + if (x >= ERFC_CONTFRAC_CUTOFF) + return 0.0; + + x2 = x*x; + a = 0.0; + da = 0.5; + p = 1.0; p_last = 0.0; + q = da + x2; q_last = 1.0; + for (i = 0; i < ERFC_CONTFRAC_TERMS; i++) { + double temp; + a += da; + da += 2.0; + b = da + x2; + temp = p; p = b*p - a*p_last; p_last = temp; + temp = q; q = b*q - a*q_last; q_last = temp; + } + return p / q * x * exp(-x2) / sqrtpi; +} + +/* Error function erf(x), for general x */ + +static double +m_erf(double x) +{ + double absx, cf; + + if (Py_IS_NAN(x)) + return x; + absx = fabs(x); + if (absx < ERF_SERIES_CUTOFF) + return m_erf_series(x); + else { + cf = m_erfc_contfrac(absx); + return x > 0.0 ? 1.0 - cf : cf - 1.0; + } +} + +/* Complementary error function erfc(x), for general x. */ + +static double +m_erfc(double x) +{ + double absx, cf; + + if (Py_IS_NAN(x)) + return x; + absx = fabs(x); + if (absx < ERF_SERIES_CUTOFF) + return 1.0 - m_erf_series(x); + else { + cf = m_erfc_contfrac(absx); + return x > 0.0 ? cf : 2.0 - cf; + } +} /* wrapper for atan2 that deals directly with special cases before @@ -685,6 +821,10 @@ "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh, 1, "cosh(x)\n\nReturn the hyperbolic cosine of x.") +FUNC1A(erf, m_erf, + "erf(x)\n\nError function at x.") +FUNC1A(erfc, m_erfc, + "erfc(x)\n\nComplementary error function at x.") FUNC1(exp, exp, 1, "exp(x)\n\nReturn e raised to the power of x.") FUNC1(expm1, m_expm1, 1, @@ -1424,6 +1564,8 @@ {"cos", math_cos, METH_O, math_cos_doc}, {"cosh", math_cosh, METH_O, math_cosh_doc}, {"degrees", math_degrees, METH_O, math_degrees_doc}, + {"erf", math_erf, METH_O, math_erf_doc}, + {"erfc", math_erfc, METH_O, math_erfc_doc}, {"exp", math_exp, METH_O, math_exp_doc}, {"expm1", math_expm1, METH_O, math_expm1_doc}, {"fabs", math_fabs, METH_O, math_fabs_doc}, From python-checkins at python.org Sat Dec 19 12:20:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 19 Dec 2009 11:20:49 -0000 Subject: [Python-checkins] r76879 - in python/branches/py3k: Doc/library/math.rst Lib/test/math_testcases.txt Misc/NEWS Modules/mathmodule.c Message-ID: Author: mark.dickinson Date: Sat Dec 19 12:20:49 2009 New Revision: 76879 Log: Merged revisions 76878 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76878 | mark.dickinson | 2009-12-19 11:07:23 +0000 (Sat, 19 Dec 2009) | 3 lines Issue #3366: Add error function and complementary error function to math module. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/math.rst python/branches/py3k/Lib/test/math_testcases.txt python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/mathmodule.c Modified: python/branches/py3k/Doc/library/math.rst ============================================================================== --- python/branches/py3k/Doc/library/math.rst (original) +++ python/branches/py3k/Doc/library/math.rst Sat Dec 19 12:20:49 2009 @@ -161,6 +161,8 @@ >>> expm1(1e-5) # result accurate to full precision 1.0000050000166668e-05 + .. versionadded:: 3.2 + .. function:: log(x[, base]) @@ -295,6 +297,20 @@ Special functions ----------------- +.. function:: erf(x) + + Return the error function at *x*. + + .. versionadded:: 3.2 + + +.. function:: erfc(x) + + Return the complementary error function at *x*. + + .. versionadded:: 3.2 + + .. function:: gamma(x) Return the Gamma function at *x*. @@ -307,7 +323,7 @@ Return the natural logarithm of the absolute value of the Gamma function at *x*. - .. versionadded:: 2.7 + .. versionadded:: 3.2 Constants Modified: python/branches/py3k/Lib/test/math_testcases.txt ============================================================================== --- python/branches/py3k/Lib/test/math_testcases.txt (original) +++ python/branches/py3k/Lib/test/math_testcases.txt Sat Dec 19 12:20:49 2009 @@ -47,6 +47,87 @@ -- MPFR homepage at http://www.mpfr.org for more information about the -- MPFR project. + +------------------------- +-- erf: error function -- +------------------------- + +erf0000 erf 0.0 -> 0.0 +erf0001 erf -0.0 -> -0.0 +erf0002 erf inf -> 1.0 +erf0003 erf -inf -> -1.0 +erf0004 erf nan -> nan + +-- tiny values +erf0010 erf 1e-308 -> 1.1283791670955125e-308 +erf0011 erf 5e-324 -> 4.9406564584124654e-324 +erf0012 erf 1e-10 -> 1.1283791670955126e-10 + +-- small integers +erf0020 erf 1 -> 0.84270079294971489 +erf0021 erf 2 -> 0.99532226501895271 +erf0022 erf 3 -> 0.99997790950300136 +erf0023 erf 4 -> 0.99999998458274209 +erf0024 erf 5 -> 0.99999999999846256 +erf0025 erf 6 -> 1.0 + +erf0030 erf -1 -> -0.84270079294971489 +erf0031 erf -2 -> -0.99532226501895271 +erf0032 erf -3 -> -0.99997790950300136 +erf0033 erf -4 -> -0.99999998458274209 +erf0034 erf -5 -> -0.99999999999846256 +erf0035 erf -6 -> -1.0 + +-- huge values should all go to +/-1, depending on sign +erf0040 erf -40 -> -1.0 +erf0041 erf 1e16 -> 1.0 +erf0042 erf -1e150 -> -1.0 +erf0043 erf 1.7e308 -> 1.0 + + +---------------------------------------- +-- erfc: complementary error function -- +---------------------------------------- + +erfc0000 erfc 0.0 -> 1.0 +erfc0001 erfc -0.0 -> 1.0 +erfc0002 erfc inf -> 0.0 +erfc0003 erfc -inf -> 2.0 +erfc0004 erfc nan -> nan + +-- tiny values +erfc0010 erfc 1e-308 -> 1.0 +erfc0011 erfc 5e-324 -> 1.0 +erfc0012 erfc 1e-10 -> 0.99999999988716204 + +-- small integers +erfc0020 erfc 1 -> 0.15729920705028513 +erfc0021 erfc 2 -> 0.0046777349810472662 +erfc0022 erfc 3 -> 2.2090496998585441e-05 +erfc0023 erfc 4 -> 1.541725790028002e-08 +erfc0024 erfc 5 -> 1.5374597944280349e-12 +erfc0025 erfc 6 -> 2.1519736712498913e-17 + +erfc0030 erfc -1 -> 1.8427007929497148 +erfc0031 erfc -2 -> 1.9953222650189528 +erfc0032 erfc -3 -> 1.9999779095030015 +erfc0033 erfc -4 -> 1.9999999845827421 +erfc0034 erfc -5 -> 1.9999999999984626 +erfc0035 erfc -6 -> 2.0 + +-- as x -> infinity, erfc(x) behaves like exp(-x*x)/x/sqrt(pi) +erfc0040 erfc 20 -> 5.3958656116079012e-176 +erfc0041 erfc 25 -> 8.3001725711965228e-274 +erfc0042 erfc 27 -> 5.2370464393526292e-319 +erfc0043 erfc 28 -> 0.0 + +-- huge values +erfc0050 erfc -40 -> 2.0 +erfc0051 erfc 1e16 -> 0.0 +erfc0052 erfc -1e150 -> 2.0 +erfc0053 erfc 1.7e308 -> 0.0 + + --------------------------------------------------------- -- lgamma: log of absolute value of the gamma function -- --------------------------------------------------------- @@ -250,6 +331,7 @@ gam0140 gamma -63.349078729022985 -> 4.1777971677761880e-88 gam0141 gamma -127.45117632943295 -> 1.1831110896236810e-214 + ----------------------------------------------------------- -- expm1: exp(x) - 1, without precision loss for small x -- ----------------------------------------------------------- Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Dec 19 12:20:49 2009 @@ -457,7 +457,7 @@ - Issue #7078: Set struct.__doc__ from _struct.__doc__. -- Issue #3366: Add expm1, gamma, lgamma functions to math module. +- Issue #3366: Add erf, erfc, expm1, gamma, lgamma functions to math module. - Issue #6877: It is now possible to link the readline extension to the libedit readline emulation on OSX 10.5 or later. Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Sat Dec 19 12:20:49 2009 @@ -69,6 +69,7 @@ */ static const double pi = 3.141592653589793238462643383279502884197; +static const double sqrtpi = 1.772453850905516027298167483341145182798; static double sinpi(double x) @@ -375,6 +376,141 @@ return r; } +/* + Implementations of the error function erf(x) and the complementary error + function erfc(x). + + Method: following 'Numerical Recipes' by Flannery, Press et. al. (2nd ed., + Cambridge University Press), we use a series approximation for erf for + small x, and a continued fraction approximation for erfc(x) for larger x; + combined with the relations erf(-x) = -erf(x) and erfc(x) = 1.0 - erf(x), + this gives us erf(x) and erfc(x) for all x. + + The series expansion used is: + + erf(x) = x*exp(-x*x)/sqrt(pi) * [ + 2/1 + 4/3 x**2 + 8/15 x**4 + 16/105 x**6 + ...] + + The coefficient of x**(2k-2) here is 4**k*factorial(k)/factorial(2*k). + This series converges well for smallish x, but slowly for larger x. + + The continued fraction expansion used is: + + erfc(x) = x*exp(-x*x)/sqrt(pi) * [1/(0.5 + x**2 -) 0.5/(2.5 + x**2 - ) + 3.0/(4.5 + x**2 - ) 7.5/(6.5 + x**2 - ) ...] + + after the first term, the general term has the form: + + k*(k-0.5)/(2*k+0.5 + x**2 - ...). + + This expansion converges fast for larger x, but convergence becomes + infinitely slow as x approaches 0.0. The (somewhat naive) continued + fraction evaluation algorithm used below also risks overflow for large x; + but for large x, erfc(x) == 0.0 to within machine precision. (For + example, erfc(30.0) is approximately 2.56e-393). + + Parameters: use series expansion for abs(x) < ERF_SERIES_CUTOFF and + continued fraction expansion for ERF_SERIES_CUTOFF <= abs(x) < + ERFC_CONTFRAC_CUTOFF. ERFC_SERIES_TERMS and ERFC_CONTFRAC_TERMS are the + numbers of terms to use for the relevant expansions. */ + +#define ERF_SERIES_CUTOFF 1.5 +#define ERF_SERIES_TERMS 25 +#define ERFC_CONTFRAC_CUTOFF 30.0 +#define ERFC_CONTFRAC_TERMS 50 + +/* + Error function, via power series. + + Given a finite float x, return an approximation to erf(x). + Converges reasonably fast for small x. +*/ + +static double +m_erf_series(double x) +{ + double x2, acc, fk; + int i; + + x2 = x * x; + acc = 0.0; + fk = (double)ERF_SERIES_TERMS + 0.5; + for (i = 0; i < ERF_SERIES_TERMS; i++) { + acc = 2.0 + x2 * acc / fk; + fk -= 1.0; + } + return acc * x * exp(-x2) / sqrtpi; +} + +/* + Complementary error function, via continued fraction expansion. + + Given a positive float x, return an approximation to erfc(x). Converges + reasonably fast for x large (say, x > 2.0), and should be safe from + overflow if x and nterms are not too large. On an IEEE 754 machine, with x + <= 30.0, we're safe up to nterms = 100. For x >= 30.0, erfc(x) is smaller + than the smallest representable nonzero float. */ + +static double +m_erfc_contfrac(double x) +{ + double x2, a, da, p, p_last, q, q_last, b; + int i; + + if (x >= ERFC_CONTFRAC_CUTOFF) + return 0.0; + + x2 = x*x; + a = 0.0; + da = 0.5; + p = 1.0; p_last = 0.0; + q = da + x2; q_last = 1.0; + for (i = 0; i < ERFC_CONTFRAC_TERMS; i++) { + double temp; + a += da; + da += 2.0; + b = da + x2; + temp = p; p = b*p - a*p_last; p_last = temp; + temp = q; q = b*q - a*q_last; q_last = temp; + } + return p / q * x * exp(-x2) / sqrtpi; +} + +/* Error function erf(x), for general x */ + +static double +m_erf(double x) +{ + double absx, cf; + + if (Py_IS_NAN(x)) + return x; + absx = fabs(x); + if (absx < ERF_SERIES_CUTOFF) + return m_erf_series(x); + else { + cf = m_erfc_contfrac(absx); + return x > 0.0 ? 1.0 - cf : cf - 1.0; + } +} + +/* Complementary error function erfc(x), for general x. */ + +static double +m_erfc(double x) +{ + double absx, cf; + + if (Py_IS_NAN(x)) + return x; + absx = fabs(x); + if (absx < ERF_SERIES_CUTOFF) + return 1.0 - m_erf_series(x); + else { + cf = m_erfc_contfrac(absx); + return x > 0.0 ? cf : 2.0 - cf; + } +} /* wrapper for atan2 that deals directly with special cases before @@ -721,6 +857,10 @@ "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh, 1, "cosh(x)\n\nReturn the hyperbolic cosine of x.") +FUNC1A(erf, m_erf, + "erf(x)\n\nError function at x.") +FUNC1A(erfc, m_erfc, + "erfc(x)\n\nComplementary error function at x.") FUNC1(exp, exp, 1, "exp(x)\n\nReturn e raised to the power of x.") FUNC1(expm1, m_expm1, 1, @@ -1497,6 +1637,8 @@ {"cos", math_cos, METH_O, math_cos_doc}, {"cosh", math_cosh, METH_O, math_cosh_doc}, {"degrees", math_degrees, METH_O, math_degrees_doc}, + {"erf", math_erf, METH_O, math_erf_doc}, + {"erfc", math_erfc, METH_O, math_erfc_doc}, {"exp", math_exp, METH_O, math_exp_doc}, {"expm1", math_expm1, METH_O, math_expm1_doc}, {"fabs", math_fabs, METH_O, math_fabs_doc}, From python-checkins at python.org Sat Dec 19 12:22:11 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 19 Dec 2009 11:22:11 -0000 Subject: [Python-checkins] r76880 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sat Dec 19 12:22:10 2009 New Revision: 76880 Log: Blocked revisions 76878 via svnmerge ........ r76878 | mark.dickinson | 2009-12-19 11:07:23 +0000 (Sat, 19 Dec 2009) | 3 lines Issue #3366: Add error function and complementary error function to math module. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Dec 19 12:22:40 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 19 Dec 2009 11:22:40 -0000 Subject: [Python-checkins] r76881 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sat Dec 19 12:22:40 2009 New Revision: 76881 Log: Blocked revisions 76879 via svnmerge ................ r76879 | mark.dickinson | 2009-12-19 11:20:49 +0000 (Sat, 19 Dec 2009) | 10 lines Merged revisions 76878 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76878 | mark.dickinson | 2009-12-19 11:07:23 +0000 (Sat, 19 Dec 2009) | 3 lines Issue #3366: Add error function and complementary error function to math module. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sat Dec 19 18:30:29 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 17:30:29 -0000 Subject: [Python-checkins] r76882 - python/trunk/Doc/library/string.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 18:30:28 2009 New Revision: 76882 Log: #7527: use standard versionadded tags. Modified: python/trunk/Doc/library/string.rst Modified: python/trunk/Doc/library/string.rst ============================================================================== --- python/trunk/Doc/library/string.rst (original) +++ python/trunk/Doc/library/string.rst Sat Dec 19 18:30:28 2009 @@ -105,7 +105,9 @@ String Formatting ----------------- -Starting in Python 2.6, the built-in str and unicode classes provide the ability +.. versionadded:: 2.6 + +The built-in str and unicode classes provide the ability to do complex variable substitutions and value formatting via the :meth:`str.format` method described in :pep:`3101`. The :class:`Formatter` class in the :mod:`string` module allows you to create and customize your own @@ -488,6 +490,8 @@ Template strings ---------------- +.. versionadded:: 2.4 + Templates provide simpler string substitutions as described in :pep:`292`. Instead of the normal ``%``\ -based substitutions, Templates support ``$``\ -based substitutions, using the following rules: @@ -506,8 +510,6 @@ Any other appearance of ``$`` in the string will result in a :exc:`ValueError` being raised. -.. versionadded:: 2.4 - The :mod:`string` module provides a :class:`Template` class that implements these rules. The methods of :class:`Template` are: From python-checkins at python.org Sat Dec 19 18:34:32 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 17:34:32 -0000 Subject: [Python-checkins] r76883 - python/trunk/Doc/c-api/init.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 18:34:32 2009 New Revision: 76883 Log: #7521: remove Py_GetBuildNumber(), which was removed in favor of Py_GetBuildInfo(). 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 Dec 19 18:34:32 2009 @@ -284,15 +284,6 @@ modify its value. The value is available to Python code as ``sys.version``. -.. cfunction:: const char* Py_GetBuildNumber() - - Return a string representing the Subversion revision that this Python executable - was built from. This number is a string because it may contain a trailing 'M' - if Python was built from a mixed revision source tree. - - .. versionadded:: 2.5 - - .. cfunction:: const char* Py_GetPlatform() .. index:: single: platform (in module sys) From python-checkins at python.org Sat Dec 19 18:35:49 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 17:35:49 -0000 Subject: [Python-checkins] r76884 - in python/branches/py3k: Doc/c-api/init.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 18:35:49 2009 New Revision: 76884 Log: Merged revisions 76883 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76883 | georg.brandl | 2009-12-19 18:34:32 +0100 (Sa, 19 Dez 2009) | 1 line #7521: remove Py_GetBuildNumber(), which was removed in favor of Py_GetBuildInfo(). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/init.rst Modified: python/branches/py3k/Doc/c-api/init.rst ============================================================================== --- python/branches/py3k/Doc/c-api/init.rst (original) +++ python/branches/py3k/Doc/c-api/init.rst Sat Dec 19 18:35:49 2009 @@ -283,13 +283,6 @@ modify its value. The value is available to Python code as :data:`sys.version`. -.. cfunction:: const char* Py_GetBuildNumber() - - Return a string representing the Subversion revision that this Python executable - was built from. This number is a string because it may contain a trailing 'M' - if Python was built from a mixed revision source tree. - - .. cfunction:: const char* Py_GetPlatform() .. index:: single: platform (in module sys) From python-checkins at python.org Sat Dec 19 18:36:20 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 17:36:20 -0000 Subject: [Python-checkins] r76885 - python/branches/py3k/Doc/c-api/reflection.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 18:36:20 2009 New Revision: 76885 Log: #7521: remove PyEval_GetRestricted() from the docs. Modified: python/branches/py3k/Doc/c-api/reflection.rst Modified: python/branches/py3k/Doc/c-api/reflection.rst ============================================================================== --- python/branches/py3k/Doc/c-api/reflection.rst (original) +++ python/branches/py3k/Doc/c-api/reflection.rst Sat Dec 19 18:36:20 2009 @@ -34,12 +34,6 @@ Return the line number that *frame* is currently executing. -.. cfunction:: int PyEval_GetRestricted() - - If there is a current frame and it is executing in restricted mode, return true, - otherwise false. - - .. cfunction:: const char* PyEval_GetFuncName(PyObject *func) Return the name of *func* if it is a function, class or instance object, else the From python-checkins at python.org Sat Dec 19 18:43:34 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 17:43:34 -0000 Subject: [Python-checkins] r76886 - python/trunk/Doc/faq/design.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 18:43:33 2009 New Revision: 76886 Log: #7493: review of Design FAQ by Florent Xicluna. Modified: python/trunk/Doc/faq/design.rst Modified: python/trunk/Doc/faq/design.rst ============================================================================== --- python/trunk/Doc/faq/design.rst (original) +++ python/trunk/Doc/faq/design.rst Sat Dec 19 18:43:33 2009 @@ -7,7 +7,7 @@ Guido van Rossum believes that using indentation for grouping is extremely elegant and contributes a lot to the clarity of the average Python program. -Most people learn to love this feature after awhile. +Most people learn to love this feature after a while. Since there are no begin/end brackets there cannot be a disagreement between grouping perceived by the parser and the human reader. Occasionally C @@ -48,7 +48,7 @@ People are often very surprised by results like this:: - >>> 1.2-1.0 + >>> 1.2 - 1.0 0.199999999999999996 and think it is a bug in Python. It's not. This has nothing to do with Python, @@ -85,7 +85,7 @@ ``==`` fails. Instead, you have to check that the difference between the two numbers is less than a certain threshold:: - epsilon = 0.0000000000001 # Tiny allowed error + epsilon = 0.0000000000001 # Tiny allowed error expected_result = 0.4 if expected_result-epsilon <= computation() <= expected_result+epsilon: @@ -131,24 +131,25 @@ Second, it means that no special syntax is necessary if you want to explicitly reference or call the method from a particular class. In C++, if you want to use a method from a base class which is overridden in a derived class, you have -to use the ``::`` operator -- in Python you can write baseclass.methodname(self, -). This is particularly useful for :meth:`__init__` methods, and -in general in cases where a derived class method wants to extend the base class -method of the same name and thus has to call the base class method somehow. +to use the ``::`` operator -- in Python you can write +``baseclass.methodname(self, )``. This is particularly useful +for :meth:`__init__` methods, and in general in cases where a derived class +method wants to extend the base class method of the same name and thus has to +call the base class method somehow. Finally, for instance variables it solves a syntactic problem with assignment: since local variables in Python are (by definition!) those variables to which a -value assigned in a function body (and that aren't explicitly declared global), -there has to be some way to tell the interpreter that an assignment was meant to -assign to an instance variable instead of to a local variable, and it should -preferably be syntactic (for efficiency reasons). C++ does this through +value is assigned in a function body (and that aren't explicitly declared +global), there has to be some way to tell the interpreter that an assignment was +meant to assign to an instance variable instead of to a local variable, and it +should preferably be syntactic (for efficiency reasons). C++ does this through declarations, but Python doesn't have declarations and it would be a pity having -to introduce them just for this purpose. Using the explicit "self.var" solves +to introduce them just for this purpose. Using the explicit ``self.var`` solves this nicely. Similarly, for using instance variables, having to write -"self.var" means that references to unqualified names inside a method don't have -to search the instance's directories. To put it another way, local variables -and instance variables live in two different namespaces, and you need to tell -Python which namespace to use. +``self.var`` means that references to unqualified names inside a method don't +have to search the instance's directories. To put it another way, local +variables and instance variables live in two different namespaces, and you need +to tell Python which namespace to use. Why can't I use an assignment in an expression? @@ -234,8 +235,10 @@ .. XXX talk about protocols? -Note that for string operations Python has moved from external functions (the -``string`` module) to methods. However, ``len()`` is still a function. +.. note:: + + For string operations, Python has moved from external functions (the + ``string`` module) to methods. However, ``len()`` is still a function. Why is join() a string method instead of a list or tuple method? @@ -298,22 +301,24 @@ expensive. In versions of Python prior to 2.0 it was common to use this idiom:: try: - value = dict[key] + value = mydict[key] except KeyError: - dict[key] = getvalue(key) - value = dict[key] + mydict[key] = getvalue(key) + value = mydict[key] This only made sense when you expected the dict to have the key almost all the time. If that wasn't the case, you coded it like this:: - if dict.has_key(key): - value = dict[key] + if mydict.has_key(key): + value = mydict[key] else: - dict[key] = getvalue(key) - value = dict[key] + mydict[key] = getvalue(key) + value = mydict[key] + +.. note:: -(In Python 2.0 and higher, you can code this as ``value = dict.setdefault(key, -getvalue(key))``.) + In Python 2.0 and higher, you can code this as ``value = + mydict.setdefault(key, getvalue(key))``. Why isn't there a switch or case statement in Python? @@ -432,7 +437,7 @@ `_, `PyInline `_, `Py2Cmod `_, and `Weave -`_. +`_. How does Python manage memory? @@ -450,6 +455,8 @@ difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation. +.. XXX relevant for Python 2.6? + Sometimes objects get stuck in tracebacks temporarily and hence are not deallocated when you might expect. Clear the tracebacks with:: @@ -461,8 +468,8 @@ things. They contain a portion of the program state extracted during the handling of an exception (usually the most recent exception). -In the absence of circularities and tracebacks, Python programs need not -explicitly manage memory. +In the absence of circularities and tracebacks, Python programs do not need to +manage memory explicitly. Why doesn't Python use a more traditional garbage collection scheme? For one thing, this is not a C standard feature and hence it's not portable. (Yes, we @@ -481,19 +488,19 @@ In Jython, the following code (which is fine in CPython) will probably run out of file descriptors long before it runs out of memory:: - for file in : + for file in very_long_list_of_files: f = open(file) c = f.read(1) Using the current reference counting and destructor scheme, each new assignment to f closes the previous file. Using GC, this is not guaranteed. If you want to write code that will work with any Python implementation, you should -explicitly close the file; this will work regardless of GC:: +explicitly close the file or use the :keyword:`with` statement; this will work +regardless of GC:: - for file in : - f = open(file) - c = f.read(1) - f.close() + for file in very_long_list_of_files: + with open(file) as f: + c = f.read(1) Why isn't all memory freed when Python exits? @@ -589,10 +596,10 @@ - Hash lists by their address (object ID). This doesn't work because if you construct a new list with the same value it won't be found; e.g.:: - d = {[1,2]: '12'} - print d[[1,2]] + mydict = {[1, 2]: '12'} + print mydict[[1, 2]] - would raise a KeyError exception because the id of the ``[1,2]`` used in the + would raise a KeyError exception because the id of the ``[1, 2]`` used in the second line differs from that in the first line. In other words, dictionary keys should be compared using ``==``, not using :keyword:`is`. @@ -613,7 +620,7 @@ There is a trick to get around this if you need to, but use it at your own risk: You can wrap a mutable structure inside a class instance which has both a -:meth:`__cmp_` and a :meth:`__hash__` method. You must then make sure that the +:meth:`__eq__` and a :meth:`__hash__` method. You must then make sure that the hash value for all such wrapper objects that reside in a dictionary (or other hash based structure), remain fixed while the object is in the dictionary (or other structure). :: @@ -621,15 +628,15 @@ class ListWrapper: def __init__(self, the_list): self.the_list = the_list - def __cmp__(self, other): + def __eq__(self, other): return self.the_list == other.the_list def __hash__(self): l = self.the_list result = 98767 - len(l)*555 - for i in range(len(l)): + for i, el in enumerate(l): try: - result = result + (hash(l[i]) % 9999999) * 1001 + i - except: + result = result + (hash(el) % 9999999) * 1001 + i + except Exception: result = (result % 7777777) + i * 333 return result @@ -637,8 +644,8 @@ members of the list may be unhashable and also by the possibility of arithmetic overflow. -Furthermore it must always be the case that if ``o1 == o2`` (ie ``o1.__cmp__(o2) -== 0``) then ``hash(o1) == hash(o2)`` (ie, ``o1.__hash__() == o2.__hash__()``), +Furthermore it must always be the case that if ``o1 == o2`` (ie ``o1.__eq__(o2) +is True``) then ``hash(o1) == hash(o2)`` (ie, ``o1.__hash__() == o2.__hash__()``), regardless of whether the object is in a dictionary or not. If you fail to meet these restrictions dictionaries and other hash based structures will misbehave. @@ -661,8 +668,8 @@ creates a new list from a provided iterable, sorts it and returns it. For example, here's how to iterate over the keys of a dictionary in sorted order:: - for key in sorted(dict.iterkeys()): - ... # do whatever with dict[key]... + for key in sorted(mydict): + ... # do whatever with mydict[key]... How do you specify and enforce an interface spec in Python? @@ -711,14 +718,14 @@ This type of bug commonly bites neophyte programmers. Consider this function:: - def foo(D={}): # Danger: shared reference to one dict for all calls + def foo(mydict={}): # Danger: shared reference to one dict for all calls ... compute something ... - D[key] = value - return D + mydict[key] = value + return mydict -The first time you call this function, ``D`` contains a single item. The second -time, ``D`` contains two items because when ``foo()`` begins executing, ``D`` -starts out with an item already in it. +The first time you call this function, ``mydict`` contains a single item. The +second time, ``mydict`` contains two items because when ``foo()`` begins +executing, ``mydict`` starts out with an item already in it. It is often expected that a function call creates new objects for default values. This is not what happens. Default values are created exactly once, when @@ -734,14 +741,14 @@ inside the function, check if the parameter is ``None`` and create a new list/dictionary/whatever if it is. For example, don't write:: - def foo(dict={}): + def foo(mydict={}): ... but:: - def foo(dict=None): - if dict is None: - dict = {} # create a new dict for local namespace + def foo(mydict=None): + if mydict is None: + mydict = {} # create a new dict for local namespace This feature can be useful. When you have a function that's time-consuming to compute, a common technique is to cache the parameters and the resulting value @@ -750,7 +757,7 @@ # Callers will never provide a third parameter for this function. def expensive (arg1, arg2, _cache={}): - if _cache.has_key((arg1, arg2)): + if (arg1, arg2) in _cache: return _cache[(arg1, arg2)] # Calculate the value @@ -770,13 +777,13 @@ reasonable uses of the "go" or "goto" constructs of C, Fortran, and other languages. For example:: - class label: pass # declare a label + class label: pass # declare a label try: ... - if (condition): raise label() # goto label + if (condition): raise label() # goto label ... - except label: # where to goto + except label: # where to goto pass ... @@ -801,7 +808,7 @@ If you're trying to build Windows pathnames, note that all Windows system calls accept forward slashes too:: - f = open("/mydir/file.txt") # works fine! + f = open("/mydir/file.txt") # works fine! If you're trying to build a pathname for a DOS command, try e.g. one of :: @@ -849,21 +856,20 @@ The primary benefit of "with" and similar language features (reduction of code volume) can, however, easily be achieved in Python by assignment. Instead of:: - function(args).dict[index][index].a = 21 - function(args).dict[index][index].b = 42 - function(args).dict[index][index].c = 63 + function(args).mydict[index][index].a = 21 + function(args).mydict[index][index].b = 42 + function(args).mydict[index][index].c = 63 write this:: - ref = function(args).dict[index][index] + ref = function(args).mydict[index][index] ref.a = 21 ref.b = 42 ref.c = 63 This also has the side-effect of increasing execution speed because name bindings are resolved at run-time in Python, and the second version only needs -to perform the resolution once. If the referenced object does not have a, b and -c attributes, of course, the end result is still a run-time exception. +to perform the resolution once. Why are colons required for the if/while/def/class statements? From python-checkins at python.org Sat Dec 19 18:46:40 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 17:46:40 -0000 Subject: [Python-checkins] r76887 - in python/branches/py3k: Doc/faq/design.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 18:46:40 2009 New Revision: 76887 Log: Recorded merge of revisions 76886 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76886 | georg.brandl | 2009-12-19 18:43:33 +0100 (Sa, 19 Dez 2009) | 1 line #7493: review of Design FAQ by Florent Xicluna. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/faq/design.rst Modified: python/branches/py3k/Doc/faq/design.rst ============================================================================== --- python/branches/py3k/Doc/faq/design.rst (original) +++ python/branches/py3k/Doc/faq/design.rst Sat Dec 19 18:46:40 2009 @@ -234,8 +234,10 @@ .. XXX talk about protocols? -Note that for string operations Python has moved from external functions (the -``string`` module) to methods. However, ``len()`` is still a function. +.. note:: + + For string operations, Python has moved from external functions (the + ``string`` module) to methods. However, ``len()`` is still a function. Why is join() a string method instead of a list or tuple method? @@ -306,14 +308,15 @@ This only made sense when you expected the dict to have the key almost all the time. If that wasn't the case, you coded it like this:: - if dict.has_key(key): + if key in dict(key): value = dict[key] else: dict[key] = getvalue(key) value = dict[key] -(In Python 2.0 and higher, you can code this as ``value = dict.setdefault(key, -getvalue(key))``.) +For this specific case, you could also use ``value = dict.setdefault(key, +getvalue(key))``, but only if the ``getvalue()`` call is cheap enough because it +is evaluated in all cases. Why isn't there a switch or case statement in Python? @@ -750,7 +753,7 @@ # Callers will never provide a third parameter for this function. def expensive (arg1, arg2, _cache={}): - if _cache.has_key((arg1, arg2)): + if (arg1, arg2) in _cache: return _cache[(arg1, arg2)] # Calculate the value From python-checkins at python.org Sat Dec 19 18:51:41 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 17:51:41 -0000 Subject: [Python-checkins] r76888 - python/branches/py3k/Doc/faq/programming.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 18:51:41 2009 New Revision: 76888 Log: #7495: Review of Programming FAQ by Florent Xicluna. Modified: python/branches/py3k/Doc/faq/programming.rst Modified: python/branches/py3k/Doc/faq/programming.rst ============================================================================== --- python/branches/py3k/Doc/faq/programming.rst (original) +++ python/branches/py3k/Doc/faq/programming.rst Sat Dec 19 18:51:41 2009 @@ -176,19 +176,19 @@ it is much shorter and far faster to use :: - L2 = list(L1[:3]) # "list" is redundant if L1 is a list. + L2 = list(L1[:3]) # "list" is redundant if L1 is a list. Note that the functionally-oriented builtins such as :func:`map`, :func:`zip`, and friends can be a convenient accelerator for loops that perform a single task. For example to pair the elements of two lists together:: - >>> zip([1,2,3], [4,5,6]) + >>> list(zip([1,2,3], [4,5,6])) [(1, 4), (2, 5), (3, 6)] or to compute a number of sines:: - >>> map( math.sin, (1,2,3,4)) - [0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308] + >>> list(map(math.sin, (1, 2, 3, 4))) + [0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308] The operation completes very quickly in such cases. @@ -197,10 +197,9 @@ ``"".join([s1,s2,s3,s4,s5,s6,s7])`` may be far faster than the more obvious ``s1+s2+s3+s4+s5+s6+s7``, since the "summation" will compute many subexpressions, whereas ``join()`` does all the copying in one pass. For -manipulating strings, use the ``replace()`` method on string objects. Use -regular expressions only when you're not dealing with constant string patterns. -Consider using the string formatting operations ``string % tuple`` and ``string -% dictionary``. +manipulating strings, use the ``replace()`` and the ``format()`` methods on +string objects. Use regular expressions only when you're not dealing with +constant string patterns. Be sure to use the :meth:`list.sort` builtin method to do sorting, and see the `sorting mini-HOWTO `_ for examples @@ -210,7 +209,7 @@ Another common trick is to "push loops into functions or methods." For example suppose you have a program that runs slowly and you use the profiler to determine that a Python function ``ff()`` is being called lots of times. If you -notice that ``ff ()``:: +notice that ``ff()``:: def ff(x): ... # do something with x computing result... @@ -387,7 +386,7 @@ import config import mod - print config.x + print(config.x) Note that using a module is also the basis for implementing the Singleton design pattern, for the same reason. @@ -408,16 +407,15 @@ It's good practice if you import modules in the following order: -1. standard library modules -- e.g. ``sys``, ``os``, ``getopt``, ``re``) +1. standard library modules -- e.g. ``sys``, ``os``, ``getopt``, ``re`` 2. third-party library modules (anything installed in Python's site-packages directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc. 3. locally-developed modules Never use relative package imports. If you're writing code that's in the ``package.sub.m1`` module and want to import ``package.sub.m2``, do not just -write ``import m2``, even though it's legal. Write ``from package.sub import -m2`` instead. Relative imports can lead to a module being initialized twice, -leading to confusing bugs. +write ``from . import m2``, even though it's legal. Write ``from package.sub import +m2`` instead. See :pep:`328` for details. It is sometimes necessary to move imports to a function or class to avoid problems with circular imports. Gordon McMillan says: @@ -499,7 +497,7 @@ x, y = 'old-value', 99 x, y = func2(x, y) - print x, y # output: new-value 100 + print(x, y) # output: new-value 100 This is almost always the clearest solution. @@ -513,7 +511,7 @@ args = ['old-value', 99] func1(args) - print args[0], args[1] # output: new-value 100 + print(args[0], args[1]) # output: new-value 100 4) By passing in a dictionary that gets mutated:: @@ -523,7 +521,7 @@ args = {'a':' old-value', 'b': 99} func3(args) - print args['a'], args['b'] + print(args['a'], args['b']) 5) Or bundle up values in a class instance:: @@ -538,7 +536,7 @@ args = callByRef(a='old-value', b=99) func4(args) - print args.a, args.b + print(args.a, args.b) There's almost never a good reason to get this complicated. @@ -644,10 +642,10 @@ a = B() b = a - print b - <__main__.A instance at 016D07CC> - print a - <__main__.A instance at 016D07CC> + print(b) + <__main__.A object at 0x16D07CC> + print(a) + <__main__.A object at 0x16D07CC> Arguably the class has a name: even though it is bound to two names and invoked through the name B the created instance is still reported as an instance of @@ -677,7 +675,7 @@ Comma is not an operator in Python. Consider this session:: >>> "a" in "b", "a" - (False, '1') + (False, 'a') Since the comma is not an operator, but a separator between expressions the above is evaluated as if you had entered:: @@ -686,7 +684,7 @@ not:: - >>> "a" in ("5", "a") + >>> "a" in ("b", "a") The same is true of the various assignment operators (``=``, ``+=`` etc). They are not truly operators but syntactic delimiters in assignment statements. @@ -728,12 +726,12 @@ if not isfunction(on_true): return on_true else: - return apply(on_true) + return on_true() else: if not isfunction(on_false): return on_false else: - return apply(on_false) + return on_false() In most cases you'll pass b and c directly: ``q(a, b, c)``. To avoid evaluating b or c when they shouldn't be, encapsulate them within a lambda function, e.g.: @@ -758,22 +756,24 @@ Yes. Usually this is done by nesting :keyword:`lambda` within :keyword:`lambda`. See the following three examples, due to Ulf Bartelt:: + from functools import reduce + # Primes < 1000 - print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0, - map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000))) + print(list(filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0, + map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000))))) # First 10 Fibonacci numbers - print map(lambda x,f=lambda x,f:(x<=1) or (f(x-1,f)+f(x-2,f)): f(x,f), - range(10)) + print(list(map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1: + f(x,f), range(10)))) # Mandelbrot set - print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y, + print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y, Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM, Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro, i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y >=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr( 64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy - ))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24) + ))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)) # \___ ___/ \___ ___/ | | |__ lines on screen # V V | |______ columns on screen # | | |__________ maximum of "iterations" @@ -789,10 +789,11 @@ How do I specify hexadecimal and octal integers? ------------------------------------------------ -To specify an octal digit, precede the octal value with a zero. For example, to -set the variable "a" to the octal value "10" (8 in decimal), type:: +To specify an octal digit, precede the octal value with a zero, and then a lower +or uppercase "o". For example, to set the variable "a" to the octal value "10" +(8 in decimal), type:: - >>> a = 010 + >>> a = 0o10 >>> a 8 @@ -808,17 +809,17 @@ 178 -Why does -22 / 10 return -3? ----------------------------- +Why does -22 // 10 return -3? +----------------------------- It's primarily driven by the desire that ``i % j`` have the same sign as ``j``. If you want that, and also want:: - i == (i / j) * j + (i % j) + i == (i // j) * j + (i % j) then integer division has to return the floor. C also requires that identity to -hold, and then compilers that truncate ``i / j`` need to make ``i % j`` have the -same sign as ``i``. +hold, and then compilers that truncate ``i // j`` need to make ``i % j`` have +the same sign as ``i``. There are few real use cases for ``i % j`` when ``j`` is negative. When ``j`` is positive, there are many, and in virtually all of them it's more useful for @@ -848,8 +849,8 @@ directory. :func:`eval` also has the effect of interpreting numbers as Python expressions, -so that e.g. ``eval('09')`` gives a syntax error because Python regards numbers -starting with '0' as octal (base 8). +so that e.g. ``eval('09')`` gives a syntax error because Python does not allow +leading '0' in a decimal number (except '0'). How do I convert a number to a string? @@ -857,10 +858,9 @@ To convert, e.g., the number 144 to the string '144', use the built-in type constructor :func:`str`. If you want a hexadecimal or octal representation, use -the built-in functions ``hex()`` or ``oct()``. For fancy formatting, use -:ref:`the % operator ` on strings, e.g. ``"%04d" % 144`` -yields ``'0144'`` and ``"%.3f" % (1/3.0)`` yields ``'0.333'``. See the library -reference manual for details. +the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see +the :ref:`string-formatting` section, e.g. ``"{:04d}".format(144)`` yields +``'0144'`` and ``"{:.3f}" % (1/3)`` yields ``'0.333'``. How do I modify a string in place? @@ -871,19 +871,20 @@ >>> s = "Hello, world" >>> a = list(s) - >>> print a + >>> print(a) ['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd'] >>> a[7:] = list("there!") >>> ''.join(a) 'Hello, there!' >>> import array - >>> a = array.array('c', s) - >>> print a - array('c', 'Hello, world') - >>> a[0] = 'y' ; print a - array('c', 'yello world') - >>> a.tostring() + >>> a = array.array('u', s) + >>> print(a) + array('u', 'Hello, world') + >>> a[0] = 'y' + >>> print(a) + array('u', 'yello world') + >>> a.tounicode() 'yello, world' @@ -931,7 +932,7 @@ * Use :func:`locals` or :func:`eval` to resolve the function name:: def myFunc(): - print "hello" + print("hello") fname = "myFunc" @@ -958,12 +959,12 @@ ... "\r\n" ... "\r\n") >>> lines.rstrip("\n\r") - "line 1 " + 'line 1 ' Since this is typically only desired when reading text one line at a time, using ``S.rstrip()`` this way works well. -For older versions of Python, There are two partial substitutes: +For older versions of Python, there are two partial substitutes: - If you want to remove all trailing whitespace, use the ``rstrip()`` method of string objects. This removes all trailing whitespace, not just a single @@ -988,45 +989,10 @@ :cfunc:`sscanf` and better suited for the task. -What does 'UnicodeError: ASCII [decoding,encoding] error: ordinal not in range(128)' mean? ------------------------------------------------------------------------------------------- - -This error indicates that your Python installation can handle only 7-bit ASCII -strings. There are a couple ways to fix or work around the problem. +What does 'UnicodeDecodeError' or 'UnicodeEncodeError' error mean? +------------------------------------------------------------------- -If your programs must handle data in arbitrary character set encodings, the -environment the application runs in will generally identify the encoding of the -data it is handing you. You need to convert the input to Unicode data using -that encoding. For example, a program that handles email or web input will -typically find character set encoding information in Content-Type headers. This -can then be used to properly convert input data to Unicode. Assuming the string -referred to by ``value`` is encoded as UTF-8:: - - value = unicode(value, "utf-8") - -will return a Unicode object. If the data is not correctly encoded as UTF-8, -the above call will raise a :exc:`UnicodeError` exception. - -If you only want strings converted to Unicode which have non-ASCII data, you can -try converting them first assuming an ASCII encoding, and then generate Unicode -objects if that fails:: - - try: - x = unicode(value, "ascii") - except UnicodeError: - value = unicode(value, "utf-8") - else: - # value was valid ASCII data - pass - -It's possible to set a default encoding in a file called ``sitecustomize.py`` -that's part of the Python library. However, this isn't recommended because -changing the Python-wide default encoding may cause third-party extension -modules to fail. - -Note that on Windows, there is an encoding known as "mbcs", which uses an -encoding specific to your current locale. In many cases, and particularly when -working with COM, this may be an appropriate default encoding to use. +See the :ref:`unicode-howto`. Sequences (Tuples/Lists) @@ -1089,26 +1055,26 @@ If you don't mind reordering the list, sort it and then scan from the end of the list, deleting duplicates as you go:: - if List: - List.sort() - last = List[-1] - for i in range(len(List)-2, -1, -1): - if last == List[i]: - del List[i] + if mylist: + mylist.sort() + last = mylist[-1] + for i in range(len(mylist)-2, -1, -1): + if last == mylist[i]: + del mylist[i] else: - last = List[i] + last = mylist[i] If all elements of the list may be used as dictionary keys (i.e. they are all hashable) this is often faster :: d = {} - for x in List: - d[x] = x - List = d.values() + for x in mylist: + d[x] = 1 + mylist = list(d.keys()) In Python 2.5 and later, the following is possible instead:: - List = list(set(List)) + mylist = list(set(mylist)) This converts the list into a set, thereby removing duplicates, and then back into a list. @@ -1184,15 +1150,7 @@ Use a list comprehension:: - result = [obj.method() for obj in List] - -More generically, you can try the following function:: - - def method_map(objects, method, arguments): - """method_map([a,b], "meth", (1,2)) gives [a.meth(1,2), b.meth(1,2)]""" - nobjects = len(objects) - methods = map(getattr, objects, [method]*nobjects) - return map(apply, methods, [arguments]*nobjects) + result = [obj.method() for obj in mylist] Dictionaries @@ -1209,23 +1167,17 @@ case, use the ``pprint`` module to pretty-print the dictionary; the items will be presented in order sorted by the key. -A more complicated solution is to subclass ``UserDict.UserDict`` to create a +A more complicated solution is to subclass ``dict`` to create a ``SortedDict`` class that prints itself in a predictable order. Here's one simpleminded implementation of such a class:: - import UserDict, string - - class SortedDict(UserDict.UserDict): + class SortedDict(dict): def __repr__(self): - result = [] - append = result.append - keys = self.data.keys() - keys.sort() - for k in keys: - append("%s: %s" % (`k`, `self.data[k]`)) - return "{%s}" % string.join(result, ", ") + keys = sorted(self.keys()) + result = ("{!r}: {!r}".format(k, self[k]) for k in keys) + return "{{{}}}".format(", ".join(result)) - __str__ = __repr__ + __str__ = __repr__ This will work for many common situations you might encounter, though it's far from a perfect solution. The largest flaw is that if some values in the @@ -1247,18 +1199,18 @@ sorting is quite simple to do with list comprehensions. To sort a list of strings by their uppercase values:: - tmp1 = [(x.upper(), x) for x in L] # Schwartzian transform + tmp1 = [(x.upper(), x) for x in L] # Schwartzian transform tmp1.sort() Usorted = [x[1] for x in tmp1] To sort by the integer value of a subfield extending from positions 10-15 in each string:: - tmp2 = [(int(s[10:15]), s) for s in L] # Schwartzian transform + tmp2 = [(int(s[10:15]), s) for s in L] # Schwartzian transform tmp2.sort() Isorted = [x[1] for x in tmp2] -Note that Isorted may also be computed by :: +For versions prior to 3.0, Isorted may also be computed by :: def intfield(s): return int(s[10:15]) @@ -1276,23 +1228,24 @@ How can I sort one list by values from another list? ---------------------------------------------------- -Merge them into a single list of tuples, sort the resulting list, and then pick +Merge them into an iterator of tuples, sort the resulting list, and then pick out the element you want. :: >>> list1 = ["what", "I'm", "sorting", "by"] >>> list2 = ["something", "else", "to", "sort"] >>> pairs = zip(list1, list2) + >>> pairs = sorted(pairs) >>> pairs - [('what', 'something'), ("I'm", 'else'), ('sorting', 'to'), ('by', 'sort')] - >>> pairs.sort() - >>> result = [ x[1] for x in pairs ] + [("I'm", 'else'), ('by', 'sort'), ('sorting', 'to'), ('what', 'something')] + >>> result = [x[1] for x in pairs] >>> result ['else', 'sort', 'to', 'something'] + An alternative for the last step is:: - result = [] - for p in pairs: result.append(p[1]) + >>> result = [] + >>> for p in pairs: result.append(p[1]) If you find this more legible, you might prefer to use this instead of the final list comprehension. However, it is almost twice as slow for long lists. Why? @@ -1351,7 +1304,7 @@ is an instance of any of a number of classes by providing a tuple instead of a single class, e.g. ``isinstance(obj, (class1, class2, ...))``, and can also check whether an object is one of Python's built-in types, e.g. -``isinstance(obj, str)`` or ``isinstance(obj, (int, long, float, complex))``. +``isinstance(obj, str)`` or ``isinstance(obj, (int, float, complex))``. Note that most programs do not use :func:`isinstance` on user-defined classes very often. If you are developing the classes yourself, a more proper @@ -1360,7 +1313,7 @@ different thing based on what class it is. For example, if you have a function that does something:: - def search (obj): + def search(obj): if isinstance(obj, Mailbox): # ... code to search a mailbox elif isinstance(obj, Document): @@ -1430,17 +1383,17 @@ How do I call a method defined in a base class from a derived class that overrides it? -------------------------------------------------------------------------------------- -If you're using new-style classes, use the built-in :func:`super` function:: +Use the built-in :func:`super` function:: class Derived(Base): def meth (self): super(Derived, self).meth() -If you're using classic classes: For a class definition such as ``class -Derived(Base): ...`` you can call method ``meth()`` defined in ``Base`` (or one -of ``Base``'s base classes) as ``Base.meth(self, arguments...)``. Here, -``Base.meth`` is an unbound method, so you need to provide the ``self`` -argument. +For version prior to 3.0, you may be using classic classes: For a class +definition such as ``class Derived(Base): ...`` you can call method ``meth()`` +defined in ``Base`` (or one of ``Base``'s base classes) as ``Base.meth(self, +arguments...)``. Here, ``Base.meth`` is an unbound method, so you need to +provide the ``self`` argument. How can I organize my code to make it easier to change the base class? @@ -1463,8 +1416,8 @@ How do I create static class data and static class methods? ----------------------------------------------------------- -Static data (in the sense of C++ or Java) is easy; static methods (again in the -sense of C++ or Java) are not supported directly. +Both static data and static methods (in the sense of C++ or Java) are supported +in Python. For static data, simply define a class attribute. To assign a new value to the attribute, you have to explicitly use the class name in the assignment:: @@ -1483,9 +1436,9 @@ search path from ``c.__class__`` back to ``C``. Caution: within a method of C, an assignment like ``self.count = 42`` creates a -new and unrelated instance vrbl named "count" in ``self``'s own dict. Rebinding -of a class-static data name must always specify the class whether inside a -method or not:: +new and unrelated instance named "count" in ``self``'s own dict. Rebinding of a +class-static data name must always specify the class whether inside a method or +not:: C.count = 314 @@ -1536,9 +1489,9 @@ class C: def __init__(self, i=None): if i is None: - print "No arguments" + print("No arguments") else: - print "Argument is", i + print("Argument is", i) This is not entirely equivalent, but close enough in practice. @@ -1597,11 +1550,13 @@ Tree data structures, for instance, should use weak references for their parent and sibling references (if they need them!). -If the object has ever been a local variable in a function that caught an -expression in an except clause, chances are that a reference to the object still -exists in that function's stack frame as contained in the stack trace. -Normally, calling :func:`sys.exc_clear` will take care of this by clearing the -last recorded exception. +.. XXX relevant for Python 3? + + If the object has ever been a local variable in a function that caught an + expression in an except clause, chances are that a reference to the object + still exists in that function's stack frame as contained in the stack trace. + Normally, calling :func:`sys.exc_clear` will take care of this by clearing + the last recorded exception. Finally, if your :meth:`__del__` method raises an exception, a warning message is printed to :data:`sys.stderr`. @@ -1669,7 +1624,7 @@ after checking ``__name__``:: def main(): - print 'Running test...' + print('Running test...') ... if __name__ == '__main__': @@ -1758,8 +1713,9 @@ basic module would be parsed and re-parsed many times. To force rereading of a changed module, do this:: + import imp import modname - reload(modname) + imp.reload(modname) Warning: this technique is not 100% fool-proof. In particular, modules containing statements like :: @@ -1771,17 +1727,18 @@ updated to use the new class definition. This can result in the following paradoxical behaviour: + >>> import imp >>> import cls >>> c = cls.C() # Create an instance of C - >>> reload(cls) - + >>> imp.reload(cls) + >>> isinstance(c, cls.C) # isinstance is false?!? False -The nature of the problem is made clear if you print out the class objects: - - >>> c.__class__ - - >>> cls.C - +The nature of the problem is made clear if you print out the "identity" of the +class objects: + >>> hex(id(c.__class__)) + '0x7352a0' + >>> hex(id(cls.C)) + '0x4198d0' From python-checkins at python.org Sat Dec 19 18:57:51 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 17:57:51 -0000 Subject: [Python-checkins] r76889 - in python/branches/py3k/Doc: faq/library.rst howto/urllib2.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 18:57:51 2009 New Revision: 76889 Log: #7499: Review of Library FAQ by Florent Xicluna. Modified: python/branches/py3k/Doc/faq/library.rst python/branches/py3k/Doc/howto/urllib2.rst Modified: python/branches/py3k/Doc/faq/library.rst ============================================================================== --- python/branches/py3k/Doc/faq/library.rst (original) +++ python/branches/py3k/Doc/faq/library.rst Sat Dec 19 18:57:51 2009 @@ -38,7 +38,7 @@ type:: import sys - print sys.builtin_module_names + print(sys.builtin_module_names) How do I make a Python script executable on Unix? @@ -187,8 +187,11 @@ ----------------------------------------- For Unix variants: There are several solutions. It's straightforward to do this -using curses, but curses is a fairly large module to learn. Here's a solution -without curses:: +using curses, but curses is a fairly large module to learn. + +.. XXX this doesn't work out of the box, some IO expert needs to check why + + Here's a solution without curses:: import termios, fcntl, sys, os fd = sys.stdin.fileno() @@ -202,23 +205,24 @@ fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK) try: - while 1: + while True: try: c = sys.stdin.read(1) - print "Got character", `c` - except IOError: pass + print("Got character", repr(c)) + except IOError: + pass finally: termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm) fcntl.fcntl(fd, fcntl.F_SETFL, oldflags) -You need the :mod:`termios` and the :mod:`fcntl` module for any of this to work, -and I've only tried it on Linux, though it should work elsewhere. In this code, -characters are read and printed one at a time. - -:func:`termios.tcsetattr` turns off stdin's echoing and disables canonical mode. -:func:`fcntl.fnctl` is used to obtain stdin's file descriptor flags and modify -them for non-blocking mode. Since reading stdin when it is empty results in an -:exc:`IOError`, this error is caught and ignored. + You need the :mod:`termios` and the :mod:`fcntl` module for any of this to + work, and I've only tried it on Linux, though it should work elsewhere. In + this code, characters are read and printed one at a time. + + :func:`termios.tcsetattr` turns off stdin's echoing and disables canonical + mode. :func:`fcntl.fnctl` is used to obtain stdin's file descriptor flags + and modify them for non-blocking mode. Since reading stdin when it is empty + results in an :exc:`IOError`, this error is caught and ignored. Threads @@ -247,13 +251,13 @@ import threading, time def thread_task(name, n): - for i in range(n): print name, i + for i in range(n): print(name, i) for i in range(10): T = threading.Thread(target=thread_task, args=(str(i), i)) T.start() - time.sleep(10) # <----------------------------! + time.sleep(10) # <---------------------------! But now (on many platforms) the threads don't run in parallel, but appear to run sequentially, one at a time! The reason is that the OS thread scheduler doesn't @@ -262,8 +266,8 @@ A simple fix is to add a tiny sleep to the start of the run function:: def thread_task(name, n): - time.sleep(0.001) # <---------------------! - for i in range(n): print name, i + time.sleep(0.001) # <--------------------! + for i in range(n): print(name, i) for i in range(10): T = threading.Thread(target=thread_task, args=(str(i), i)) @@ -289,28 +293,28 @@ Here's a trivial example:: - import threading, Queue, time + import threading, queue, time # The worker thread gets jobs off the queue. When the queue is empty, it # assumes there will be no more work and exits. # (Realistically workers will run until terminated.) def worker (): - print 'Running worker' + print('Running worker') time.sleep(0.1) while True: try: arg = q.get(block=False) - except Queue.Empty: - print 'Worker', threading.currentThread(), - print 'queue empty' + except queue.Empty: + print('Worker', threading.currentThread(), end=' ') + print('queue empty') break else: - print 'Worker', threading.currentThread(), - print 'running with argument', arg + print('Worker', threading.currentThread(), end=' ') + print('running with argument', arg) time.sleep(0.5) # Create queue - q = Queue.Queue() + q = queue.Queue() # Start a pool of 5 workers for i in range(5): @@ -322,10 +326,10 @@ q.put(i) # Give threads time to run - print 'Main thread sleeping' + print('Main thread sleeping') time.sleep(5) -When run, this will produce the following output: +When run, this will produce the following output:: Running worker Running worker @@ -333,12 +337,12 @@ Running worker Running worker Main thread sleeping - Worker running with argument 0 - Worker running with argument 1 - Worker running with argument 2 - Worker running with argument 3 - Worker running with argument 4 - Worker running with argument 5 + Worker running with argument 0 + Worker running with argument 1 + Worker running with argument 2 + Worker running with argument 3 + Worker running with argument 4 + Worker running with argument 5 ... Consult the module's documentation for more details; the ``Queue`` class @@ -351,7 +355,7 @@ A global interpreter lock (GIL) is used internally to ensure that only one thread runs in the Python VM at a time. In general, Python offers to switch among threads only between bytecode instructions; how frequently it switches can -be set via :func:`sys.setcheckinterval`. Each bytecode instruction and +be set via :func:`sys.setswitchinterval`. Each bytecode instruction and therefore all the C implementation code reached from each instruction is therefore atomic from the point of view of a Python program. @@ -443,7 +447,7 @@ ----------------------------------------------------- Use ``os.remove(filename)`` or ``os.unlink(filename)``; for documentation, see -the :mod:`os` module. The two functions are identical; :func:`unlink` is simply +the :mod:`os` module. The two functions are identical; :func:`~os.unlink` is simply the name of the Unix system call for this function. To remove a directory, use :func:`os.rmdir`; use :func:`os.mkdir` to create one. @@ -505,81 +509,83 @@ ``p.read(n)``. -How do I run a subprocess with pipes connected to both input and output? ------------------------------------------------------------------------- - -.. XXX update to use subprocess +.. XXX update to use subprocess. See the :ref:`subprocess-replacements` section. -Use the :mod:`popen2` module. For example:: + How do I run a subprocess with pipes connected to both input and output? + ------------------------------------------------------------------------ - import popen2 - fromchild, tochild = popen2.popen2("command") - tochild.write("input\n") - tochild.flush() - output = fromchild.readline() - -Warning: in general it is unwise to do this because you can easily cause a -deadlock where your process is blocked waiting for output from the child while -the child is blocked waiting for input from you. This can be caused because the -parent expects the child to output more text than it does, or it can be caused -by data being stuck in stdio buffers due to lack of flushing. The Python parent -can of course explicitly flush the data it sends to the child before it reads -any output, but if the child is a naive C program it may have been written to -never explicitly flush its output, even if it is interactive, since flushing is -normally automatic. - -Note that a deadlock is also possible if you use :func:`popen3` to read stdout -and stderr. If one of the two is too large for the internal buffer (increasing -the buffer size does not help) and you ``read()`` the other one first, there is -a deadlock, too. - -Note on a bug in popen2: unless your program calls ``wait()`` or ``waitpid()``, -finished child processes are never removed, and eventually calls to popen2 will -fail because of a limit on the number of child processes. Calling -:func:`os.waitpid` with the :data:`os.WNOHANG` option can prevent this; a good -place to insert such a call would be before calling ``popen2`` again. - -In many cases, all you really need is to run some data through a command and get -the result back. Unless the amount of data is very large, the easiest way to do -this is to write it to a temporary file and run the command with that temporary -file as input. The standard module :mod:`tempfile` exports a ``mktemp()`` -function to generate unique temporary file names. :: + Use the :mod:`popen2` module. For example:: - import tempfile - import os - - class Popen3: - """ - This is a deadlock-safe version of popen that returns - an object with errorlevel, out (a string) and err (a string). - (capturestderr may not work under windows.) - Example: print Popen3('grep spam','\n\nhere spam\n\n').out - """ - def __init__(self,command,input=None,capturestderr=None): - outfile=tempfile.mktemp() - command="( %s ) > %s" % (command,outfile) - if input: - infile=tempfile.mktemp() - open(infile,"w").write(input) - command=command+" <"+infile - if capturestderr: - errfile=tempfile.mktemp() - command=command+" 2>"+errfile - self.errorlevel=os.system(command) >> 8 - self.out=open(outfile,"r").read() - os.remove(outfile) - if input: - os.remove(infile) - if capturestderr: - self.err=open(errfile,"r").read() - os.remove(errfile) - -Note that many interactive programs (e.g. vi) don't work well with pipes -substituted for standard input and output. You will have to use pseudo ttys -("ptys") instead of pipes. Or you can use a Python interface to Don Libes' -"expect" library. A Python extension that interfaces to expect is called "expy" -and available from http://expectpy.sourceforge.net. A pure Python solution that -works like expect is `pexpect `_. + import popen2 + fromchild, tochild = popen2.popen2("command") + tochild.write("input\n") + tochild.flush() + output = fromchild.readline() + + Warning: in general it is unwise to do this because you can easily cause a + deadlock where your process is blocked waiting for output from the child + while the child is blocked waiting for input from you. This can be caused + because the parent expects the child to output more text than it does, or it + can be caused by data being stuck in stdio buffers due to lack of flushing. + The Python parent can of course explicitly flush the data it sends to the + child before it reads any output, but if the child is a naive C program it + may have been written to never explicitly flush its output, even if it is + interactive, since flushing is normally automatic. + + Note that a deadlock is also possible if you use :func:`popen3` to read + stdout and stderr. If one of the two is too large for the internal buffer + (increasing the buffer size does not help) and you ``read()`` the other one + first, there is a deadlock, too. + + Note on a bug in popen2: unless your program calls ``wait()`` or + ``waitpid()``, finished child processes are never removed, and eventually + calls to popen2 will fail because of a limit on the number of child + processes. Calling :func:`os.waitpid` with the :data:`os.WNOHANG` option can + prevent this; a good place to insert such a call would be before calling + ``popen2`` again. + + In many cases, all you really need is to run some data through a command and + get the result back. Unless the amount of data is very large, the easiest + way to do this is to write it to a temporary file and run the command with + that temporary file as input. The standard module :mod:`tempfile` exports a + ``mktemp()`` function to generate unique temporary file names. :: + + import tempfile + import os + + class Popen3: + """ + This is a deadlock-safe version of popen that returns + an object with errorlevel, out (a string) and err (a string). + (capturestderr may not work under windows.) + Example: print(Popen3('grep spam','\n\nhere spam\n\n').out) + """ + def __init__(self,command,input=None,capturestderr=None): + outfile=tempfile.mktemp() + command="( %s ) > %s" % (command,outfile) + if input: + infile=tempfile.mktemp() + open(infile,"w").write(input) + command=command+" <"+infile + if capturestderr: + errfile=tempfile.mktemp() + command=command+" 2>"+errfile + self.errorlevel=os.system(command) >> 8 + self.out=open(outfile,"r").read() + os.remove(outfile) + if input: + os.remove(infile) + if capturestderr: + self.err=open(errfile,"r").read() + os.remove(errfile) + + Note that many interactive programs (e.g. vi) don't work well with pipes + substituted for standard input and output. You will have to use pseudo ttys + ("ptys") instead of pipes. Or you can use a Python interface to Don Libes' + "expect" library. A Python extension that interfaces to expect is called + "expy" and available from http://expectpy.sourceforge.net. A pure Python + solution that works like expect is `pexpect + `_. How do I access the serial (RS232) port? @@ -601,7 +607,7 @@ which in turn are a medium-level layer of abstraction on top of (among other things) low-level C file descriptors. -For most file objects you create in Python via the builtin ``file`` constructor, +For most file objects you create in Python via the builtin ``open`` constructor, ``f.close()`` marks the Python file object as being closed from Python's point of view, and also arranges to close the underlying C stream. This also happens automatically in f's destructor, when f becomes garbage. @@ -645,41 +651,29 @@ I would like to retrieve web pages that are the result of POSTing a form. Is there existing code that would let me do this easily? -Yes. Here's a simple example that uses httplib:: +Yes. Here's a simple example that uses urllib.request:: #!/usr/local/bin/python - import httplib, sys, time + import urllib.request ### build the query string qs = "First=Josephine&MI=Q&Last=Public" ### connect and send the server a path - httpobj = httplib.HTTP('www.some-server.out-there', 80) - httpobj.putrequest('POST', '/cgi-bin/some-cgi-script') - ### now generate the rest of the HTTP headers... - httpobj.putheader('Accept', '*/*') - httpobj.putheader('Connection', 'Keep-Alive') - httpobj.putheader('Content-type', 'application/x-www-form-urlencoded') - httpobj.putheader('Content-length', '%d' % len(qs)) - httpobj.endheaders() - httpobj.send(qs) - ### find out what the server said in response... - reply, msg, hdrs = httpobj.getreply() - if reply != 200: - sys.stdout.write(httpobj.getfile().read()) + req = urllib.request.urlopen('http://www.some-server.out-there' + '/cgi-bin/some-cgi-script', data=qs) + msg, hdrs = req.read(), req.info() Note that in general for URL-encoded POST operations, query strings must be -quoted by using :func:`urllib.quote`. For example to send name="Guy Steele, +quoted by using :func:`urllib.parse.urlencode`. For example to send name="Guy Steele, Jr.":: - >>> from urllib import quote - >>> x = quote("Guy Steele, Jr.") - >>> x - 'Guy%20Steele,%20Jr.' - >>> query_string = "name="+x - >>> query_string - 'name=Guy%20Steele,%20Jr.' + >>> import urllib.parse + >>> urllib.parse.urlencode({'name': 'Guy Steele, Jr.'}) + 'name=Guy+Steele%2C+Jr.' + +.. seealso:: :ref:`urllib-howto` for extensive examples. What module should I use to help with generating HTML? @@ -712,9 +706,9 @@ import sys, smtplib - fromaddr = raw_input("From: ") - toaddrs = raw_input("To: ").split(',') - print "Enter message, end with ^D:" + fromaddr = input("From: ") + toaddrs = input("To: ").split(',') + print("Enter message, end with ^D:") msg = '' while True: line = sys.stdin.readline() @@ -732,17 +726,17 @@ ``/usr/sbin/sendmail``. The sendmail manual page will help you out. Here's some sample code:: - SENDMAIL = "/usr/sbin/sendmail" # sendmail location + SENDMAIL = "/usr/sbin/sendmail" # sendmail location import os p = os.popen("%s -t -i" % SENDMAIL, "w") p.write("To: receiver at example.com\n") p.write("Subject: test\n") - p.write("\n") # blank line separating headers from body + p.write("\n") # blank line separating headers from body p.write("Some text\n") p.write("some more text\n") sts = p.close() if sts != 0: - print "Sendmail exit status", sts + print("Sendmail exit status", sts) How do I avoid blocking in the connect() method of a socket? @@ -759,7 +753,7 @@ You can use the ``connect_ex()`` method to avoid creating an exception. It will just return the errno value. To poll, you can call ``connect_ex()`` again later --- 0 or ``errno.EISCONN`` indicate that you're connected -- or you can pass this +-- ``0`` or ``errno.EISCONN`` indicate that you're connected -- or you can pass this socket to select to check if it's writable. @@ -798,21 +792,15 @@ general such as using gdbm with pickle/shelve. -Why is cPickle so slow? ------------------------ - -.. XXX update this, default protocol is 2/3 - -The default format used by the pickle module is a slow one that results in -readable pickles. Making it the default, but it would break backward -compatibility:: +If my program crashes with a bsddb (or anydbm) database open, it gets corrupted. How come? +------------------------------------------------------------------------------------------ - largeString = 'z' * (100 * 1024) - myPickle = cPickle.dumps(largeString, protocol=1) +.. XXX move this FAQ entry elsewhere? +.. note:: -If my program crashes with a bsddb (or anydbm) database open, it gets corrupted. How come? ------------------------------------------------------------------------------------------- + The bsddb module is now available as a standalone package `pybsddb + `_. Databases opened for write access with the bsddb module (and often by the anydbm module, since it will preferentially use bsddb) must explicitly be closed using @@ -827,6 +815,13 @@ I tried to open Berkeley DB file, but bsddb produces bsddb.error: (22, 'Invalid argument'). Help! How can I restore my data? ---------------------------------------------------------------------------------------------------------------------------- +.. XXX move this FAQ entry elsewhere? + +.. note:: + + The bsddb module is now available as a standalone package `pybsddb + `_. + Don't panic! Your data is probably intact. The most frequent cause for the error is that you tried to open an earlier Berkeley DB file with a later version of the Berkeley DB library. Modified: python/branches/py3k/Doc/howto/urllib2.rst ============================================================================== --- python/branches/py3k/Doc/howto/urllib2.rst (original) +++ python/branches/py3k/Doc/howto/urllib2.rst Sat Dec 19 18:57:51 2009 @@ -1,3 +1,5 @@ +.. _urllib-howto: + *********************************************************** HOWTO Fetch Internet Resources Using The urllib Package *********************************************************** From python-checkins at python.org Sat Dec 19 18:59:59 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 17:59:59 -0000 Subject: [Python-checkins] r76890 - in python/branches/py3k/Doc/faq: extending.rst gui.rst windows.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 18:59:59 2009 New Revision: 76890 Log: #7500: add "Python 3 review needed" comments and fix a few obvious errors. Modified: python/branches/py3k/Doc/faq/extending.rst python/branches/py3k/Doc/faq/gui.rst python/branches/py3k/Doc/faq/windows.rst Modified: python/branches/py3k/Doc/faq/extending.rst ============================================================================== --- python/branches/py3k/Doc/faq/extending.rst (original) +++ python/branches/py3k/Doc/faq/extending.rst Sat Dec 19 18:59:59 2009 @@ -7,6 +7,9 @@ .. highlight:: c +.. XXX need review for Python 3. + + Can I create my own functions in C? ----------------------------------- @@ -51,8 +54,7 @@ `__, `CXX `_ `Boost `_, or `Weave -`_ are also alternatives for wrapping -C++ libraries. +`_ are also alternatives for wrapping C++ libraries. How can I execute arbitrary Python statements from C? @@ -159,8 +161,8 @@ ... >>> import sys >>> sys.stdout = StdoutCatcher() - >>> print 'foo' - >>> print 'hello world!' + >>> print('foo') + >>> print('hello world!') >>> sys.stderr.write(sys.stdout.data) foo hello world! @@ -201,7 +203,7 @@ `_, `CXX `_, `Boost `_, `Weave -`_ or `SWIG `_ +`_ or `SWIG `_ I added a module using the Setup file and the make fails; why? @@ -470,12 +472,9 @@ >>> import sys >>> if sys.maxunicode > 65535: - ... print 'UCS4 build' + ... print('UCS4 build') ... else: - ... print 'UCS2 build' + ... print('UCS2 build') The only way to solve this problem is to use extension modules compiled with a Python binary built using the same size for Unicode characters. - - - Modified: python/branches/py3k/Doc/faq/gui.rst ============================================================================== --- python/branches/py3k/Doc/faq/gui.rst (original) +++ python/branches/py3k/Doc/faq/gui.rst Sat Dec 19 18:59:59 2009 @@ -6,6 +6,9 @@ .. contents:: +.. XXX need review for Python 3. + + General GUI Questions ===================== @@ -159,6 +162,3 @@ have "keyboard focus". Check out the Tk documentation for the focus command. Usually a widget is given the keyboard focus by clicking in it (but not for labels; see the takefocus option). - - - Modified: python/branches/py3k/Doc/faq/windows.rst ============================================================================== --- python/branches/py3k/Doc/faq/windows.rst (original) +++ python/branches/py3k/Doc/faq/windows.rst Sat Dec 19 18:59:59 2009 @@ -8,6 +8,10 @@ .. contents:: +.. XXX need review for Python 3. + XXX need review for Windows Vista/Seven? + + How do I run a Python program under Windows? -------------------------------------------- @@ -67,7 +71,7 @@ evaluated while you wait. This is one of Python's strongest features. Check it by entering a few expressions of your choice and seeing the results:: - >>> print "Hello" + >>> print("Hello") Hello >>> "Hello" * 3 HelloHelloHello @@ -507,7 +511,7 @@ import win32pipe f = win32pipe.popen('dir /c c:\\') - print f.readlines() + print(f.readlines()) f.close() From python-checkins at python.org Sat Dec 19 19:16:32 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 18:16:32 -0000 Subject: [Python-checkins] r76891 - python/trunk/Doc/library/os.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 19:16:31 2009 New Revision: 76891 Log: #7479: add note about function availability on Unices. Modified: python/trunk/Doc/library/os.rst Modified: python/trunk/Doc/library/os.rst ============================================================================== --- python/trunk/Doc/library/os.rst (original) +++ python/trunk/Doc/library/os.rst Sat Dec 19 19:16:31 2009 @@ -13,19 +13,24 @@ module, and for high-level file and directory handling see the :mod:`shutil` module. -The design of all built-in operating system dependent modules of Python is such -that as long as the same functionality is available, it uses the same interface; -for example, the function ``os.stat(path)`` returns stat information about -*path* in the same format (which happens to have originated with the POSIX -interface). +Notes on the availability of these functions: -Extensions peculiar to a particular operating system are also available through -the :mod:`os` module, but using them is of course a threat to portability! +* The design of all built-in operating system dependent modules of Python is + such that as long as the same functionality is available, it uses the same + interface; for example, the function ``os.stat(path)`` returns stat + information about *path* in the same format (which happens to have originated + with the POSIX interface). + +* Extensions peculiar to a particular operating system are also available + through the :mod:`os` module, but using them is of course a threat to + portability. + +* An "Availability: Unix" note means that this function is commonly found on + Unix systems. It does not make any claims about its existence on a specific + operating system. -.. note:: - - If not separately noted, all functions that claim "Availability: Unix" are - supported on Mac OS X, which builds on a Unix core. +* If not separately noted, all functions that claim "Availability: Unix" are + supported on Mac OS X, which builds on a Unix core. .. note:: @@ -41,9 +46,9 @@ .. data:: name - The name of the operating system dependent module imported. The following names - have currently been registered: ``'posix'``, ``'nt'``, ``'mac'``, ``'os2'``, - ``'ce'``, ``'java'``, ``'riscos'``. + The name of the operating system dependent module imported. The following + names have currently been registered: ``'posix'``, ``'nt'``, ``'mac'``, + ``'os2'``, ``'ce'``, ``'java'``, ``'riscos'``. .. _os-procinfo: From python-checkins at python.org Sat Dec 19 19:20:18 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 18:20:18 -0000 Subject: [Python-checkins] r76892 - python/trunk/Doc/library/stdtypes.rst Message-ID: Author: georg.brandl Date: Sat Dec 19 19:20:18 2009 New Revision: 76892 Log: #7480: remove tautology. 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 Sat Dec 19 19:20:18 2009 @@ -2828,8 +2828,7 @@ .. attribute:: class.__bases__ - The tuple of base classes of a class object. If there are no base classes, this - will be an empty tuple. + The tuple of base classes of a class object. .. attribute:: class.__name__ From python-checkins at python.org Sat Dec 19 19:22:15 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 19 Dec 2009 18:22:15 -0000 Subject: [Python-checkins] r76893 - python/branches/py3k/Doc/library/stdtypes.rst Message-ID: Author: antoine.pitrou Date: Sat Dec 19 19:22:15 2009 New Revision: 76893 Log: Issue #7508: remove obsolete documentation about built-in file objects. Modified: python/branches/py3k/Doc/library/stdtypes.rst Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Sat Dec 19 19:22:15 2009 @@ -12,7 +12,7 @@ .. index:: pair: built-in; types -The principal built-in types are numerics, sequences, mappings, files, classes, +The principal built-in types are numerics, sequences, mappings, classes, instances and exceptions. Some operations are supported by several object types; in particular, @@ -165,7 +165,7 @@ pair: objects; comparing Objects of different types, except different numeric types, never compare equal. -Furthermore, some types (for example, file objects) support only a degenerate +Furthermore, some types (for example, function objects) support only a degenerate notion of comparison where any two objects of that type are unequal. The ``<``, ``<=``, ``>`` and ``>=`` operators will raise a :exc:`TypeError` exception when any operand is a complex number, the objects are of different types that cannot @@ -2070,283 +2070,6 @@ {'bacon'} -.. _bltin-file-objects: - -File Objects -============ - -.. index:: - object: file - builtin: file - module: os - module: socket - -.. XXX this is quite out of date, must be updated with "io" module - -File objects are implemented using C's ``stdio`` package and can be -created with the built-in :func:`open` function. File -objects are also returned by some other built-in functions and methods, -such as :func:`os.popen` and :func:`os.fdopen` and the :meth:`makefile` -method of socket objects. Temporary files can be created using the -:mod:`tempfile` module, and high-level file operations such as copying, -moving, and deleting files and directories can be achieved with the -:mod:`shutil` module. - -When a file operation fails for an I/O-related reason, the exception -:exc:`IOError` is raised. This includes situations where the operation is not -defined for some reason, like :meth:`seek` on a tty device or writing a file -opened for reading. - -Files have the following methods: - - -.. method:: file.close() - - Close the file. A closed file cannot be read or written any more. Any operation - which requires that the file be open will raise a :exc:`ValueError` after the - file has been closed. Calling :meth:`close` more than once is allowed. - - You can avoid having to call this method explicitly if you use - the :keyword:`with` statement. For example, the following code will - automatically close *f* when the :keyword:`with` block is exited:: - - from __future__ import with_statement # This isn't required in Python 2.6 - - with open("hello.txt") as f: - for line in f: - print(line) - - In older versions of Python, you would have needed to do this to get the same - effect:: - - f = open("hello.txt") - try: - for line in f: - print(line) - finally: - f.close() - - .. note:: - - Not all "file-like" types in Python support use as a context manager for the - :keyword:`with` statement. If your code is intended to work with any file-like - object, you can use the function :func:`contextlib.closing` instead of using - the object directly. - - -.. method:: file.flush() - - Flush the internal buffer, like ``stdio``'s :cfunc:`fflush`. This may be a - no-op on some file-like objects. - - .. note:: - - :meth:`flush` does not necessarily write the file's data to disk. Use - :meth:`flush` followed by :func:`os.fsync` to ensure this behavior. - - -.. method:: file.fileno() - - .. index:: - pair: file; descriptor - module: fcntl - - Return the integer "file descriptor" that is used by the underlying - implementation to request I/O operations from the operating system. This can be - useful for other, lower level interfaces that use file descriptors, such as the - :mod:`fcntl` module or :func:`os.read` and friends. - - .. note:: - - File-like objects which do not have a real file descriptor should *not* provide - this method! - - -.. method:: file.isatty() - - Return ``True`` if the file is connected to a tty(-like) device, else ``False``. - - .. note:: - - If a file-like object is not associated with a real file, this method should - *not* be implemented. - - -.. method:: file.__next__() - - A file object is its own iterator, for example ``iter(f)`` returns *f* (unless - *f* is closed). When a file is used as an iterator, typically in a - :keyword:`for` loop (for example, ``for line in f: print(line)``), the - :meth:`__next__` method is called repeatedly. This method returns the next - input line, or raises :exc:`StopIteration` when EOF is hit when the file is open - for reading (behavior is undefined when the file is open for writing). In order - to make a :keyword:`for` loop the most efficient way of looping over the lines - of a file (a very common operation), the :meth:`__next__` method uses a hidden - read-ahead buffer. As a consequence of using a read-ahead buffer, combining - :meth:`__next__` with other file methods (like :meth:`readline`) does not work - right. However, using :meth:`seek` to reposition the file to an absolute - position will flush the read-ahead buffer. - - -.. method:: file.read([size]) - - Read at most *size* bytes from the file (less if the read hits EOF before - obtaining *size* bytes). If the *size* argument is negative or omitted, read - all data until EOF is reached. The bytes are returned as a string object. An - empty string is returned when EOF is encountered immediately. (For certain - files, like ttys, it makes sense to continue reading after an EOF is hit.) Note - that this method may call the underlying C function :cfunc:`fread` more than - once in an effort to acquire as close to *size* bytes as possible. Also note - that when in non-blocking mode, less data than was requested may be - returned, even if no *size* parameter was given. - - -.. method:: file.readline([size]) - - Read one entire line from the file. A trailing newline character is kept in the - string (but may be absent when a file ends with an incomplete line). [#]_ If - the *size* argument is present and non-negative, it is a maximum byte count - (including the trailing newline) and an incomplete line may be returned. An - empty string is returned *only* when EOF is encountered immediately. - - .. note:: - - Unlike ``stdio``'s :cfunc:`fgets`, the returned string contains null characters - (``'\0'``) if they occurred in the input. - - -.. method:: file.readlines([sizehint]) - - Read until EOF using :meth:`readline` and return a list containing the lines - thus read. If the optional *sizehint* argument is present, instead of - reading up to EOF, whole lines totalling approximately *sizehint* bytes - (possibly after rounding up to an internal buffer size) are read. Objects - implementing a file-like interface may choose to ignore *sizehint* if it - cannot be implemented, or cannot be implemented efficiently. - - -.. method:: file.seek(offset[, whence]) - - Set the file's current position, like ``stdio``'s :cfunc:`fseek`. The *whence* - argument is optional and defaults to ``os.SEEK_SET`` or ``0`` (absolute file - positioning); other values are ``os.SEEK_CUR`` or ``1`` (seek relative to the - current position) and ``os.SEEK_END`` or ``2`` (seek relative to the file's - end). There is no return value. - - For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by two and - ``f.seek(-3, os.SEEK_END)`` sets the position to the third to last. - - Note that if the file is opened for appending - (mode ``'a'`` or ``'a+'``), any :meth:`seek` operations will be undone at the - next write. If the file is only opened for writing in append mode (mode - ``'a'``), this method is essentially a no-op, but it remains useful for files - opened in append mode with reading enabled (mode ``'a+'``). If the file is - opened in text mode (without ``'b'``), only offsets returned by :meth:`tell` are - legal. Use of other offsets causes undefined behavior. - - Note that not all file objects are seekable. - - -.. method:: file.tell() - - Return the file's current position, like ``stdio``'s :cfunc:`ftell`. - - .. note:: - - On Windows, :meth:`tell` can return illegal values (after an :cfunc:`fgets`) - when reading files with Unix-style line-endings. Use binary mode (``'rb'``) to - circumvent this problem. - - -.. method:: file.truncate([size]) - - Truncate the file's size. If the optional *size* argument is present, the file - is truncated to (at most) that size. The size defaults to the current position. - The current file position is not changed. Note that if a specified size exceeds - the file's current size, the result is platform-dependent: possibilities - include that the file may remain unchanged, increase to the specified size as if - zero-filled, or increase to the specified size with undefined new content. - Availability: Windows, many Unix variants. - - -.. method:: file.write(str) - - Write a string to the file. Due to buffering, the string may not actually - show up in the file until the :meth:`flush` or :meth:`close` method is - called. - - The meaning of the return value is not defined for every file-like object. - Some (mostly low-level) file-like objects may return the number of bytes - actually written, others return ``None``. - - -.. method:: file.writelines(sequence) - - Write a sequence of strings to the file. The sequence can be any iterable - object producing strings, typically a list of strings. There is no return value. - (The name is intended to match :meth:`readlines`; :meth:`writelines` does not - add line separators.) - -Files support the iterator protocol. Each iteration returns the same result as -``file.readline()``, and iteration ends when the :meth:`readline` method returns -an empty string. - -File objects also offer a number of other interesting attributes. These are not -required for file-like objects, but should be implemented if they make sense for -the particular object. - - -.. attribute:: file.closed - - bool indicating the current state of the file object. This is a read-only - attribute; the :meth:`close` method changes the value. It may not be available - on all file-like objects. - - -.. XXX does this still apply? -.. attribute:: file.encoding - - The encoding that this file uses. When strings are written to a file, - they will be converted to byte strings using this encoding. In addition, when - the file is connected to a terminal, the attribute gives the encoding that the - terminal is likely to use (that information might be incorrect if the user has - misconfigured the terminal). The attribute is read-only and may not be present - on all file-like objects. It may also be ``None``, in which case the file uses - the system default encoding for converting strings. - - -.. attribute:: file.errors - - The Unicode error handler used along with the encoding. - - -.. attribute:: file.mode - - The I/O mode for the file. If the file was created using the :func:`open` - built-in function, this will be the value of the *mode* parameter. This is a - read-only attribute and may not be present on all file-like objects. - - -.. attribute:: file.name - - If the file object was created using :func:`open`, the name of the file. - Otherwise, some string that indicates the source of the file object, of the - form ``<...>``. This is a read-only attribute and may not be present on all - file-like objects. - - -.. attribute:: file.newlines - - If Python was built with the :option:`--with-universal-newlines` option to - :program:`configure` (the default) this read-only attribute exists, and for - files opened in universal newline read mode it keeps track of the types of - newlines encountered while reading the file. The values it can take are - ``'\r'``, ``'\n'``, ``'\r\n'``, ``None`` (unknown, no newlines read yet) or a - tuple containing all the newline types seen, to indicate that multiple newline - conventions were encountered. For files not opened in universal newline read - mode the value of this attribute will be ``None``. - - .. _typememoryview: memoryview Types @@ -2781,9 +2504,3 @@ .. [#] To format only a tuple you should therefore provide a singleton tuple whose only element is the tuple to be formatted. - -.. [#] The advantage of leaving the newline on is that returning an empty string is - then an unambiguous EOF indication. It is also possible (in cases where it - might matter, for example, if you want to make an exact copy of a file while - scanning its lines) to tell whether the last line of a file ended in a newline - or not (yes this happens!). From python-checkins at python.org Sat Dec 19 19:23:15 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 19 Dec 2009 18:23:15 -0000 Subject: [Python-checkins] r76894 - in python/branches/release31-maint: Doc/library/stdtypes.rst Message-ID: Author: antoine.pitrou Date: Sat Dec 19 19:23:15 2009 New Revision: 76894 Log: Merged revisions 76893 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76893 | antoine.pitrou | 2009-12-19 19:22:15 +0100 (sam., 19 d?c. 2009) | 4 lines Issue #7508: remove obsolete documentation about built-in file objects. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/stdtypes.rst Modified: python/branches/release31-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release31-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release31-maint/Doc/library/stdtypes.rst Sat Dec 19 19:23:15 2009 @@ -12,7 +12,7 @@ .. index:: pair: built-in; types -The principal built-in types are numerics, sequences, mappings, files, classes, +The principal built-in types are numerics, sequences, mappings, classes, instances and exceptions. Some operations are supported by several object types; in particular, @@ -165,7 +165,7 @@ pair: objects; comparing Objects of different types, except different numeric types, never compare equal. -Furthermore, some types (for example, file objects) support only a degenerate +Furthermore, some types (for example, function objects) support only a degenerate notion of comparison where any two objects of that type are unequal. The ``<``, ``<=``, ``>`` and ``>=`` operators will raise a :exc:`TypeError` exception when any operand is a complex number, the objects are of different types that cannot @@ -2066,283 +2066,6 @@ {'bacon'} -.. _bltin-file-objects: - -File Objects -============ - -.. index:: - object: file - builtin: file - module: os - module: socket - -.. XXX this is quite out of date, must be updated with "io" module - -File objects are implemented using C's ``stdio`` package and can be -created with the built-in :func:`open` function. File -objects are also returned by some other built-in functions and methods, -such as :func:`os.popen` and :func:`os.fdopen` and the :meth:`makefile` -method of socket objects. Temporary files can be created using the -:mod:`tempfile` module, and high-level file operations such as copying, -moving, and deleting files and directories can be achieved with the -:mod:`shutil` module. - -When a file operation fails for an I/O-related reason, the exception -:exc:`IOError` is raised. This includes situations where the operation is not -defined for some reason, like :meth:`seek` on a tty device or writing a file -opened for reading. - -Files have the following methods: - - -.. method:: file.close() - - Close the file. A closed file cannot be read or written any more. Any operation - which requires that the file be open will raise a :exc:`ValueError` after the - file has been closed. Calling :meth:`close` more than once is allowed. - - You can avoid having to call this method explicitly if you use - the :keyword:`with` statement. For example, the following code will - automatically close *f* when the :keyword:`with` block is exited:: - - from __future__ import with_statement # This isn't required in Python 2.6 - - with open("hello.txt") as f: - for line in f: - print(line) - - In older versions of Python, you would have needed to do this to get the same - effect:: - - f = open("hello.txt") - try: - for line in f: - print(line) - finally: - f.close() - - .. note:: - - Not all "file-like" types in Python support use as a context manager for the - :keyword:`with` statement. If your code is intended to work with any file-like - object, you can use the function :func:`contextlib.closing` instead of using - the object directly. - - -.. method:: file.flush() - - Flush the internal buffer, like ``stdio``'s :cfunc:`fflush`. This may be a - no-op on some file-like objects. - - .. note:: - - :meth:`flush` does not necessarily write the file's data to disk. Use - :meth:`flush` followed by :func:`os.fsync` to ensure this behavior. - - -.. method:: file.fileno() - - .. index:: - pair: file; descriptor - module: fcntl - - Return the integer "file descriptor" that is used by the underlying - implementation to request I/O operations from the operating system. This can be - useful for other, lower level interfaces that use file descriptors, such as the - :mod:`fcntl` module or :func:`os.read` and friends. - - .. note:: - - File-like objects which do not have a real file descriptor should *not* provide - this method! - - -.. method:: file.isatty() - - Return ``True`` if the file is connected to a tty(-like) device, else ``False``. - - .. note:: - - If a file-like object is not associated with a real file, this method should - *not* be implemented. - - -.. method:: file.__next__() - - A file object is its own iterator, for example ``iter(f)`` returns *f* (unless - *f* is closed). When a file is used as an iterator, typically in a - :keyword:`for` loop (for example, ``for line in f: print(line)``), the - :meth:`__next__` method is called repeatedly. This method returns the next - input line, or raises :exc:`StopIteration` when EOF is hit when the file is open - for reading (behavior is undefined when the file is open for writing). In order - to make a :keyword:`for` loop the most efficient way of looping over the lines - of a file (a very common operation), the :meth:`__next__` method uses a hidden - read-ahead buffer. As a consequence of using a read-ahead buffer, combining - :meth:`__next__` with other file methods (like :meth:`readline`) does not work - right. However, using :meth:`seek` to reposition the file to an absolute - position will flush the read-ahead buffer. - - -.. method:: file.read([size]) - - Read at most *size* bytes from the file (less if the read hits EOF before - obtaining *size* bytes). If the *size* argument is negative or omitted, read - all data until EOF is reached. The bytes are returned as a string object. An - empty string is returned when EOF is encountered immediately. (For certain - files, like ttys, it makes sense to continue reading after an EOF is hit.) Note - that this method may call the underlying C function :cfunc:`fread` more than - once in an effort to acquire as close to *size* bytes as possible. Also note - that when in non-blocking mode, less data than was requested may be - returned, even if no *size* parameter was given. - - -.. method:: file.readline([size]) - - Read one entire line from the file. A trailing newline character is kept in the - string (but may be absent when a file ends with an incomplete line). [#]_ If - the *size* argument is present and non-negative, it is a maximum byte count - (including the trailing newline) and an incomplete line may be returned. An - empty string is returned *only* when EOF is encountered immediately. - - .. note:: - - Unlike ``stdio``'s :cfunc:`fgets`, the returned string contains null characters - (``'\0'``) if they occurred in the input. - - -.. method:: file.readlines([sizehint]) - - Read until EOF using :meth:`readline` and return a list containing the lines - thus read. If the optional *sizehint* argument is present, instead of - reading up to EOF, whole lines totalling approximately *sizehint* bytes - (possibly after rounding up to an internal buffer size) are read. Objects - implementing a file-like interface may choose to ignore *sizehint* if it - cannot be implemented, or cannot be implemented efficiently. - - -.. method:: file.seek(offset[, whence]) - - Set the file's current position, like ``stdio``'s :cfunc:`fseek`. The *whence* - argument is optional and defaults to ``os.SEEK_SET`` or ``0`` (absolute file - positioning); other values are ``os.SEEK_CUR`` or ``1`` (seek relative to the - current position) and ``os.SEEK_END`` or ``2`` (seek relative to the file's - end). There is no return value. - - For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by two and - ``f.seek(-3, os.SEEK_END)`` sets the position to the third to last. - - Note that if the file is opened for appending - (mode ``'a'`` or ``'a+'``), any :meth:`seek` operations will be undone at the - next write. If the file is only opened for writing in append mode (mode - ``'a'``), this method is essentially a no-op, but it remains useful for files - opened in append mode with reading enabled (mode ``'a+'``). If the file is - opened in text mode (without ``'b'``), only offsets returned by :meth:`tell` are - legal. Use of other offsets causes undefined behavior. - - Note that not all file objects are seekable. - - -.. method:: file.tell() - - Return the file's current position, like ``stdio``'s :cfunc:`ftell`. - - .. note:: - - On Windows, :meth:`tell` can return illegal values (after an :cfunc:`fgets`) - when reading files with Unix-style line-endings. Use binary mode (``'rb'``) to - circumvent this problem. - - -.. method:: file.truncate([size]) - - Truncate the file's size. If the optional *size* argument is present, the file - is truncated to (at most) that size. The size defaults to the current position. - The current file position is not changed. Note that if a specified size exceeds - the file's current size, the result is platform-dependent: possibilities - include that the file may remain unchanged, increase to the specified size as if - zero-filled, or increase to the specified size with undefined new content. - Availability: Windows, many Unix variants. - - -.. method:: file.write(str) - - Write a string to the file. Due to buffering, the string may not actually - show up in the file until the :meth:`flush` or :meth:`close` method is - called. - - The meaning of the return value is not defined for every file-like object. - Some (mostly low-level) file-like objects may return the number of bytes - actually written, others return ``None``. - - -.. method:: file.writelines(sequence) - - Write a sequence of strings to the file. The sequence can be any iterable - object producing strings, typically a list of strings. There is no return value. - (The name is intended to match :meth:`readlines`; :meth:`writelines` does not - add line separators.) - -Files support the iterator protocol. Each iteration returns the same result as -``file.readline()``, and iteration ends when the :meth:`readline` method returns -an empty string. - -File objects also offer a number of other interesting attributes. These are not -required for file-like objects, but should be implemented if they make sense for -the particular object. - - -.. attribute:: file.closed - - bool indicating the current state of the file object. This is a read-only - attribute; the :meth:`close` method changes the value. It may not be available - on all file-like objects. - - -.. XXX does this still apply? -.. attribute:: file.encoding - - The encoding that this file uses. When strings are written to a file, - they will be converted to byte strings using this encoding. In addition, when - the file is connected to a terminal, the attribute gives the encoding that the - terminal is likely to use (that information might be incorrect if the user has - misconfigured the terminal). The attribute is read-only and may not be present - on all file-like objects. It may also be ``None``, in which case the file uses - the system default encoding for converting strings. - - -.. attribute:: file.errors - - The Unicode error handler used along with the encoding. - - -.. attribute:: file.mode - - The I/O mode for the file. If the file was created using the :func:`open` - built-in function, this will be the value of the *mode* parameter. This is a - read-only attribute and may not be present on all file-like objects. - - -.. attribute:: file.name - - If the file object was created using :func:`open`, the name of the file. - Otherwise, some string that indicates the source of the file object, of the - form ``<...>``. This is a read-only attribute and may not be present on all - file-like objects. - - -.. attribute:: file.newlines - - If Python was built with the :option:`--with-universal-newlines` option to - :program:`configure` (the default) this read-only attribute exists, and for - files opened in universal newline read mode it keeps track of the types of - newlines encountered while reading the file. The values it can take are - ``'\r'``, ``'\n'``, ``'\r\n'``, ``None`` (unknown, no newlines read yet) or a - tuple containing all the newline types seen, to indicate that multiple newline - conventions were encountered. For files not opened in universal newline read - mode the value of this attribute will be ``None``. - - .. _typememoryview: memoryview Types @@ -2777,9 +2500,3 @@ .. [#] To format only a tuple you should therefore provide a singleton tuple whose only element is the tuple to be formatted. - -.. [#] The advantage of leaving the newline on is that returning an empty string is - then an unambiguous EOF indication. It is also possible (in cases where it - might matter, for example, if you want to make an exact copy of a file while - scanning its lines) to tell whether the last line of a file ended in a newline - or not (yes this happens!). From python-checkins at python.org Sat Dec 19 19:23:28 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 19 Dec 2009 18:23:28 -0000 Subject: [Python-checkins] r76895 - in python/branches/py3k: Doc/library/uuid.rst Lib/test/test_uuid.py Lib/uuid.py Message-ID: Author: georg.brandl Date: Sat Dec 19 19:23:28 2009 New Revision: 76895 Log: #7380: Fix some str/bytearray/bytes issues in uuid docs and implementation. Modified: python/branches/py3k/Doc/library/uuid.rst python/branches/py3k/Lib/test/test_uuid.py python/branches/py3k/Lib/uuid.py Modified: python/branches/py3k/Doc/library/uuid.rst ============================================================================== --- python/branches/py3k/Doc/library/uuid.rst (original) +++ python/branches/py3k/Doc/library/uuid.rst Sat Dec 19 19:23:28 2009 @@ -31,9 +31,9 @@ UUID('{12345678-1234-5678-1234-567812345678}') UUID('12345678123456781234567812345678') UUID('urn:uuid:12345678-1234-5678-1234-567812345678') - UUID(bytes='\x12\x34\x56\x78'*4) - UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' + - '\x12\x34\x56\x78\x12\x34\x56\x78') + UUID(bytes=b'\x12\x34\x56\x78'*4) + UUID(bytes_le=b'\x78\x56\x34\x12\x34\x12\x78\x56' + + b'\x12\x34\x56\x78\x12\x34\x56\x78') UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678)) UUID(int=0x12345678123456781234567812345678) @@ -247,7 +247,7 @@ # get the raw 16 bytes of the UUID >>> x.bytes - '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f' # make a UUID from a 16-byte string >>> uuid.UUID(bytes=x.bytes) Modified: python/branches/py3k/Lib/test/test_uuid.py ============================================================================== --- python/branches/py3k/Lib/test/test_uuid.py (original) +++ python/branches/py3k/Lib/test/test_uuid.py Sat Dec 19 19:23:28 2009 @@ -1,5 +1,6 @@ from unittest import TestCase from test import support +import builtins import uuid def importable(name): @@ -176,6 +177,11 @@ for u in equivalents: for v in equivalents: equal(u, v) + + # Bug 7380: "bytes" and "bytes_le" should give the same type. + equal(type(u.bytes), builtins.bytes) + equal(type(u.bytes_le), builtins.bytes) + ascending.append(u) # Test comparison of UUIDs. Modified: python/branches/py3k/Lib/uuid.py ============================================================================== --- python/branches/py3k/Lib/uuid.py (original) +++ python/branches/py3k/Lib/uuid.py Sat Dec 19 19:23:28 2009 @@ -13,7 +13,7 @@ >>> import uuid # make a UUID based on the host ID and current time - >>> uuid.uuid1() + >>> uuid.uuid1() # doctest: +SKIP UUID('a8098c1a-f86e-11da-bd1a-00112444be1e') # make a UUID using an MD5 hash of a namespace UUID and a name @@ -21,7 +21,7 @@ UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e') # make a random UUID - >>> uuid.uuid4() + >>> uuid.uuid4() # doctest: +SKIP UUID('16fd2706-8baf-433b-82eb-8c7fada847da') # make a UUID using a SHA-1 hash of a namespace UUID and a name @@ -237,7 +237,7 @@ bytes = bytearray() for shift in range(0, 128, 8): bytes.insert(0, (self.int >> shift) & 0xff) - return bytes + return bytes_(bytes) @property def bytes_le(self): From python-checkins at python.org Sat Dec 19 22:01:11 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 19 Dec 2009 21:01:11 -0000 Subject: [Python-checkins] r76896 - in python/trunk: Doc/library/io.rst Lib/_pyio.py Modules/_io/_iomodule.c Message-ID: Author: antoine.pitrou Date: Sat Dec 19 22:01:10 2009 New Revision: 76896 Log: Issue #7545: improve documentation of the `buffering` argument in io.open(). Modified: python/trunk/Doc/library/io.rst python/trunk/Lib/_pyio.py python/trunk/Modules/_io/_iomodule.c Modified: python/trunk/Doc/library/io.rst ============================================================================== --- python/trunk/Doc/library/io.rst (original) +++ python/trunk/Doc/library/io.rst Sat Dec 19 22:01:10 2009 @@ -106,10 +106,20 @@ :class:`unicode` strings, the bytes having been first decoded using a platform-dependent encoding or using the specified *encoding* if given. - *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 - in binary mode), 1 to set line buffering, and an integer > 1 to indicate the - size of the buffer. + *buffering* is an optional integer used to set the buffering policy. + Pass 0 to switch buffering off (only allowed in binary mode), 1 to select + line buffering (only usable in text mode), and an integer > 1 to indicate + the size of a fixed-size chunk buffer. When no *buffering* argument is + given, the default buffering policy works as follows: + + * Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on :attr:`DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + + * "Interactive" text files (files for which :meth:`isatty` returns True) + use line buffering. Other text files use the policy described above + for binary files. *encoding* is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform Modified: python/trunk/Lib/_pyio.py ============================================================================== --- python/trunk/Lib/_pyio.py (original) +++ python/trunk/Lib/_pyio.py Sat Dec 19 22:01:10 2009 @@ -92,6 +92,21 @@ allowed in binary mode), 1 to set line buffering, and an integer > 1 for full buffering. + buffering is an optional integer used to set the buffering policy. + Pass 0 to switch buffering off (only allowed in binary mode), 1 to select + line buffering (only usable in text mode), and an integer > 1 to indicate + the size of a fixed-size chunk buffer. When no buffering argument is + given, the default buffering policy works as follows: + + * Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + + * "Interactive" text files (files for which isatty() returns True) + use line buffering. Other text files use the policy described above + for binary files. + encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform dependent, but any encoding supported by Python can be Modified: python/trunk/Modules/_io/_iomodule.c ============================================================================== --- python/trunk/Modules/_io/_iomodule.c (original) +++ python/trunk/Modules/_io/_iomodule.c Sat Dec 19 22:01:10 2009 @@ -219,10 +219,20 @@ "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" +"buffering is an optional integer used to set the buffering policy.\n" +"Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n" +"line buffering (only usable in text mode), and an integer > 1 to indicate\n" +"the size of a fixed-size chunk buffer. When no buffering argument is\n" +"given, the default buffering policy works as follows:\n" +"\n" +"* Binary files are buffered in fixed-size chunks; the size of the buffer\n" +" is chosen using a heuristic trying to determine the underlying device's\n" +" \"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`.\n" +" On many systems, the buffer will typically be 4096 or 8192 bytes long.\n" +"\n" +"* \"Interactive\" text files (files for which isatty() returns True)\n" +" use line buffering. Other text files use the policy described above\n" +" for binary files.\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" From python-checkins at python.org Sat Dec 19 22:03:37 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 19 Dec 2009 21:03:37 -0000 Subject: [Python-checkins] r76897 - in python/branches/release26-maint: Doc/library/io.rst Lib/io.py Message-ID: Author: antoine.pitrou Date: Sat Dec 19 22:03:36 2009 New Revision: 76897 Log: Merged revisions 76896 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76896 | antoine.pitrou | 2009-12-19 22:01:10 +0100 (sam., 19 d?c. 2009) | 3 lines Issue #7545: improve documentation of the `buffering` argument in io.open(). ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/io.rst python/branches/release26-maint/Lib/io.py Modified: python/branches/release26-maint/Doc/library/io.rst ============================================================================== --- python/branches/release26-maint/Doc/library/io.rst (original) +++ python/branches/release26-maint/Doc/library/io.rst Sat Dec 19 22:03:36 2009 @@ -94,10 +94,20 @@ strings, the bytes having been first decoded using a platform-dependent encoding or using the specified *encoding* if given. - *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 - in binary mode), 1 to set line buffering, and an integer > 1 to indicate the - size of the buffer. + *buffering* is an optional integer used to set the buffering policy. + Pass 0 to switch buffering off (only allowed in binary mode), 1 to select + line buffering (only usable in text mode), and an integer > 1 to indicate + the size of a fixed-size chunk buffer. When no *buffering* argument is + given, the default buffering policy works as follows: + + * Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on :attr:`DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + + * "Interactive" text files (files for which :meth:`isatty` returns True) + use line buffering. Other text files use the policy described above + for binary files. *encoding* is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform Modified: python/branches/release26-maint/Lib/io.py ============================================================================== --- python/branches/release26-maint/Lib/io.py (original) +++ python/branches/release26-maint/Lib/io.py Sat Dec 19 22:03:36 2009 @@ -124,10 +124,20 @@ returned as strings, the bytes having been first decoded using a platform-dependent encoding or using the specified encoding if given. - 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 in binary mode), 1 to set line buffering, and an integer > 1 - for full buffering. + buffering is an optional integer used to set the buffering policy. + Pass 0 to switch buffering off (only allowed in binary mode), 1 to select + line buffering (only usable in text mode), and an integer > 1 to indicate + the size of a fixed-size chunk buffer. When no buffering argument is + given, the default buffering policy works as follows: + + * Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + + * "Interactive" text files (files for which isatty() returns True) + use line buffering. Other text files use the policy described above + for binary files. encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is From python-checkins at python.org Sat Dec 19 22:06:36 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 19 Dec 2009 21:06:36 -0000 Subject: [Python-checkins] r76898 - python/trunk/Lib/_pyio.py Message-ID: Author: antoine.pitrou Date: Sat Dec 19 22:06:36 2009 New Revision: 76898 Log: Remove superfetatory paragraph (left there by mistake). Modified: python/trunk/Lib/_pyio.py Modified: python/trunk/Lib/_pyio.py ============================================================================== --- python/trunk/Lib/_pyio.py (original) +++ python/trunk/Lib/_pyio.py Sat Dec 19 22:06:36 2009 @@ -87,11 +87,6 @@ returned as strings, the bytes having been first decoded using a platform-dependent encoding or using the specified encoding if given. - 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 in binary mode), 1 to set line buffering, and an integer > 1 - for full buffering. - buffering is an optional integer used to set the buffering policy. Pass 0 to switch buffering off (only allowed in binary mode), 1 to select line buffering (only usable in text mode), and an integer > 1 to indicate From python-checkins at python.org Sat Dec 19 22:07:24 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 19 Dec 2009 21:07:24 -0000 Subject: [Python-checkins] r76899 - python/branches/release26-maint Message-ID: Author: antoine.pitrou Date: Sat Dec 19 22:07:24 2009 New Revision: 76899 Log: Blocked revisions 76898 via svnmerge ........ r76898 | antoine.pitrou | 2009-12-19 22:06:36 +0100 (sam., 19 d?c. 2009) | 3 lines Remove superfetatory paragraph (left there by mistake). ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Dec 19 22:08:31 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 19 Dec 2009 21:08:31 -0000 Subject: [Python-checkins] r76900 - in python/branches/py3k: Doc/library/io.rst Lib/_pyio.py Modules/_io/_iomodule.c Message-ID: Author: antoine.pitrou Date: Sat Dec 19 22:08:31 2009 New Revision: 76900 Log: Merged revisions 76896,76898 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76896 | antoine.pitrou | 2009-12-19 22:01:10 +0100 (sam., 19 d?c. 2009) | 3 lines Issue #7545: improve documentation of the `buffering` argument in io.open(). ........ r76898 | antoine.pitrou | 2009-12-19 22:06:36 +0100 (sam., 19 d?c. 2009) | 3 lines Remove superfetatory paragraph (left there by mistake). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/io.rst python/branches/py3k/Lib/_pyio.py python/branches/py3k/Modules/_io/_iomodule.c Modified: python/branches/py3k/Doc/library/io.rst ============================================================================== --- python/branches/py3k/Doc/library/io.rst (original) +++ python/branches/py3k/Doc/library/io.rst Sat Dec 19 22:08:31 2009 @@ -96,10 +96,20 @@ strings, the bytes having been first decoded using a platform-dependent encoding or using the specified *encoding* if given. - *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 - in binary mode), 1 to set line buffering, and an integer > 1 to indicate the - size of the buffer. + *buffering* is an optional integer used to set the buffering policy. + Pass 0 to switch buffering off (only allowed in binary mode), 1 to select + line buffering (only usable in text mode), and an integer > 1 to indicate + the size of a fixed-size chunk buffer. When no *buffering* argument is + given, the default buffering policy works as follows: + + * Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on :attr:`DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + + * "Interactive" text files (files for which :meth:`isatty` returns True) + use line buffering. Other text files use the policy described above + for binary files. *encoding* is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform Modified: python/branches/py3k/Lib/_pyio.py ============================================================================== --- python/branches/py3k/Lib/_pyio.py (original) +++ python/branches/py3k/Lib/_pyio.py Sat Dec 19 22:08:31 2009 @@ -82,10 +82,20 @@ returned as strings, the bytes having been first decoded using a platform-dependent encoding or using the specified encoding if given. - 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 in binary mode), 1 to set line buffering, and an integer > 1 - for full buffering. + buffering is an optional integer used to set the buffering policy. + Pass 0 to switch buffering off (only allowed in binary mode), 1 to select + line buffering (only usable in text mode), and an integer > 1 to indicate + the size of a fixed-size chunk buffer. When no buffering argument is + given, the default buffering policy works as follows: + + * Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + + * "Interactive" text files (files for which isatty() returns True) + use line buffering. Other text files use the policy described above + for binary files. encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is Modified: python/branches/py3k/Modules/_io/_iomodule.c ============================================================================== --- python/branches/py3k/Modules/_io/_iomodule.c (original) +++ python/branches/py3k/Modules/_io/_iomodule.c Sat Dec 19 22:08:31 2009 @@ -219,10 +219,20 @@ "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" +"buffering is an optional integer used to set the buffering policy.\n" +"Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n" +"line buffering (only usable in text mode), and an integer > 1 to indicate\n" +"the size of a fixed-size chunk buffer. When no buffering argument is\n" +"given, the default buffering policy works as follows:\n" +"\n" +"* Binary files are buffered in fixed-size chunks; the size of the buffer\n" +" is chosen using a heuristic trying to determine the underlying device's\n" +" \"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`.\n" +" On many systems, the buffer will typically be 4096 or 8192 bytes long.\n" +"\n" +"* \"Interactive\" text files (files for which isatty() returns True)\n" +" use line buffering. Other text files use the policy described above\n" +" for binary files.\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" From python-checkins at python.org Sat Dec 19 22:09:58 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 19 Dec 2009 21:09:58 -0000 Subject: [Python-checkins] r76901 - in python/branches/release31-maint: Doc/library/io.rst Lib/_pyio.py Modules/_io/_iomodule.c Message-ID: Author: antoine.pitrou Date: Sat Dec 19 22:09:58 2009 New Revision: 76901 Log: Merged revisions 76900 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76900 | antoine.pitrou | 2009-12-19 22:08:31 +0100 (sam., 19 d?c. 2009) | 13 lines Merged revisions 76896,76898 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76896 | antoine.pitrou | 2009-12-19 22:01:10 +0100 (sam., 19 d?c. 2009) | 3 lines Issue #7545: improve documentation of the `buffering` argument in io.open(). ........ r76898 | antoine.pitrou | 2009-12-19 22:06:36 +0100 (sam., 19 d?c. 2009) | 3 lines Remove superfetatory paragraph (left there by mistake). ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/io.rst python/branches/release31-maint/Lib/_pyio.py python/branches/release31-maint/Modules/_io/_iomodule.c Modified: python/branches/release31-maint/Doc/library/io.rst ============================================================================== --- python/branches/release31-maint/Doc/library/io.rst (original) +++ python/branches/release31-maint/Doc/library/io.rst Sat Dec 19 22:09:58 2009 @@ -96,10 +96,20 @@ strings, the bytes having been first decoded using a platform-dependent encoding or using the specified *encoding* if given. - *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 - in binary mode), 1 to set line buffering, and an integer > 1 to indicate the - size of the buffer. + *buffering* is an optional integer used to set the buffering policy. + Pass 0 to switch buffering off (only allowed in binary mode), 1 to select + line buffering (only usable in text mode), and an integer > 1 to indicate + the size of a fixed-size chunk buffer. When no *buffering* argument is + given, the default buffering policy works as follows: + + * Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on :attr:`DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + + * "Interactive" text files (files for which :meth:`isatty` returns True) + use line buffering. Other text files use the policy described above + for binary files. *encoding* is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform Modified: python/branches/release31-maint/Lib/_pyio.py ============================================================================== --- python/branches/release31-maint/Lib/_pyio.py (original) +++ python/branches/release31-maint/Lib/_pyio.py Sat Dec 19 22:09:58 2009 @@ -82,10 +82,20 @@ returned as strings, the bytes having been first decoded using a platform-dependent encoding or using the specified encoding if given. - 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 in binary mode), 1 to set line buffering, and an integer > 1 - for full buffering. + buffering is an optional integer used to set the buffering policy. + Pass 0 to switch buffering off (only allowed in binary mode), 1 to select + line buffering (only usable in text mode), and an integer > 1 to indicate + the size of a fixed-size chunk buffer. When no buffering argument is + given, the default buffering policy works as follows: + + * Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + + * "Interactive" text files (files for which isatty() returns True) + use line buffering. Other text files use the policy described above + for binary files. encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is Modified: python/branches/release31-maint/Modules/_io/_iomodule.c ============================================================================== --- python/branches/release31-maint/Modules/_io/_iomodule.c (original) +++ python/branches/release31-maint/Modules/_io/_iomodule.c Sat Dec 19 22:09:58 2009 @@ -219,10 +219,20 @@ "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" +"buffering is an optional integer used to set the buffering policy.\n" +"Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n" +"line buffering (only usable in text mode), and an integer > 1 to indicate\n" +"the size of a fixed-size chunk buffer. When no buffering argument is\n" +"given, the default buffering policy works as follows:\n" +"\n" +"* Binary files are buffered in fixed-size chunks; the size of the buffer\n" +" is chosen using a heuristic trying to determine the underlying device's\n" +" \"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`.\n" +" On many systems, the buffer will typically be 4096 or 8192 bytes long.\n" +"\n" +"* \"Interactive\" text files (files for which isatty() returns True)\n" +" use line buffering. Other text files use the policy described above\n" +" for binary files.\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" From python-checkins at python.org Sat Dec 19 22:19:36 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 19 Dec 2009 21:19:36 -0000 Subject: [Python-checkins] r76902 - python/branches/py3k/Python/bltinmodule.c Message-ID: Author: mark.dickinson Date: Sat Dec 19 22:19:35 2009 New Revision: 76902 Log: Fix typo (reported by terlop on IRC) Modified: python/branches/py3k/Python/bltinmodule.c Modified: python/branches/py3k/Python/bltinmodule.c ============================================================================== --- python/branches/py3k/Python/bltinmodule.c (original) +++ python/branches/py3k/Python/bltinmodule.c Sat Dec 19 22:19:35 2009 @@ -804,7 +804,7 @@ PyDoc_STRVAR(exec_doc, "exec(object[, globals[, locals]])\n\ \n\ -Read and execute code from a object, which can be a string or a code\n\ +Read and execute code from an object, which can be a string or a code\n\ object.\n\ The globals and locals are dictionaries, defaulting to the current\n\ globals and locals. If only globals is given, locals defaults to it."); From python-checkins at python.org Sat Dec 19 22:20:55 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 19 Dec 2009 21:20:55 -0000 Subject: [Python-checkins] r76903 - in python/branches/release31-maint: Python/bltinmodule.c Message-ID: Author: mark.dickinson Date: Sat Dec 19 22:20:55 2009 New Revision: 76903 Log: Merged revisions 76902 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76902 | mark.dickinson | 2009-12-19 21:19:35 +0000 (Sat, 19 Dec 2009) | 1 line Fix typo (reported by terlop on IRC) ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Python/bltinmodule.c Modified: python/branches/release31-maint/Python/bltinmodule.c ============================================================================== --- python/branches/release31-maint/Python/bltinmodule.c (original) +++ python/branches/release31-maint/Python/bltinmodule.c Sat Dec 19 22:20:55 2009 @@ -804,7 +804,7 @@ PyDoc_STRVAR(exec_doc, "exec(object[, globals[, locals]])\n\ \n\ -Read and execute code from a object, which can be a string or a code\n\ +Read and execute code from an object, which can be a string or a code\n\ object.\n\ The globals and locals are dictionaries, defaulting to the current\n\ globals and locals. If only globals is given, locals defaults to it."); From python-checkins at python.org Sat Dec 19 23:41:49 2009 From: python-checkins at python.org (ezio.melotti) Date: Sat, 19 Dec 2009 22:41:49 -0000 Subject: [Python-checkins] r76904 - in python/trunk/Doc: c-api/init.rst distutils/setupscript.rst faq/extending.rst faq/library.rst faq/windows.rst library/collections.rst library/doctest.rst library/hmac.rst library/hotshot.rst library/logging.rst library/multiprocessing.rst library/pdb.rst library/smtplib.rst library/socket.rst library/stdtypes.rst library/turtle.rst library/unittest.rst license.rst tutorial/stdlib.rst tutorial/stdlib2.rst using/unix.rst using/windows.rst Message-ID: Author: ezio.melotti Date: Sat Dec 19 23:41:49 2009 New Revision: 76904 Log: #7388: "python".capitalize() in the Doc Modified: python/trunk/Doc/c-api/init.rst python/trunk/Doc/distutils/setupscript.rst python/trunk/Doc/faq/extending.rst python/trunk/Doc/faq/library.rst python/trunk/Doc/faq/windows.rst python/trunk/Doc/library/collections.rst python/trunk/Doc/library/doctest.rst python/trunk/Doc/library/hmac.rst python/trunk/Doc/library/hotshot.rst python/trunk/Doc/library/logging.rst python/trunk/Doc/library/multiprocessing.rst python/trunk/Doc/library/pdb.rst python/trunk/Doc/library/smtplib.rst python/trunk/Doc/library/socket.rst python/trunk/Doc/library/stdtypes.rst python/trunk/Doc/library/turtle.rst python/trunk/Doc/library/unittest.rst python/trunk/Doc/license.rst python/trunk/Doc/tutorial/stdlib.rst python/trunk/Doc/tutorial/stdlib2.rst python/trunk/Doc/using/unix.rst python/trunk/Doc/using/windows.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 Dec 19 23:41:49 2009 @@ -821,7 +821,7 @@ .. index:: single: setcheckinterval() (in module sys) Every check interval, when the global interpreter lock is released and -reacquired, python will also call any such provided functions. This can be used +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 @@ -839,7 +839,7 @@ 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. + 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 Modified: python/trunk/Doc/distutils/setupscript.rst ============================================================================== --- python/trunk/Doc/distutils/setupscript.rst (original) +++ python/trunk/Doc/distutils/setupscript.rst Sat Dec 19 23:41:49 2009 @@ -649,7 +649,7 @@ 1.0.1a2 the second alpha release of the first patch version of 1.0 -:option:`classifiers` are specified in a python list:: +:option:`classifiers` are specified in a Python list:: setup(..., classifiers=[ Modified: python/trunk/Doc/faq/extending.rst ============================================================================== --- python/trunk/Doc/faq/extending.rst (original) +++ python/trunk/Doc/faq/extending.rst Sat Dec 19 23:41:49 2009 @@ -432,7 +432,7 @@ -------------------------------------------------------------------- To dynamically load g++ extension modules, you must recompile Python, relink it -using g++ (change LINKCC in the python Modules Makefile), and link your +using g++ (change LINKCC in the Python Modules Makefile), and link your extension module using g++ (e.g., ``g++ -shared -o mymodule.so mymodule.o``). Modified: python/trunk/Doc/faq/library.rst ============================================================================== --- python/trunk/Doc/faq/library.rst (original) +++ python/trunk/Doc/faq/library.rst Sat Dec 19 23:41:49 2009 @@ -61,7 +61,7 @@ If you would like the script to be independent of where the Python interpreter lives, you can use the "env" program. Almost all Unix variants support the -following, assuming the python interpreter is in a directory on the user's +following, assuming the Python interpreter is in a directory on the user's $PATH:: #!/usr/bin/env python Modified: python/trunk/Doc/faq/windows.rst ============================================================================== --- python/trunk/Doc/faq/windows.rst (original) +++ python/trunk/Doc/faq/windows.rst Sat Dec 19 23:41:49 2009 @@ -204,7 +204,7 @@ for developing code by experiment. -How do I make python scripts executable? +How do I make Python scripts executable? ---------------------------------------- On Windows 2000, the standard Python installer already associates the .py Modified: python/trunk/Doc/library/collections.rst ============================================================================== --- python/trunk/Doc/library/collections.rst (original) +++ python/trunk/Doc/library/collections.rst Sat Dec 19 23:41:49 2009 @@ -491,7 +491,7 @@ yield s / float(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 +deletion. For example, a pure Python implementation of ``del d[n]`` relies on the :meth:`rotate` method to position elements to be popped:: def delete_nth(d, n): Modified: python/trunk/Doc/library/doctest.rst ============================================================================== --- python/trunk/Doc/library/doctest.rst (original) +++ python/trunk/Doc/library/doctest.rst Sat Dec 19 23:41:49 2009 @@ -1132,7 +1132,7 @@ The advanced API revolves around two container classes, which are used to store the interactive examples extracted from doctest cases: -* :class:`Example`: A single python :term:`statement`, paired with its expected +* :class:`Example`: A single Python :term:`statement`, paired with its expected output. * :class:`DocTest`: A collection of :class:`Example`\ s, typically extracted Modified: python/trunk/Doc/library/hmac.rst ============================================================================== --- python/trunk/Doc/library/hmac.rst (original) +++ python/trunk/Doc/library/hmac.rst Sat Dec 19 23:41:49 2009 @@ -57,5 +57,5 @@ .. seealso:: Module :mod:`hashlib` - The python module providing secure hash functions. + The Python module providing secure hash functions. Modified: python/trunk/Doc/library/hotshot.rst ============================================================================== --- python/trunk/Doc/library/hotshot.rst (original) +++ python/trunk/Doc/library/hotshot.rst Sat Dec 19 23:41:49 2009 @@ -127,7 +127,7 @@ Example Usage ------------- -Note that this example runs the python "benchmark" pystones. It can take some +Note that this example runs the Python "benchmark" pystones. It can take some time to run, and will produce large output files. :: >>> import hotshot, hotshot.stats, test.pystone Modified: python/trunk/Doc/library/logging.rst ============================================================================== --- python/trunk/Doc/library/logging.rst (original) +++ python/trunk/Doc/library/logging.rst Sat Dec 19 23:41:49 2009 @@ -2256,7 +2256,7 @@ of the :class:`LogRecord` attributes - such as the default value mentioned above making use of the fact that the user's message and arguments are pre-formatted into a :class:`LogRecord`'s *message* attribute. This format string contains -standard python %-style mapping keys. See section :ref:`string-formatting` +standard Python %-style mapping keys. See section :ref:`string-formatting` for more information on string formatting. Currently, the useful mapping keys in a :class:`LogRecord` are: Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Sat Dec 19 23:41:49 2009 @@ -688,7 +688,7 @@ .. function:: set_executable() - Sets the path of the python interpreter to use when starting a child process. + Sets the path of the Python interpreter to use when starting a child process. (By default :data:`sys.executable` is used). Embedders will probably need to do some thing like :: Modified: python/trunk/Doc/library/pdb.rst ============================================================================== --- python/trunk/Doc/library/pdb.rst (original) +++ python/trunk/Doc/library/pdb.rst Sat Dec 19 23:41:49 2009 @@ -382,7 +382,7 @@ (Pdb) run [*args* ...] - Restart the debugged python program. If an argument is supplied, it is split + Restart the debugged Python program. If an argument is supplied, it is split with "shlex" and the result is used as the new sys.argv. History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run". Modified: python/trunk/Doc/library/smtplib.rst ============================================================================== --- python/trunk/Doc/library/smtplib.rst (original) +++ python/trunk/Doc/library/smtplib.rst Sat Dec 19 23:41:49 2009 @@ -271,7 +271,7 @@ .. versionchanged:: 2.6 :exc:`RuntimeError` - SSL/TLS support is not available to your python interpreter. + SSL/TLS support is not available to your Python interpreter. .. method:: SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]) Modified: python/trunk/Doc/library/socket.rst ============================================================================== --- python/trunk/Doc/library/socket.rst (original) +++ python/trunk/Doc/library/socket.rst Sat Dec 19 23:41:49 2009 @@ -751,7 +751,7 @@ in general it is recommended to call :meth:`settimeout` before calling :meth:`connect` or pass a timeout parameter to :meth:`create_connection`. The system network stack may return a connection timeout error -of its own regardless of any python socket timeout setting. +of its own regardless of any Python socket timeout setting. .. method:: socket.setsockopt(level, optname, value) Modified: python/trunk/Doc/library/stdtypes.rst ============================================================================== --- python/trunk/Doc/library/stdtypes.rst (original) +++ python/trunk/Doc/library/stdtypes.rst Sat Dec 19 23:41:49 2009 @@ -1397,10 +1397,10 @@ | ``'c'`` | Single character (accepts integer or single | | | | character string). | | +------------+-----------------------------------------------------+-------+ -| ``'r'`` | String (converts any python object using | \(5) | +| ``'r'`` | String (converts any Python object using | \(5) | | | :func:`repr`). | | +------------+-----------------------------------------------------+-------+ -| ``'s'`` | String (converts any python object using | \(6) | +| ``'s'`` | String (converts any Python object using | \(6) | | | :func:`str`). | | +------------+-----------------------------------------------------+-------+ | ``'%'`` | No argument is converted, results in a ``'%'`` | | Modified: python/trunk/Doc/library/turtle.rst ============================================================================== --- python/trunk/Doc/library/turtle.rst (original) +++ python/trunk/Doc/library/turtle.rst Sat Dec 19 23:41:49 2009 @@ -36,7 +36,7 @@ The turtle module provides turtle graphics primitives, in both object-oriented and procedure-oriented ways. Because it uses :mod:`Tkinter` for the underlying -graphics, it needs a version of python installed with Tk support. +graphics, it needs a version of Python installed with Tk support. The object-oriented interface uses essentially two+two classes: Modified: python/trunk/Doc/library/unittest.rst ============================================================================== --- python/trunk/Doc/library/unittest.rst (original) +++ python/trunk/Doc/library/unittest.rst Sat Dec 19 23:41:49 2009 @@ -199,7 +199,7 @@ You can run tests with more detail (higher verbosity) by passing in the -v flag:: - python-m unittest -v test_module + python -m unittest -v test_module For a list of all the command line options:: @@ -1600,7 +1600,7 @@ .. note:: - The default pattern is 'test*.py'. This matches all python files + The default pattern is 'test*.py'. This matches all Python files that start with 'test' but *won't* match any test directories. A pattern like 'test*' will match test packages as well as Modified: python/trunk/Doc/license.rst ============================================================================== --- python/trunk/Doc/license.rst (original) +++ python/trunk/Doc/license.rst Sat Dec 19 23:41:49 2009 @@ -624,7 +624,7 @@ - Use binascii module to do the actual line-by-line conversion between ascii and binary. This results in a 1000-fold speedup. The C version is still 5 times faster, though. - - Arguments more compliant with python standard + - Arguments more compliant with Python standard XML Remote Procedure Calls Modified: python/trunk/Doc/tutorial/stdlib.rst ============================================================================== --- python/trunk/Doc/tutorial/stdlib.rst (original) +++ python/trunk/Doc/tutorial/stdlib.rst Sat Dec 19 23:41:49 2009 @@ -306,7 +306,7 @@ * The :mod:`xml.dom` and :mod:`xml.sax` packages provide robust support for parsing this popular data interchange format. Likewise, the :mod:`csv` module supports direct reads and writes in a common database format. Together, these - modules and packages greatly simplify data interchange between python + modules and packages greatly simplify data interchange between Python applications and other tools. * Internationalization is supported by a number of modules including Modified: python/trunk/Doc/tutorial/stdlib2.rst ============================================================================== --- python/trunk/Doc/tutorial/stdlib2.rst (original) +++ python/trunk/Doc/tutorial/stdlib2.rst Sat Dec 19 23:41:49 2009 @@ -289,7 +289,7 @@ that stores only homogeneous data and stores it more compactly. The following example shows an array of numbers stored as two byte unsigned binary numbers (typecode ``"H"``) rather than the usual 16 bytes per entry for regular lists of -python int objects:: +Python int objects:: >>> from array import array >>> a = array('H', [4000, 10, 700, 22222]) Modified: python/trunk/Doc/using/unix.rst ============================================================================== --- python/trunk/Doc/using/unix.rst (original) +++ python/trunk/Doc/using/unix.rst Sat Dec 19 23:41:49 2009 @@ -131,14 +131,14 @@ some Unices may not have the :program:`env` command, so you may need to hardcode ``/usr/bin/python`` as the interpreter path. -To use shell commands in your python scripts, look at the :mod:`subprocess` module. +To use shell commands in your Python scripts, look at the :mod:`subprocess` module. Editors ======= Vim and Emacs are excellent editors which support Python very well. For more -information on how to code in python in these editors, look at: +information on how to code in Python in these editors, look at: * http://www.vim.org/scripts/script.php?script_id=790 * http://sourceforge.net/projects/python-mode Modified: python/trunk/Doc/using/windows.rst ============================================================================== --- python/trunk/Doc/using/windows.rst (original) +++ python/trunk/Doc/using/windows.rst Sat Dec 19 23:41:49 2009 @@ -71,7 +71,7 @@ `Enthought Python Distribution `_ Popular modules (such as PyWin32) with their respective documentation, tool - suite for building extensible python applications + suite for building extensible Python applications Notice that these packages are likely to install *older* versions of Python. From python-checkins at python.org Sat Dec 19 23:59:01 2009 From: python-checkins at python.org (ezio.melotti) Date: Sat, 19 Dec 2009 22:59:01 -0000 Subject: [Python-checkins] r76905 - in python/branches/release26-maint: Doc/distutils/setupscript.rst Doc/faq/extending.rst Doc/faq/library.rst Doc/faq/windows.rst Doc/library/collections.rst Doc/library/doctest.rst Doc/library/hmac.rst Doc/library/hotshot.rst Doc/library/logging.rst Doc/library/multiprocessing.rst Doc/library/pdb.rst Doc/library/smtplib.rst Doc/library/socket.rst Doc/library/stdtypes.rst Doc/library/turtle.rst Doc/license.rst Doc/tutorial/stdlib.rst Doc/tutorial/stdlib2.rst Doc/using/unix.rst Doc/using/windows.rst Message-ID: Author: ezio.melotti Date: Sat Dec 19 23:59:01 2009 New Revision: 76905 Log: Merged revisions 76904 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76904 | ezio.melotti | 2009-12-20 00:41:49 +0200 (Sun, 20 Dec 2009) | 1 line #7388: "python".capitalize() in the Doc ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/distutils/setupscript.rst python/branches/release26-maint/Doc/faq/extending.rst python/branches/release26-maint/Doc/faq/library.rst python/branches/release26-maint/Doc/faq/windows.rst python/branches/release26-maint/Doc/library/collections.rst python/branches/release26-maint/Doc/library/doctest.rst python/branches/release26-maint/Doc/library/hmac.rst python/branches/release26-maint/Doc/library/hotshot.rst python/branches/release26-maint/Doc/library/logging.rst python/branches/release26-maint/Doc/library/multiprocessing.rst python/branches/release26-maint/Doc/library/pdb.rst python/branches/release26-maint/Doc/library/smtplib.rst python/branches/release26-maint/Doc/library/socket.rst python/branches/release26-maint/Doc/library/stdtypes.rst python/branches/release26-maint/Doc/library/turtle.rst python/branches/release26-maint/Doc/license.rst python/branches/release26-maint/Doc/tutorial/stdlib.rst python/branches/release26-maint/Doc/tutorial/stdlib2.rst python/branches/release26-maint/Doc/using/unix.rst python/branches/release26-maint/Doc/using/windows.rst Modified: python/branches/release26-maint/Doc/distutils/setupscript.rst ============================================================================== --- python/branches/release26-maint/Doc/distutils/setupscript.rst (original) +++ python/branches/release26-maint/Doc/distutils/setupscript.rst Sat Dec 19 23:59:01 2009 @@ -620,7 +620,7 @@ 1.0.1a2 the second alpha release of the first patch version of 1.0 -:option:`classifiers` are specified in a python list:: +:option:`classifiers` are specified in a Python list:: setup(..., classifiers=[ Modified: python/branches/release26-maint/Doc/faq/extending.rst ============================================================================== --- python/branches/release26-maint/Doc/faq/extending.rst (original) +++ python/branches/release26-maint/Doc/faq/extending.rst Sat Dec 19 23:59:01 2009 @@ -432,7 +432,7 @@ -------------------------------------------------------------------- To dynamically load g++ extension modules, you must recompile Python, relink it -using g++ (change LINKCC in the python Modules Makefile), and link your +using g++ (change LINKCC in the Python Modules Makefile), and link your extension module using g++ (e.g., ``g++ -shared -o mymodule.so mymodule.o``). Modified: python/branches/release26-maint/Doc/faq/library.rst ============================================================================== --- python/branches/release26-maint/Doc/faq/library.rst (original) +++ python/branches/release26-maint/Doc/faq/library.rst Sat Dec 19 23:59:01 2009 @@ -61,7 +61,7 @@ If you would like the script to be independent of where the Python interpreter lives, you can use the "env" program. Almost all Unix variants support the -following, assuming the python interpreter is in a directory on the user's +following, assuming the Python interpreter is in a directory on the user's $PATH:: #!/usr/bin/env python Modified: python/branches/release26-maint/Doc/faq/windows.rst ============================================================================== --- python/branches/release26-maint/Doc/faq/windows.rst (original) +++ python/branches/release26-maint/Doc/faq/windows.rst Sat Dec 19 23:59:01 2009 @@ -204,7 +204,7 @@ for developing code by experiment. -How do I make python scripts executable? +How do I make Python scripts executable? ---------------------------------------- On Windows 2000, the standard Python installer already associates the .py Modified: python/branches/release26-maint/Doc/library/collections.rst ============================================================================== --- python/branches/release26-maint/Doc/library/collections.rst (original) +++ python/branches/release26-maint/Doc/library/collections.rst Sat Dec 19 23:59:01 2009 @@ -334,7 +334,7 @@ yield s / float(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 +deletion. For example, a pure Python implementation of ``del d[n]`` relies on the :meth:`rotate` method to position elements to be popped:: def delete_nth(d, n): 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 Sat Dec 19 23:59:01 2009 @@ -1132,7 +1132,7 @@ The advanced API revolves around two container classes, which are used to store the interactive examples extracted from doctest cases: -* :class:`Example`: A single python :term:`statement`, paired with its expected +* :class:`Example`: A single Python :term:`statement`, paired with its expected output. * :class:`DocTest`: A collection of :class:`Example`\ s, typically extracted Modified: python/branches/release26-maint/Doc/library/hmac.rst ============================================================================== --- python/branches/release26-maint/Doc/library/hmac.rst (original) +++ python/branches/release26-maint/Doc/library/hmac.rst Sat Dec 19 23:59:01 2009 @@ -57,5 +57,5 @@ .. seealso:: Module :mod:`hashlib` - The python module providing secure hash functions. + The Python module providing secure hash 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 Sat Dec 19 23:59:01 2009 @@ -127,7 +127,7 @@ Example Usage ------------- -Note that this example runs the python "benchmark" pystones. It can take some +Note that this example runs the Python "benchmark" pystones. It can take some time to run, and will produce large output files. :: >>> import hotshot, hotshot.stats, test.pystone Modified: python/branches/release26-maint/Doc/library/logging.rst ============================================================================== --- python/branches/release26-maint/Doc/library/logging.rst (original) +++ python/branches/release26-maint/Doc/library/logging.rst Sat Dec 19 23:59:01 2009 @@ -2213,7 +2213,7 @@ of the :class:`LogRecord` attributes - such as the default value mentioned above making use of the fact that the user's message and arguments are pre-formatted into a :class:`LogRecord`'s *message* attribute. This format string contains -standard python %-style mapping keys. See section :ref:`string-formatting` +standard Python %-style mapping keys. See section :ref:`string-formatting` for more information on string formatting. Currently, the useful mapping keys in a :class:`LogRecord` are: 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 Sat Dec 19 23:59:01 2009 @@ -688,7 +688,7 @@ .. function:: set_executable() - Sets the path of the python interpreter to use when starting a child process. + Sets the path of the Python interpreter to use when starting a child process. (By default :data:`sys.executable` is used). Embedders will probably need to do some thing like :: 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 Sat Dec 19 23:59:01 2009 @@ -352,7 +352,7 @@ (Pdb) run [*args* ...] - Restart the debugged python program. If an argument is supplied, it is split + Restart the debugged Python program. If an argument is supplied, it is split with "shlex" and the result is used as the new sys.argv. History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run". Modified: python/branches/release26-maint/Doc/library/smtplib.rst ============================================================================== --- python/branches/release26-maint/Doc/library/smtplib.rst (original) +++ python/branches/release26-maint/Doc/library/smtplib.rst Sat Dec 19 23:59:01 2009 @@ -271,7 +271,7 @@ .. versionchanged:: 2.6 :exc:`RuntimeError` - SSL/TLS support is not available to your python interpreter. + SSL/TLS support is not available to your Python interpreter. .. method:: SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]) Modified: python/branches/release26-maint/Doc/library/socket.rst ============================================================================== --- python/branches/release26-maint/Doc/library/socket.rst (original) +++ python/branches/release26-maint/Doc/library/socket.rst Sat Dec 19 23:59:01 2009 @@ -756,7 +756,7 @@ in general it is recommended to call :meth:`settimeout` before calling :meth:`connect` or pass a timeout parameter to :meth:`create_connection`. The system network stack may return a connection timeout error -of its own regardless of any python socket timeout setting. +of its own regardless of any Python socket timeout setting. .. method:: socket.setsockopt(level, optname, value) 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 Sat Dec 19 23:59:01 2009 @@ -1362,10 +1362,10 @@ | ``'c'`` | Single character (accepts integer or single | | | | character string). | | +------------+-----------------------------------------------------+-------+ -| ``'r'`` | String (converts any python object using | \(5) | +| ``'r'`` | String (converts any Python object using | \(5) | | | :func:`repr`). | | +------------+-----------------------------------------------------+-------+ -| ``'s'`` | String (converts any python object using | \(6) | +| ``'s'`` | String (converts any Python object using | \(6) | | | :func:`str`). | | +------------+-----------------------------------------------------+-------+ | ``'%'`` | No argument is converted, results in a ``'%'`` | | 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 Sat Dec 19 23:59:01 2009 @@ -36,7 +36,7 @@ The turtle module provides turtle graphics primitives, in both object-oriented and procedure-oriented ways. Because it uses :mod:`Tkinter` for the underlying -graphics, it needs a version of python installed with Tk support. +graphics, it needs a version of Python installed with Tk support. The object-oriented interface uses essentially two+two classes: Modified: python/branches/release26-maint/Doc/license.rst ============================================================================== --- python/branches/release26-maint/Doc/license.rst (original) +++ python/branches/release26-maint/Doc/license.rst Sat Dec 19 23:59:01 2009 @@ -624,7 +624,7 @@ - Use binascii module to do the actual line-by-line conversion between ascii and binary. This results in a 1000-fold speedup. The C version is still 5 times faster, though. - - Arguments more compliant with python standard + - Arguments more compliant with Python standard XML Remote Procedure Calls Modified: python/branches/release26-maint/Doc/tutorial/stdlib.rst ============================================================================== --- python/branches/release26-maint/Doc/tutorial/stdlib.rst (original) +++ python/branches/release26-maint/Doc/tutorial/stdlib.rst Sat Dec 19 23:59:01 2009 @@ -306,7 +306,7 @@ * The :mod:`xml.dom` and :mod:`xml.sax` packages provide robust support for parsing this popular data interchange format. Likewise, the :mod:`csv` module supports direct reads and writes in a common database format. Together, these - modules and packages greatly simplify data interchange between python + modules and packages greatly simplify data interchange between Python applications and other tools. * Internationalization is supported by a number of modules including Modified: python/branches/release26-maint/Doc/tutorial/stdlib2.rst ============================================================================== --- python/branches/release26-maint/Doc/tutorial/stdlib2.rst (original) +++ python/branches/release26-maint/Doc/tutorial/stdlib2.rst Sat Dec 19 23:59:01 2009 @@ -289,7 +289,7 @@ that stores only homogeneous data and stores it more compactly. The following example shows an array of numbers stored as two byte unsigned binary numbers (typecode ``"H"``) rather than the usual 16 bytes per entry for regular lists of -python int objects:: +Python int objects:: >>> from array import array >>> a = array('H', [4000, 10, 700, 22222]) Modified: python/branches/release26-maint/Doc/using/unix.rst ============================================================================== --- python/branches/release26-maint/Doc/using/unix.rst (original) +++ python/branches/release26-maint/Doc/using/unix.rst Sat Dec 19 23:59:01 2009 @@ -131,14 +131,14 @@ some Unices may not have the :program:`env` command, so you may need to hardcode ``/usr/bin/python`` as the interpreter path. -To use shell commands in your python scripts, look at the :mod:`subprocess` module. +To use shell commands in your Python scripts, look at the :mod:`subprocess` module. Editors ======= Vim and Emacs are excellent editors which support Python very well. For more -information on how to code in python in these editors, look at: +information on how to code in Python in these editors, look at: * http://www.vim.org/scripts/script.php?script_id=790 * http://sourceforge.net/projects/python-mode Modified: python/branches/release26-maint/Doc/using/windows.rst ============================================================================== --- python/branches/release26-maint/Doc/using/windows.rst (original) +++ python/branches/release26-maint/Doc/using/windows.rst Sat Dec 19 23:59:01 2009 @@ -71,7 +71,7 @@ `Enthought Python Distribution `_ Popular modules (such as PyWin32) with their respective documentation, tool - suite for building extensible python applications + suite for building extensible Python applications Notice that these packages are likely to install *older* versions of Python. From python-checkins at python.org Sun Dec 20 00:26:38 2009 From: python-checkins at python.org (ezio.melotti) Date: Sat, 19 Dec 2009 23:26:38 -0000 Subject: [Python-checkins] r76906 - in python/branches/py3k: Doc/c-api/init.rst Doc/distutils/setupscript.rst Doc/faq/extending.rst Doc/faq/library.rst Doc/faq/windows.rst Doc/library/collections.rst Doc/library/doctest.rst Doc/library/hmac.rst Doc/library/logging.rst Doc/library/multiprocessing.rst Doc/library/pdb.rst Doc/library/random.rst Doc/library/smtplib.rst Doc/library/socket.rst Doc/library/stdtypes.rst Doc/library/turtle.rst Doc/library/unittest.rst Doc/license.rst Doc/tutorial/stdlib.rst Doc/tutorial/stdlib2.rst Doc/using/unix.rst Doc/using/windows.rst Message-ID: Author: ezio.melotti Date: Sun Dec 20 00:26:38 2009 New Revision: 76906 Log: Merged revisions 76904 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76904 | ezio.melotti | 2009-12-20 00:41:49 +0200 (Sun, 20 Dec 2009) | 1 line #7388: "python".capitalize() in the Doc ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/init.rst python/branches/py3k/Doc/distutils/setupscript.rst python/branches/py3k/Doc/faq/extending.rst python/branches/py3k/Doc/faq/library.rst python/branches/py3k/Doc/faq/windows.rst python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/doctest.rst python/branches/py3k/Doc/library/hmac.rst python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Doc/library/multiprocessing.rst python/branches/py3k/Doc/library/pdb.rst python/branches/py3k/Doc/library/random.rst python/branches/py3k/Doc/library/smtplib.rst python/branches/py3k/Doc/library/socket.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/library/turtle.rst python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Doc/license.rst python/branches/py3k/Doc/tutorial/stdlib.rst python/branches/py3k/Doc/tutorial/stdlib2.rst python/branches/py3k/Doc/using/unix.rst python/branches/py3k/Doc/using/windows.rst Modified: python/branches/py3k/Doc/c-api/init.rst ============================================================================== --- python/branches/py3k/Doc/c-api/init.rst (original) +++ python/branches/py3k/Doc/c-api/init.rst Sun Dec 20 00:26:38 2009 @@ -808,7 +808,7 @@ .. index:: single: setcheckinterval() (in module sys) Every check interval, when the global interpreter lock is released and -reacquired, python will also call any such provided functions. This can be used +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 @@ -826,7 +826,7 @@ 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. + 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 Modified: python/branches/py3k/Doc/distutils/setupscript.rst ============================================================================== --- python/branches/py3k/Doc/distutils/setupscript.rst (original) +++ python/branches/py3k/Doc/distutils/setupscript.rst Sun Dec 20 00:26:38 2009 @@ -646,7 +646,7 @@ 1.0.1a2 the second alpha release of the first patch version of 1.0 -:option:`classifiers` are specified in a python list:: +:option:`classifiers` are specified in a Python list:: setup(..., classifiers=[ Modified: python/branches/py3k/Doc/faq/extending.rst ============================================================================== --- python/branches/py3k/Doc/faq/extending.rst (original) +++ python/branches/py3k/Doc/faq/extending.rst Sun Dec 20 00:26:38 2009 @@ -434,7 +434,7 @@ -------------------------------------------------------------------- To dynamically load g++ extension modules, you must recompile Python, relink it -using g++ (change LINKCC in the python Modules Makefile), and link your +using g++ (change LINKCC in the Python Modules Makefile), and link your extension module using g++ (e.g., ``g++ -shared -o mymodule.so mymodule.o``). Modified: python/branches/py3k/Doc/faq/library.rst ============================================================================== --- python/branches/py3k/Doc/faq/library.rst (original) +++ python/branches/py3k/Doc/faq/library.rst Sun Dec 20 00:26:38 2009 @@ -61,7 +61,7 @@ If you would like the script to be independent of where the Python interpreter lives, you can use the "env" program. Almost all Unix variants support the -following, assuming the python interpreter is in a directory on the user's +following, assuming the Python interpreter is in a directory on the user's $PATH:: #!/usr/bin/env python Modified: python/branches/py3k/Doc/faq/windows.rst ============================================================================== --- python/branches/py3k/Doc/faq/windows.rst (original) +++ python/branches/py3k/Doc/faq/windows.rst Sun Dec 20 00:26:38 2009 @@ -208,7 +208,7 @@ for developing code by experiment. -How do I make python scripts executable? +How do I make Python scripts executable? ---------------------------------------- On Windows 2000, the standard Python installer already associates the .py Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Sun Dec 20 00:26:38 2009 @@ -469,7 +469,7 @@ 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 +deletion. For example, a pure Python implementation of ``del d[n]`` relies on the :meth:`rotate` method to position elements to be popped:: def delete_nth(d, n): Modified: python/branches/py3k/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k/Doc/library/doctest.rst (original) +++ python/branches/py3k/Doc/library/doctest.rst Sun Dec 20 00:26:38 2009 @@ -1059,7 +1059,7 @@ The advanced API revolves around two container classes, which are used to store the interactive examples extracted from doctest cases: -* :class:`Example`: A single python :term:`statement`, paired with its expected +* :class:`Example`: A single Python :term:`statement`, paired with its expected output. * :class:`DocTest`: A collection of :class:`Example`\ s, typically extracted Modified: python/branches/py3k/Doc/library/hmac.rst ============================================================================== --- python/branches/py3k/Doc/library/hmac.rst (original) +++ python/branches/py3k/Doc/library/hmac.rst Sun Dec 20 00:26:38 2009 @@ -54,5 +54,5 @@ .. seealso:: Module :mod:`hashlib` - The python module providing secure hash functions. + The Python module providing secure hash functions. Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Sun Dec 20 00:26:38 2009 @@ -2196,7 +2196,7 @@ of the :class:`LogRecord` attributes - such as the default value mentioned above making use of the fact that the user's message and arguments are pre-formatted into a :class:`LogRecord`'s *message* attribute. This format string contains -standard python %-style mapping keys. See section :ref:`old-string-formatting` +standard Python %-style mapping keys. See section :ref:`old-string-formatting` for more information on string formatting. Currently, the useful mapping keys in a :class:`LogRecord` are: Modified: python/branches/py3k/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k/Doc/library/multiprocessing.rst Sun Dec 20 00:26:38 2009 @@ -686,7 +686,7 @@ .. function:: set_executable() - Sets the path of the python interpreter to use when starting a child process. + Sets the path of the Python interpreter to use when starting a child process. (By default :data:`sys.executable` is used). Embedders will probably need to do some thing like :: Modified: python/branches/py3k/Doc/library/pdb.rst ============================================================================== --- python/branches/py3k/Doc/library/pdb.rst (original) +++ python/branches/py3k/Doc/library/pdb.rst Sun Dec 20 00:26:38 2009 @@ -369,7 +369,7 @@ (Pdb) run [*args* ...] - Restart the debugged python program. If an argument is supplied, it is split + Restart the debugged Python program. If an argument is supplied, it is split with "shlex" and the result is used as the new sys.argv. History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run". Modified: python/branches/py3k/Doc/library/random.rst ============================================================================== --- python/branches/py3k/Doc/library/random.rst (original) +++ python/branches/py3k/Doc/library/random.rst Sun Dec 20 00:26:38 2009 @@ -67,7 +67,7 @@ .. function:: getrandbits(k) - Returns a python integer with *k* random bits. This method is supplied with + Returns a Python integer with *k* random bits. This method is supplied with the MersenneTwister generator and some other generators may also provide it as an optional part of the API. When available, :meth:`getrandbits` enables :meth:`randrange` to handle arbitrarily large ranges. Modified: python/branches/py3k/Doc/library/smtplib.rst ============================================================================== --- python/branches/py3k/Doc/library/smtplib.rst (original) +++ python/branches/py3k/Doc/library/smtplib.rst Sun Dec 20 00:26:38 2009 @@ -257,7 +257,7 @@ The server does not support the STARTTLS extension. :exc:`RuntimeError` - SSL/TLS support is not available to your python interpreter. + SSL/TLS support is not available to your Python interpreter. .. method:: SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[]) Modified: python/branches/py3k/Doc/library/socket.rst ============================================================================== --- python/branches/py3k/Doc/library/socket.rst (original) +++ python/branches/py3k/Doc/library/socket.rst Sun Dec 20 00:26:38 2009 @@ -696,7 +696,7 @@ in general it is recommended to call :meth:`settimeout` before calling :meth:`connect` or pass a timeout parameter to :meth:`create_connection`. The system network stack may return a connection timeout error -of its own regardless of any python socket timeout setting. +of its own regardless of any Python socket timeout setting. .. method:: socket.setsockopt(level, optname, value) Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Sun Dec 20 00:26:38 2009 @@ -1311,10 +1311,10 @@ | ``'c'`` | Single character (accepts integer or single | | | | character string). | | +------------+-----------------------------------------------------+-------+ -| ``'r'`` | String (converts any python object using | \(5) | +| ``'r'`` | String (converts any Python object using | \(5) | | | :func:`repr`). | | +------------+-----------------------------------------------------+-------+ -| ``'s'`` | String (converts any python object using | | +| ``'s'`` | String (converts any Python object using | | | | :func:`str`). | | +------------+-----------------------------------------------------+-------+ | ``'%'`` | No argument is converted, results in a ``'%'`` | | Modified: python/branches/py3k/Doc/library/turtle.rst ============================================================================== --- python/branches/py3k/Doc/library/turtle.rst (original) +++ python/branches/py3k/Doc/library/turtle.rst Sun Dec 20 00:26:38 2009 @@ -36,7 +36,7 @@ The turtle module provides turtle graphics primitives, in both object-oriented and procedure-oriented ways. Because it uses :mod:`Tkinter` for the underlying -graphics, it needs a version of python installed with Tk support. +graphics, it needs a version of Python installed with Tk support. The object-oriented interface uses essentially two+two classes: Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Sun Dec 20 00:26:38 2009 @@ -1591,7 +1591,7 @@ .. note:: - The default pattern is 'test*.py'. This matches all python files + The default pattern is 'test*.py'. This matches all Python files that start with 'test' but *won't* match any test directories. A pattern like 'test*' will match test packages as well as Modified: python/branches/py3k/Doc/license.rst ============================================================================== --- python/branches/py3k/Doc/license.rst (original) +++ python/branches/py3k/Doc/license.rst Sun Dec 20 00:26:38 2009 @@ -578,7 +578,7 @@ - Use binascii module to do the actual line-by-line conversion between ascii and binary. This results in a 1000-fold speedup. The C version is still 5 times faster, though. - - Arguments more compliant with python standard + - Arguments more compliant with Python standard XML Remote Procedure Calls Modified: python/branches/py3k/Doc/tutorial/stdlib.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/stdlib.rst (original) +++ python/branches/py3k/Doc/tutorial/stdlib.rst Sun Dec 20 00:26:38 2009 @@ -308,7 +308,7 @@ * The :mod:`xml.dom` and :mod:`xml.sax` packages provide robust support for parsing this popular data interchange format. Likewise, the :mod:`csv` module supports direct reads and writes in a common database format. Together, these - modules and packages greatly simplify data interchange between python + modules and packages greatly simplify data interchange between Python applications and other tools. * Internationalization is supported by a number of modules including Modified: python/branches/py3k/Doc/tutorial/stdlib2.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/stdlib2.rst (original) +++ python/branches/py3k/Doc/tutorial/stdlib2.rst Sun Dec 20 00:26:38 2009 @@ -289,7 +289,7 @@ that stores only homogeneous data and stores it more compactly. The following example shows an array of numbers stored as two byte unsigned binary numbers (typecode ``"H"``) rather than the usual 16 bytes per entry for regular lists of -python int objects:: +Python int objects:: >>> from array import array >>> a = array('H', [4000, 10, 700, 22222]) Modified: python/branches/py3k/Doc/using/unix.rst ============================================================================== --- python/branches/py3k/Doc/using/unix.rst (original) +++ python/branches/py3k/Doc/using/unix.rst Sun Dec 20 00:26:38 2009 @@ -131,14 +131,14 @@ some Unices may not have the :program:`env` command, so you may need to hardcode ``/usr/bin/python`` as the interpreter path. -To use shell commands in your python scripts, look at the :mod:`subprocess` module. +To use shell commands in your Python scripts, look at the :mod:`subprocess` module. Editors ======= Vim and Emacs are excellent editors which support Python very well. For more -information on how to code in python in these editors, look at: +information on how to code in Python in these editors, look at: * http://www.vim.org/scripts/script.php?script_id=790 * http://sourceforge.net/projects/python-mode Modified: python/branches/py3k/Doc/using/windows.rst ============================================================================== --- python/branches/py3k/Doc/using/windows.rst (original) +++ python/branches/py3k/Doc/using/windows.rst Sun Dec 20 00:26:38 2009 @@ -69,7 +69,7 @@ `Enthought Python Distribution `_ Popular modules (such as PyWin32) with their respective documentation, tool - suite for building extensible python applications + suite for building extensible Python applications Notice that these packages are likely to install *older* versions of Python. From python-checkins at python.org Sun Dec 20 00:33:46 2009 From: python-checkins at python.org (ezio.melotti) Date: Sat, 19 Dec 2009 23:33:46 -0000 Subject: [Python-checkins] r76907 - in python/branches/release31-maint: Doc/c-api/init.rst Doc/distutils/setupscript.rst Doc/faq/extending.rst Doc/faq/library.rst Doc/faq/windows.rst Doc/library/collections.rst Doc/library/doctest.rst Doc/library/hmac.rst Doc/library/logging.rst Doc/library/multiprocessing.rst Doc/library/pdb.rst Doc/library/random.rst Doc/library/smtplib.rst Doc/library/socket.rst Doc/library/stdtypes.rst Doc/library/turtle.rst Doc/license.rst Doc/tutorial/stdlib.rst Doc/tutorial/stdlib2.rst Doc/using/unix.rst Doc/using/windows.rst Message-ID: Author: ezio.melotti Date: Sun Dec 20 00:33:46 2009 New Revision: 76907 Log: Merged revisions 76906 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76906 | ezio.melotti | 2009-12-20 01:26:38 +0200 (Sun, 20 Dec 2009) | 9 lines Merged revisions 76904 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76904 | ezio.melotti | 2009-12-20 00:41:49 +0200 (Sun, 20 Dec 2009) | 1 line #7388: "python".capitalize() in the Doc ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/c-api/init.rst python/branches/release31-maint/Doc/distutils/setupscript.rst python/branches/release31-maint/Doc/faq/extending.rst python/branches/release31-maint/Doc/faq/library.rst python/branches/release31-maint/Doc/faq/windows.rst python/branches/release31-maint/Doc/library/collections.rst python/branches/release31-maint/Doc/library/doctest.rst python/branches/release31-maint/Doc/library/hmac.rst python/branches/release31-maint/Doc/library/logging.rst python/branches/release31-maint/Doc/library/multiprocessing.rst python/branches/release31-maint/Doc/library/pdb.rst python/branches/release31-maint/Doc/library/random.rst python/branches/release31-maint/Doc/library/smtplib.rst python/branches/release31-maint/Doc/library/socket.rst python/branches/release31-maint/Doc/library/stdtypes.rst python/branches/release31-maint/Doc/library/turtle.rst python/branches/release31-maint/Doc/license.rst python/branches/release31-maint/Doc/tutorial/stdlib.rst python/branches/release31-maint/Doc/tutorial/stdlib2.rst python/branches/release31-maint/Doc/using/unix.rst python/branches/release31-maint/Doc/using/windows.rst Modified: python/branches/release31-maint/Doc/c-api/init.rst ============================================================================== --- python/branches/release31-maint/Doc/c-api/init.rst (original) +++ python/branches/release31-maint/Doc/c-api/init.rst Sun Dec 20 00:33:46 2009 @@ -815,7 +815,7 @@ .. index:: single: setcheckinterval() (in module sys) Every check interval, when the global interpreter lock is released and -reacquired, python will also call any such provided functions. This can be used +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 @@ -833,7 +833,7 @@ 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. + 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 Modified: python/branches/release31-maint/Doc/distutils/setupscript.rst ============================================================================== --- python/branches/release31-maint/Doc/distutils/setupscript.rst (original) +++ python/branches/release31-maint/Doc/distutils/setupscript.rst Sun Dec 20 00:33:46 2009 @@ -646,7 +646,7 @@ 1.0.1a2 the second alpha release of the first patch version of 1.0 -:option:`classifiers` are specified in a python list:: +:option:`classifiers` are specified in a Python list:: setup(..., classifiers=[ Modified: python/branches/release31-maint/Doc/faq/extending.rst ============================================================================== --- python/branches/release31-maint/Doc/faq/extending.rst (original) +++ python/branches/release31-maint/Doc/faq/extending.rst Sun Dec 20 00:33:46 2009 @@ -432,7 +432,7 @@ -------------------------------------------------------------------- To dynamically load g++ extension modules, you must recompile Python, relink it -using g++ (change LINKCC in the python Modules Makefile), and link your +using g++ (change LINKCC in the Python Modules Makefile), and link your extension module using g++ (e.g., ``g++ -shared -o mymodule.so mymodule.o``). Modified: python/branches/release31-maint/Doc/faq/library.rst ============================================================================== --- python/branches/release31-maint/Doc/faq/library.rst (original) +++ python/branches/release31-maint/Doc/faq/library.rst Sun Dec 20 00:33:46 2009 @@ -61,7 +61,7 @@ If you would like the script to be independent of where the Python interpreter lives, you can use the "env" program. Almost all Unix variants support the -following, assuming the python interpreter is in a directory on the user's +following, assuming the Python interpreter is in a directory on the user's $PATH:: #!/usr/bin/env python Modified: python/branches/release31-maint/Doc/faq/windows.rst ============================================================================== --- python/branches/release31-maint/Doc/faq/windows.rst (original) +++ python/branches/release31-maint/Doc/faq/windows.rst Sun Dec 20 00:33:46 2009 @@ -204,7 +204,7 @@ for developing code by experiment. -How do I make python scripts executable? +How do I make Python scripts executable? ---------------------------------------- On Windows 2000, the standard Python installer already associates the .py Modified: python/branches/release31-maint/Doc/library/collections.rst ============================================================================== --- python/branches/release31-maint/Doc/library/collections.rst (original) +++ python/branches/release31-maint/Doc/library/collections.rst Sun Dec 20 00:33:46 2009 @@ -464,7 +464,7 @@ 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 +deletion. For example, a pure Python implementation of ``del d[n]`` relies on the :meth:`rotate` method to position elements to be popped:: def delete_nth(d, n): Modified: python/branches/release31-maint/Doc/library/doctest.rst ============================================================================== --- python/branches/release31-maint/Doc/library/doctest.rst (original) +++ python/branches/release31-maint/Doc/library/doctest.rst Sun Dec 20 00:33:46 2009 @@ -1059,7 +1059,7 @@ The advanced API revolves around two container classes, which are used to store the interactive examples extracted from doctest cases: -* :class:`Example`: A single python :term:`statement`, paired with its expected +* :class:`Example`: A single Python :term:`statement`, paired with its expected output. * :class:`DocTest`: A collection of :class:`Example`\ s, typically extracted Modified: python/branches/release31-maint/Doc/library/hmac.rst ============================================================================== --- python/branches/release31-maint/Doc/library/hmac.rst (original) +++ python/branches/release31-maint/Doc/library/hmac.rst Sun Dec 20 00:33:46 2009 @@ -54,5 +54,5 @@ .. seealso:: Module :mod:`hashlib` - The python module providing secure hash functions. + The Python module providing secure hash functions. Modified: python/branches/release31-maint/Doc/library/logging.rst ============================================================================== --- python/branches/release31-maint/Doc/library/logging.rst (original) +++ python/branches/release31-maint/Doc/library/logging.rst Sun Dec 20 00:33:46 2009 @@ -2142,7 +2142,7 @@ of the :class:`LogRecord` attributes - such as the default value mentioned above making use of the fact that the user's message and arguments are pre-formatted into a :class:`LogRecord`'s *message* attribute. This format string contains -standard python %-style mapping keys. See section :ref:`old-string-formatting` +standard Python %-style mapping keys. See section :ref:`old-string-formatting` for more information on string formatting. Currently, the useful mapping keys in a :class:`LogRecord` are: Modified: python/branches/release31-maint/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/release31-maint/Doc/library/multiprocessing.rst (original) +++ python/branches/release31-maint/Doc/library/multiprocessing.rst Sun Dec 20 00:33:46 2009 @@ -686,7 +686,7 @@ .. function:: set_executable() - Sets the path of the python interpreter to use when starting a child process. + Sets the path of the Python interpreter to use when starting a child process. (By default :data:`sys.executable` is used). Embedders will probably need to do some thing like :: Modified: python/branches/release31-maint/Doc/library/pdb.rst ============================================================================== --- python/branches/release31-maint/Doc/library/pdb.rst (original) +++ python/branches/release31-maint/Doc/library/pdb.rst Sun Dec 20 00:33:46 2009 @@ -369,7 +369,7 @@ (Pdb) run [*args* ...] - Restart the debugged python program. If an argument is supplied, it is split + Restart the debugged Python program. If an argument is supplied, it is split with "shlex" and the result is used as the new sys.argv. History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run". Modified: python/branches/release31-maint/Doc/library/random.rst ============================================================================== --- python/branches/release31-maint/Doc/library/random.rst (original) +++ python/branches/release31-maint/Doc/library/random.rst Sun Dec 20 00:33:46 2009 @@ -68,7 +68,7 @@ .. function:: getrandbits(k) - Returns a python integer with *k* random bits. This method is supplied with + Returns a Python integer with *k* random bits. This method is supplied with the MersenneTwister generator and some other generators may also provide it as an optional part of the API. When available, :meth:`getrandbits` enables :meth:`randrange` to handle arbitrarily large ranges. Modified: python/branches/release31-maint/Doc/library/smtplib.rst ============================================================================== --- python/branches/release31-maint/Doc/library/smtplib.rst (original) +++ python/branches/release31-maint/Doc/library/smtplib.rst Sun Dec 20 00:33:46 2009 @@ -258,7 +258,7 @@ The server does not support the STARTTLS extension. :exc:`RuntimeError` - SSL/TLS support is not available to your python interpreter. + SSL/TLS support is not available to your Python interpreter. .. method:: SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]) Modified: python/branches/release31-maint/Doc/library/socket.rst ============================================================================== --- python/branches/release31-maint/Doc/library/socket.rst (original) +++ python/branches/release31-maint/Doc/library/socket.rst Sun Dec 20 00:33:46 2009 @@ -697,7 +697,7 @@ in general it is recommended to call :meth:`settimeout` before calling :meth:`connect` or pass a timeout parameter to :meth:`create_connection`. The system network stack may return a connection timeout error -of its own regardless of any python socket timeout setting. +of its own regardless of any Python socket timeout setting. .. method:: socket.setsockopt(level, optname, value) Modified: python/branches/release31-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release31-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release31-maint/Doc/library/stdtypes.rst Sun Dec 20 00:33:46 2009 @@ -1310,10 +1310,10 @@ | ``'c'`` | Single character (accepts integer or single | | | | character string). | | +------------+-----------------------------------------------------+-------+ -| ``'r'`` | String (converts any python object using | \(5) | +| ``'r'`` | String (converts any Python object using | \(5) | | | :func:`repr`). | | +------------+-----------------------------------------------------+-------+ -| ``'s'`` | String (converts any python object using | | +| ``'s'`` | String (converts any Python object using | | | | :func:`str`). | | +------------+-----------------------------------------------------+-------+ | ``'%'`` | No argument is converted, results in a ``'%'`` | | Modified: python/branches/release31-maint/Doc/library/turtle.rst ============================================================================== --- python/branches/release31-maint/Doc/library/turtle.rst (original) +++ python/branches/release31-maint/Doc/library/turtle.rst Sun Dec 20 00:33:46 2009 @@ -36,7 +36,7 @@ The turtle module provides turtle graphics primitives, in both object-oriented and procedure-oriented ways. Because it uses :mod:`Tkinter` for the underlying -graphics, it needs a version of python installed with Tk support. +graphics, it needs a version of Python installed with Tk support. The object-oriented interface uses essentially two+two classes: Modified: python/branches/release31-maint/Doc/license.rst ============================================================================== --- python/branches/release31-maint/Doc/license.rst (original) +++ python/branches/release31-maint/Doc/license.rst Sun Dec 20 00:33:46 2009 @@ -579,7 +579,7 @@ - Use binascii module to do the actual line-by-line conversion between ascii and binary. This results in a 1000-fold speedup. The C version is still 5 times faster, though. - - Arguments more compliant with python standard + - Arguments more compliant with Python standard XML Remote Procedure Calls Modified: python/branches/release31-maint/Doc/tutorial/stdlib.rst ============================================================================== --- python/branches/release31-maint/Doc/tutorial/stdlib.rst (original) +++ python/branches/release31-maint/Doc/tutorial/stdlib.rst Sun Dec 20 00:33:46 2009 @@ -308,7 +308,7 @@ * The :mod:`xml.dom` and :mod:`xml.sax` packages provide robust support for parsing this popular data interchange format. Likewise, the :mod:`csv` module supports direct reads and writes in a common database format. Together, these - modules and packages greatly simplify data interchange between python + modules and packages greatly simplify data interchange between Python applications and other tools. * Internationalization is supported by a number of modules including Modified: python/branches/release31-maint/Doc/tutorial/stdlib2.rst ============================================================================== --- python/branches/release31-maint/Doc/tutorial/stdlib2.rst (original) +++ python/branches/release31-maint/Doc/tutorial/stdlib2.rst Sun Dec 20 00:33:46 2009 @@ -289,7 +289,7 @@ that stores only homogeneous data and stores it more compactly. The following example shows an array of numbers stored as two byte unsigned binary numbers (typecode ``"H"``) rather than the usual 16 bytes per entry for regular lists of -python int objects:: +Python int objects:: >>> from array import array >>> a = array('H', [4000, 10, 700, 22222]) Modified: python/branches/release31-maint/Doc/using/unix.rst ============================================================================== --- python/branches/release31-maint/Doc/using/unix.rst (original) +++ python/branches/release31-maint/Doc/using/unix.rst Sun Dec 20 00:33:46 2009 @@ -131,14 +131,14 @@ some Unices may not have the :program:`env` command, so you may need to hardcode ``/usr/bin/python`` as the interpreter path. -To use shell commands in your python scripts, look at the :mod:`subprocess` module. +To use shell commands in your Python scripts, look at the :mod:`subprocess` module. Editors ======= Vim and Emacs are excellent editors which support Python very well. For more -information on how to code in python in these editors, look at: +information on how to code in Python in these editors, look at: * http://www.vim.org/scripts/script.php?script_id=790 * http://sourceforge.net/projects/python-mode Modified: python/branches/release31-maint/Doc/using/windows.rst ============================================================================== --- python/branches/release31-maint/Doc/using/windows.rst (original) +++ python/branches/release31-maint/Doc/using/windows.rst Sun Dec 20 00:33:46 2009 @@ -69,7 +69,7 @@ `Enthought Python Distribution `_ Popular modules (such as PyWin32) with their respective documentation, tool - suite for building extensible python applications + suite for building extensible Python applications Notice that these packages are likely to install *older* versions of Python. From ncoghlan at gmail.com Sun Dec 20 00:46:23 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sun, 20 Dec 2009 09:46:23 +1000 Subject: [Python-checkins] r76892 - python/trunk/Doc/library/stdtypes.rst In-Reply-To: <4b2d196c.0467f10a.549d.5580SMTPIN_ADDED@mx.google.com> References: <4b2d196c.0467f10a.549d.5580SMTPIN_ADDED@mx.google.com> Message-ID: <4B2D65CF.8040707@gmail.com> georg.brandl wrote: > Modified: python/trunk/Doc/library/stdtypes.rst > ============================================================================== > --- python/trunk/Doc/library/stdtypes.rst (original) > +++ python/trunk/Doc/library/stdtypes.rst Sat Dec 19 19:20:18 2009 > @@ -2828,8 +2828,7 @@ > > .. attribute:: class.__bases__ > > - The tuple of base classes of a class object. If there are no base classes, this > - will be an empty tuple. > + The tuple of base classes of a class object. Hmm, I never found that redundant - it makes it clear the terminal value is () rather than None. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From solipsis at pitrou.net Sun Dec 20 00:50:01 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 20 Dec 2009 00:50:01 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76902): sum=0 Message-ID: <20091219235001.903F5178A9@ns6635.ovh.net> py3k results for svn r76902 (hg cset 90d1859c4d76) -------------------------------------------------- test_os leaked [0, 23, -23] references, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogHCi8M_', '-x', 'test_httpservers'] From rdmurray at bitdance.com Sun Dec 20 02:46:40 2009 From: rdmurray at bitdance.com (R. David Murray) Date: Sat, 19 Dec 2009 20:46:40 -0500 Subject: [Python-checkins] r76892 - python/trunk/Doc/library/stdtypes.rst In-Reply-To: <4B2D65CF.8040707@gmail.com> References: <4b2d196c.0467f10a.549d.5580SMTPIN_ADDED@mx.google.com> <4B2D65CF.8040707@gmail.com> Message-ID: <20091220014640.E0BE61F86BC@kimball.webabinitio.net> On Sun, 20 Dec 2009 09:46:23 +1000, Nick Coghlan wrote: > georg.brandl wrote: > > Modified: python/trunk/Doc/library/stdtypes.rst > > ============================================================================== > > --- python/trunk/Doc/library/stdtypes.rst (original) > > +++ python/trunk/Doc/library/stdtypes.rst Sat Dec 19 19:20:18 2009 > > @@ -2828,8 +2828,7 @@ > > > > .. attribute:: class.__bases__ > > > > - The tuple of base classes of a class object. If there are no base classes, this > > - will be an empty tuple. > > + The tuple of base classes of a class object. > > Hmm, I never found that redundant - it makes it clear the terminal value > is () rather than None. Since it says 'The tuple of...' its value should not be able to be anything other than a tuple unless that is explicitly documented, IMO. At least, that's what I'd expect. --David From python-checkins at python.org Sun Dec 20 07:05:13 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 20 Dec 2009 06:05:13 -0000 Subject: [Python-checkins] r76908 - in python/trunk: Lib/httplib.py Lib/test/test_urllib2.py Lib/urllib2.py Misc/NEWS Message-ID: Author: senthil.kumaran Date: Sun Dec 20 07:05:13 2009 New Revision: 76908 Log: Fix for issue 7291 - urllib2 cannot handle https with proxy requiring auth Refactored HTTPHandler tests and added testcase for proxy authorization. Modified: python/trunk/Lib/httplib.py python/trunk/Lib/test/test_urllib2.py python/trunk/Lib/urllib2.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/httplib.py ============================================================================== --- python/trunk/Lib/httplib.py (original) +++ python/trunk/Lib/httplib.py Sun Dec 20 07:05:13 2009 @@ -667,15 +667,24 @@ self._method = None self._tunnel_host = None self._tunnel_port = None + self._tunnel_headers = {} self._set_hostport(host, port) if strict is not None: self.strict = strict - def set_tunnel(self, host, port=None): - """ Sets up the host and the port for the HTTP CONNECT Tunnelling.""" + def set_tunnel(self, host, port=None, headers=None): + """ Sets up the host and the port for the HTTP CONNECT Tunnelling. + + The headers argument should be a mapping of extra HTTP headers + to send with the CONNECT request. + """ self._tunnel_host = host self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() def _set_hostport(self, host, port): if port is None: @@ -699,7 +708,10 @@ def _tunnel(self): self._set_hostport(self._tunnel_host, self._tunnel_port) - self.send("CONNECT %s:%d HTTP/1.0\r\n\r\n" % (self.host, self.port)) + self.send("CONNECT %s:%d HTTP/1.0\r\n" % (self.host, self.port)) + for header, value in self._tunnel_headers.iteritems(): + self.send("%s: %s\r\n" % (header, value)) + self.send("\r\n") response = self.response_class(self.sock, strict = self.strict, method = self._method) (version, code, message) = response._read_status() Modified: python/trunk/Lib/test/test_urllib2.py ============================================================================== --- python/trunk/Lib/test/test_urllib2.py (original) +++ python/trunk/Lib/test/test_urllib2.py Sun Dec 20 07:05:13 2009 @@ -261,6 +261,50 @@ def __call__(self, *args): return self.handle(self.meth_name, self.action, *args) +class MockHTTPResponse: + def __init__(self, fp, msg, status, reason): + self.fp = fp + self.msg = msg + self.status = status + self.reason = reason + def read(self): + return '' + +class MockHTTPClass: + def __init__(self): + self.req_headers = [] + self.data = None + self.raise_on_endheaders = False + self._tunnel_headers = {} + + def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + self.host = host + self.timeout = timeout + return self + + def set_debuglevel(self, level): + self.level = level + + def set_tunnel(self, host, port=None, headers=None): + self._tunnel_host = host + self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() + def request(self, method, url, body=None, headers={}): + self.method = method + self.selector = url + self.req_headers += headers.items() + self.req_headers.sort() + if body: + self.data = body + if self.raise_on_endheaders: + import socket + raise socket.error() + def getresponse(self): + return MockHTTPResponse(MockFile(), {}, 200, "OK") + class MockHandler: # useful for testing handler machinery # see add_ordered_mock_handlers() docstring @@ -368,6 +412,13 @@ msg = mimetools.Message(StringIO("\r\n\r\n")) return MockResponse(200, "OK", msg, "", req.get_full_url()) +class MockHTTPSHandler(urllib2.AbstractHTTPHandler): + # Useful for testing the Proxy-Authorization request by verifying the + # properties of httpcon + httpconn = MockHTTPClass() + def https_open(self, req): + return self.do_open(self.httpconn, req) + class MockPasswordManager: def add_password(self, realm, uri, user, password): self.realm = realm @@ -680,37 +731,6 @@ self.assertEqual(req.type, "ftp") def test_http(self): - class MockHTTPResponse: - def __init__(self, fp, msg, status, reason): - self.fp = fp - self.msg = msg - self.status = status - self.reason = reason - def read(self): - return '' - class MockHTTPClass: - def __init__(self): - self.req_headers = [] - self.data = None - self.raise_on_endheaders = False - def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): - self.host = host - self.timeout = timeout - return self - def set_debuglevel(self, level): - self.level = level - def request(self, method, url, body=None, headers={}): - self.method = method - self.selector = url - self.req_headers += headers.items() - self.req_headers.sort() - if body: - self.data = body - if self.raise_on_endheaders: - import socket - raise socket.error() - def getresponse(self): - return MockHTTPResponse(MockFile(), {}, 200, "OK") h = urllib2.AbstractHTTPHandler() o = h.parent = MockOpener() @@ -974,6 +994,29 @@ self.assertEqual([(handlers[0], "https_open")], [tup[0:2] for tup in o.calls]) + def test_proxy_https_proxy_authorization(self): + o = OpenerDirector() + ph = urllib2.ProxyHandler(dict(https='proxy.example.com:3128')) + o.add_handler(ph) + https_handler = MockHTTPSHandler() + o.add_handler(https_handler) + req = Request("https://www.example.com/") + req.add_header("Proxy-Authorization","FooBar") + req.add_header("User-Agent","Grail") + self.assertEqual(req.get_host(), "www.example.com") + self.assertIsNone(req._tunnel_host) + r = o.open(req) + # Verify Proxy-Authorization gets tunneled to request. + # httpsconn req_headers do not have the Proxy-Authorization header but + # the req will have. + self.assertFalse(("Proxy-Authorization","FooBar") in + https_handler.httpconn.req_headers) + self.assertTrue(("User-Agent","Grail") in + https_handler.httpconn.req_headers) + self.assertIsNotNone(req._tunnel_host) + self.assertEqual(req.get_host(), "proxy.example.com:3128") + self.assertEqual(req.get_header("Proxy-authorization"),"FooBar") + def test_basic_auth(self, quote_char='"'): opener = OpenerDirector() password_manager = MockPasswordManager() Modified: python/trunk/Lib/urllib2.py ============================================================================== --- python/trunk/Lib/urllib2.py (original) +++ python/trunk/Lib/urllib2.py Sun Dec 20 07:05:13 2009 @@ -1120,7 +1120,14 @@ (name.title(), val) for name, val in headers.items()) if req._tunnel_host: - h.set_tunnel(req._tunnel_host) + tunnel_headers = {} + proxy_auth_hdr = "Proxy-Authorization" + if proxy_auth_hdr in headers: + tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] + # Proxy-Authorization should not be sent to origin + # server. + del headers[proxy_auth_hdr] + h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: h.request(req.get_method(), req.get_selector(), req.data, headers) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 20 07:05:13 2009 @@ -24,6 +24,9 @@ Library ------- +- Issue #7231: urllib2 cannot handle https with proxy requiring auth. + Patch by Tatsuhiro Tsujikawa. + - Issue #7349: Make methods of file objects in the io module accept None as an argument where file-like objects (ie StringIO and BytesIO) accept them to mean the same as passing no argument. From python-checkins at python.org Sun Dec 20 07:32:46 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 20 Dec 2009 06:32:46 -0000 Subject: [Python-checkins] r76909 - in python/branches/release26-maint: Lib/httplib.py Lib/test/test_urllib2.py Lib/urllib2.py Misc/NEWS Message-ID: Author: senthil.kumaran Date: Sun Dec 20 07:32:46 2009 New Revision: 76909 Log: Merged revisions 76908 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76908 | senthil.kumaran | 2009-12-20 11:35:13 +0530 (Sun, 20 Dec 2009) | 4 lines Fix for issue 7291 - urllib2 cannot handle https with proxy requiring auth Refactored HTTPHandler tests and added testcase for proxy authorization. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/httplib.py python/branches/release26-maint/Lib/test/test_urllib2.py python/branches/release26-maint/Lib/urllib2.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/httplib.py ============================================================================== --- python/branches/release26-maint/Lib/httplib.py (original) +++ python/branches/release26-maint/Lib/httplib.py Sun Dec 20 07:32:46 2009 @@ -652,15 +652,24 @@ self._method = None self._tunnel_host = None self._tunnel_port = None + self._tunnel_headers = {} self._set_hostport(host, port) if strict is not None: self.strict = strict def _set_tunnel(self, host, port=None): - """ Sets up the host and the port for the HTTP CONNECT Tunnelling.""" + """ Sets up the host and the port for the HTTP CONNECT Tunnelling. + + The headers argument should be a mapping of extra HTTP headers + to send with the CONNECT request. + """ self._tunnel_host = host self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() def _set_hostport(self, host, port): if port is None: @@ -684,7 +693,10 @@ def _tunnel(self): self._set_hostport(self._tunnel_host, self._tunnel_port) - self.send("CONNECT %s:%d HTTP/1.0\r\n\r\n" % (self.host, self.port)) + self.send("CONNECT %s:%d HTTP/1.0\r\n" % (self.host, self.port)) + for header, value in self._tunnel_headers.iteritems(): + self.send("%s: %s\r\n" % (header, value)) + self.send("\r\n") response = self.response_class(self.sock, strict = self.strict, method = self._method) (version, code, message) = response._read_status() Modified: python/branches/release26-maint/Lib/test/test_urllib2.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_urllib2.py (original) +++ python/branches/release26-maint/Lib/test/test_urllib2.py Sun Dec 20 07:32:46 2009 @@ -261,6 +261,50 @@ def __call__(self, *args): return self.handle(self.meth_name, self.action, *args) +class MockHTTPResponse: + def __init__(self, fp, msg, status, reason): + self.fp = fp + self.msg = msg + self.status = status + self.reason = reason + def read(self): + return '' + +class MockHTTPClass: + def __init__(self): + self.req_headers = [] + self.data = None + self.raise_on_endheaders = False + self._tunnel_headers = {} + + def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + self.host = host + self.timeout = timeout + return self + + def set_debuglevel(self, level): + self.level = level + + def _set_tunnel(self, host, port=None, headers=None): + self._tunnel_host = host + self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() + def request(self, method, url, body=None, headers={}): + self.method = method + self.selector = url + self.req_headers += headers.items() + self.req_headers.sort() + if body: + self.data = body + if self.raise_on_endheaders: + import socket + raise socket.error() + def getresponse(self): + return MockHTTPResponse(MockFile(), {}, 200, "OK") + class MockHandler: # useful for testing handler machinery # see add_ordered_mock_handlers() docstring @@ -368,6 +412,13 @@ msg = mimetools.Message(StringIO("\r\n\r\n")) return MockResponse(200, "OK", msg, "", req.get_full_url()) +class MockHTTPSHandler(urllib2.AbstractHTTPHandler): + # Useful for testing the Proxy-Authorization request by verifying the + # properties of httpcon + httpconn = MockHTTPClass() + def https_open(self, req): + return self.do_open(self.httpconn, req) + class MockPasswordManager: def add_password(self, realm, uri, user, password): self.realm = realm @@ -680,37 +731,6 @@ self.assertEqual(req.type, "ftp") def test_http(self): - class MockHTTPResponse: - def __init__(self, fp, msg, status, reason): - self.fp = fp - self.msg = msg - self.status = status - self.reason = reason - def read(self): - return '' - class MockHTTPClass: - def __init__(self): - self.req_headers = [] - self.data = None - self.raise_on_endheaders = False - def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): - self.host = host - self.timeout = timeout - return self - def set_debuglevel(self, level): - self.level = level - def request(self, method, url, body=None, headers={}): - self.method = method - self.selector = url - self.req_headers += headers.items() - self.req_headers.sort() - if body: - self.data = body - if self.raise_on_endheaders: - import socket - raise socket.error() - def getresponse(self): - return MockHTTPResponse(MockFile(), {}, 200, "OK") h = urllib2.AbstractHTTPHandler() o = h.parent = MockOpener() @@ -974,6 +994,29 @@ self.assertEqual([(handlers[0], "https_open")], [tup[0:2] for tup in o.calls]) + def test_proxy_https_proxy_authorization(self): + o = OpenerDirector() + ph = urllib2.ProxyHandler(dict(https='proxy.example.com:3128')) + o.add_handler(ph) + https_handler = MockHTTPSHandler() + o.add_handler(https_handler) + req = Request("https://www.example.com/") + req.add_header("Proxy-Authorization","FooBar") + req.add_header("User-Agent","Grail") + self.assertEqual(req.get_host(), "www.example.com") + self.assertTrue(req._tunnel_host is None) + r = o.open(req) + # Verify Proxy-Authorization gets tunneled to request. + # httpsconn req_headers do not have the Proxy-Authorization header but + # the req will have. + self.assertFalse(("Proxy-Authorization","FooBar") in + https_handler.httpconn.req_headers) + self.assertTrue(("User-Agent","Grail") in + https_handler.httpconn.req_headers) + self.assertFalse(req._tunnel_host is None) + self.assertEqual(req.get_host(), "proxy.example.com:3128") + self.assertEqual(req.get_header("Proxy-authorization"),"FooBar") + def test_basic_auth(self, quote_char='"'): opener = OpenerDirector() password_manager = MockPasswordManager() Modified: python/branches/release26-maint/Lib/urllib2.py ============================================================================== --- python/branches/release26-maint/Lib/urllib2.py (original) +++ python/branches/release26-maint/Lib/urllib2.py Sun Dec 20 07:32:46 2009 @@ -1120,7 +1120,14 @@ (name.title(), val) for name, val in headers.items()) if req._tunnel_host: - h._set_tunnel(req._tunnel_host) + tunnel_headers = {} + proxy_auth_hdr = "Proxy-Authorization" + if proxy_auth_hdr in headers: + tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] + # Proxy-Authorization should not be sent to origin + # server. + del headers[proxy_auth_hdr] + h._set_tunnel(req._tunnel_host, headers=tunnel_headers) try: h.request(req.get_method(), req.get_selector(), req.data, headers) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Dec 20 07:32:46 2009 @@ -35,6 +35,9 @@ Library ------- +- Issue #7231: urllib2 cannot handle https with proxy requiring auth. Patch by + Tatsuhiro Tsujikawa. + - Issue #7348: StringIO.StringIO.readline(-1) now acts as if it got no argument like other file objects. From python-checkins at python.org Sun Dec 20 08:10:31 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 20 Dec 2009 07:10:31 -0000 Subject: [Python-checkins] r76910 - in python/branches/py3k: Lib/http/client.py Lib/test/test_urllib2.py Lib/urllib/request.py Misc/NEWS Message-ID: Author: senthil.kumaran Date: Sun Dec 20 08:10:31 2009 New Revision: 76910 Log: Merged revisions 76908 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76908 | senthil.kumaran | 2009-12-20 11:35:13 +0530 (Sun, 20 Dec 2009) | 4 lines Fix for issue 7291 - urllib2 cannot handle https with proxy requiring auth Refactored HTTPHandler tests and added testcase for proxy authorization. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/http/client.py python/branches/py3k/Lib/test/test_urllib2.py python/branches/py3k/Lib/urllib/request.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/http/client.py ============================================================================== --- python/branches/py3k/Lib/http/client.py (original) +++ python/branches/py3k/Lib/http/client.py Sun Dec 20 08:10:31 2009 @@ -648,9 +648,18 @@ if strict is not None: self.strict = strict - def set_tunnel(self, host, port=None): + def set_tunnel(self, host, port=None, headers=None): + """ Sets up the host and the port for the HTTP CONNECT Tunnelling. + + The headers argument should be a mapping of extra HTTP headers + to send with the CONNECT request. + """ self._tunnel_host = host self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() def _set_hostport(self, host, port): if port is None: @@ -674,12 +683,18 @@ def _tunnel(self): self._set_hostport(self._tunnel_host, self._tunnel_port) - connect_str = "CONNECT %s:%d HTTP/1.0\r\n\r\n" %(self.host, self.port) + connect_str = "CONNECT %s:%d HTTP/1.0\r\n" %(self.host, self.port) connect_bytes = connect_str.encode("ascii") self.send(connect_bytes) + for header, value in self._tunnel_headers.iteritems(): + header_str = "%s: %s\r\n" % (header, value) + header_bytes = header_str.encode("ascii") + self.send(header_bytes) + response = self.response_class(self.sock, strict = self.strict, - method= self._method) + method = self._method) (version, code, message) = response._read_status() + if code != 200: self.close() raise socket.error("Tunnel connection failed: %d %s" % (code, Modified: python/branches/py3k/Lib/test/test_urllib2.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllib2.py (original) +++ python/branches/py3k/Lib/test/test_urllib2.py Sun Dec 20 08:10:31 2009 @@ -259,6 +259,61 @@ def __call__(self, *args): return self.handle(self.meth_name, self.action, *args) +class MockHTTPResponse(io.IOBase): + def __init__(self, fp, msg, status, reason): + self.fp = fp + 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 + self.req_headers = [] + self.data = None + self.raise_on_endheaders = False + self._tunnel_headers = {} + + def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + self.host = host + self.timeout = timeout + return self + + def set_debuglevel(self, level): + self.level = level + + def set_tunnel(self, host, port=None, headers=None): + self._tunnel_host = host + self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() + + def request(self, method, url, body=None, headers={}): + self.method = method + self.selector = url + self.req_headers += headers.items() + self.req_headers.sort() + if body: + self.data = body + if self.raise_on_endheaders: + import socket + raise socket.error() + def getresponse(self): + return MockHTTPResponse(MockFile(), {}, 200, "OK") + class MockHandler: # useful for testing handler machinery # see add_ordered_mock_handlers() docstring @@ -366,6 +421,13 @@ msg = email.message_from_string("\r\n\r\n") return MockResponse(200, "OK", msg, "", req.get_full_url()) +class MockHTTPSHandler(urllib.request.AbstractHTTPHandler): + # Useful for testing the Proxy-Authorization request by verifying the + # properties of httpcon + httpconn = MockHTTPClass() + def https_open(self, req): + return self.do_open(self.httpconn, req) + class MockPasswordManager: def add_password(self, realm, uri, user, password): self.realm = realm @@ -677,43 +739,6 @@ self.assertEqual(req.type, "ftp") def test_http(self): - class MockHTTPResponse(io.IOBase): - def __init__(self, fp, msg, status, reason): - self.fp = fp - 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 - self.req_headers = [] - self.data = None - self.raise_on_endheaders = False - def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): - self.host = host - self.timeout = timeout - return self - def set_debuglevel(self, level): - self.level = level - def request(self, method, url, body=None, headers={}): - self.method = method - self.selector = url - self.req_headers += headers.items() - self.req_headers.sort() - if body: - self.data = body - if self.raise_on_endheaders: - import socket - raise socket.error() - def getresponse(self): - return MockHTTPResponse(MockFile(), {}, 200, "OK") h = urllib.request.AbstractHTTPHandler() o = h.parent = MockOpener() @@ -979,6 +1004,28 @@ self.assertEqual([(handlers[0], "https_open")], [tup[0:2] for tup in o.calls]) + def test_proxy_https_proxy_authorization(self): + o = OpenerDirector() + ph = urllib.request.ProxyHandler(dict(https='proxy.example.com:3128')) + o.add_handler(ph) + https_handler = MockHTTPSHandler() + o.add_handler(https_handler) + req = Request("https://www.example.com/") + req.add_header("Proxy-Authorization","FooBar") + req.add_header("User-Agent","Grail") + self.assertEqual(req.get_host(), "www.example.com") + self.assertIsNone(req._tunnel_host) + r = o.open(req) + # Verify Proxy-Authorization gets tunneled to request. + # httpsconn req_headers do not have the Proxy-Authorization header but + # the req will have. + self.assertFalse(("Proxy-Authorization","FooBar") in + https_handler.httpconn.req_headers) + self.assertTrue(("User-Agent","Grail") in + https_handler.httpconn.req_headers) + self.assertIsNotNone(req._tunnel_host) + self.assertEqual(req.get_host(), "proxy.example.com:3128") + self.assertEqual(req.get_header("Proxy-authorization"),"FooBar") def test_basic_auth(self, quote_char='"'): opener = OpenerDirector() Modified: python/branches/py3k/Lib/urllib/request.py ============================================================================== --- python/branches/py3k/Lib/urllib/request.py (original) +++ python/branches/py3k/Lib/urllib/request.py Sun Dec 20 08:10:31 2009 @@ -31,8 +31,8 @@ objects of interest: -OpenerDirector -- Sets up the User-Agent as the Python-urllib and manages the -Handler classes while dealing with both requests and responses. +OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages +the Handler classes, while dealing with requests and responses. Request -- An object that encapsulates the state of a request. The state can be as simple as the URL. It can also include extra HTTP @@ -1059,7 +1059,14 @@ headers = dict((name.title(), val) for name, val in headers.items()) if req._tunnel_host: - h.set_tunnel(req._tunnel_host) + tunnel_headers = {} + proxy_auth_hdr = "Proxy-Authorization" + if proxy_auth_hdr in headers: + tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] + # Proxy-Authorization should not be sent to origin + # server. + del headers[proxy_auth_hdr] + h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: h.request(req.get_method(), req.selector, req.data, headers) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Dec 20 08:10:31 2009 @@ -157,6 +157,9 @@ Library ------- +- Issue #7231: urllib2 cannot handle https with proxy requiring auth. Patch by + Tatsuhiro Tsujikawa. + - Issue #4757: `zlib.compress` and other methods in the zlib module now raise a TypeError when given an `str` object (rather than a `bytes`-like object). Patch by Victor Stinner and Florent Xicluna. From python-checkins at python.org Sun Dec 20 08:18:22 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 20 Dec 2009 07:18:22 -0000 Subject: [Python-checkins] r76911 - in python/branches/release31-maint: Lib/http/client.py Lib/test/test_urllib2.py Lib/urllib/request.py Misc/NEWS Message-ID: Author: senthil.kumaran Date: Sun Dec 20 08:18:22 2009 New Revision: 76911 Log: Merged revisions 76910 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76910 | senthil.kumaran | 2009-12-20 12:40:31 +0530 (Sun, 20 Dec 2009) | 10 lines Merged revisions 76908 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76908 | senthil.kumaran | 2009-12-20 11:35:13 +0530 (Sun, 20 Dec 2009) | 4 lines Fix for issue 7291 - urllib2 cannot handle https with proxy requiring auth Refactored HTTPHandler tests and added testcase for proxy authorization. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/http/client.py python/branches/release31-maint/Lib/test/test_urllib2.py python/branches/release31-maint/Lib/urllib/request.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/http/client.py ============================================================================== --- python/branches/release31-maint/Lib/http/client.py (original) +++ python/branches/release31-maint/Lib/http/client.py Sun Dec 20 08:18:22 2009 @@ -648,9 +648,13 @@ if strict is not None: self.strict = strict - def _set_tunnel(self, host, port=None): + def _set_tunnel(self, host, port=None, headers=None): self._tunnel_host = host self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() def _set_hostport(self, host, port): if port is None: @@ -674,12 +678,18 @@ def _tunnel(self): self._set_hostport(self._tunnel_host, self._tunnel_port) - connect_str = "CONNECT %s:%d HTTP/1.0\r\n\r\n" %(self.host, self.port) + connect_str = "CONNECT %s:%d HTTP/1.0\r\n" %(self.host, self.port) connect_bytes = connect_str.encode("ascii") self.send(connect_bytes) + for header, value in self._tunnel_headers.iteritems(): + header_str = "%s: %s\r\n" % (header, value) + header_bytes = header_str.encode("ascii") + self.send(header_bytes) + response = self.response_class(self.sock, strict = self.strict, - method= self._method) + method = self._method) (version, code, message) = response._read_status() + if code != 200: self.close() raise socket.error("Tunnel connection failed: %d %s" % (code, Modified: python/branches/release31-maint/Lib/test/test_urllib2.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_urllib2.py (original) +++ python/branches/release31-maint/Lib/test/test_urllib2.py Sun Dec 20 08:18:22 2009 @@ -259,6 +259,61 @@ def __call__(self, *args): return self.handle(self.meth_name, self.action, *args) +class MockHTTPResponse(io.IOBase): + def __init__(self, fp, msg, status, reason): + self.fp = fp + 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 + self.req_headers = [] + self.data = None + self.raise_on_endheaders = False + self._tunnel_headers = {} + + def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + self.host = host + self.timeout = timeout + return self + + def set_debuglevel(self, level): + self.level = level + + def _set_tunnel(self, host, port=None, headers=None): + self._tunnel_host = host + self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() + + def request(self, method, url, body=None, headers={}): + self.method = method + self.selector = url + self.req_headers += headers.items() + self.req_headers.sort() + if body: + self.data = body + if self.raise_on_endheaders: + import socket + raise socket.error() + def getresponse(self): + return MockHTTPResponse(MockFile(), {}, 200, "OK") + class MockHandler: # useful for testing handler machinery # see add_ordered_mock_handlers() docstring @@ -366,6 +421,13 @@ msg = email.message_from_string("\r\n\r\n") return MockResponse(200, "OK", msg, "", req.get_full_url()) +class MockHTTPSHandler(urllib.request.AbstractHTTPHandler): + # Useful for testing the Proxy-Authorization request by verifying the + # properties of httpcon + httpconn = MockHTTPClass() + def https_open(self, req): + return self.do_open(self.httpconn, req) + class MockPasswordManager: def add_password(self, realm, uri, user, password): self.realm = realm @@ -677,43 +739,6 @@ self.assertEqual(req.type, "ftp") def test_http(self): - class MockHTTPResponse(io.IOBase): - def __init__(self, fp, msg, status, reason): - self.fp = fp - 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 - self.req_headers = [] - self.data = None - self.raise_on_endheaders = False - def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): - self.host = host - self.timeout = timeout - return self - def set_debuglevel(self, level): - self.level = level - def request(self, method, url, body=None, headers={}): - self.method = method - self.selector = url - self.req_headers += headers.items() - self.req_headers.sort() - if body: - self.data = body - if self.raise_on_endheaders: - import socket - raise socket.error() - def getresponse(self): - return MockHTTPResponse(MockFile(), {}, 200, "OK") h = urllib.request.AbstractHTTPHandler() o = h.parent = MockOpener() @@ -979,6 +1004,28 @@ self.assertEqual([(handlers[0], "https_open")], [tup[0:2] for tup in o.calls]) + def test_proxy_https_proxy_authorization(self): + o = OpenerDirector() + ph = urllib.request.ProxyHandler(dict(https='proxy.example.com:3128')) + o.add_handler(ph) + https_handler = MockHTTPSHandler() + o.add_handler(https_handler) + req = Request("https://www.example.com/") + req.add_header("Proxy-Authorization","FooBar") + req.add_header("User-Agent","Grail") + self.assertEqual(req.get_host(), "www.example.com") + self.assertIsNone(req._tunnel_host) + r = o.open(req) + # Verify Proxy-Authorization gets tunneled to request. + # httpsconn req_headers do not have the Proxy-Authorization header but + # the req will have. + self.assertFalse(("Proxy-Authorization","FooBar") in + https_handler.httpconn.req_headers) + self.assertTrue(("User-Agent","Grail") in + https_handler.httpconn.req_headers) + self.assertIsNotNone(req._tunnel_host) + self.assertEqual(req.get_host(), "proxy.example.com:3128") + self.assertEqual(req.get_header("Proxy-authorization"),"FooBar") def test_basic_auth(self, quote_char='"'): opener = OpenerDirector() Modified: python/branches/release31-maint/Lib/urllib/request.py ============================================================================== --- python/branches/release31-maint/Lib/urllib/request.py (original) +++ python/branches/release31-maint/Lib/urllib/request.py Sun Dec 20 08:18:22 2009 @@ -31,8 +31,8 @@ objects of interest: -OpenerDirector -- Sets up the User-Agent as the Python-urllib and manages the -Handler classes while dealing with both requests and responses. +OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages +the Handler classes, while dealing with requests and responses. Request -- An object that encapsulates the state of a request. The state can be as simple as the URL. It can also include extra HTTP @@ -1059,7 +1059,14 @@ headers = dict((name.title(), val) for name, val in headers.items()) if req._tunnel_host: - h._set_tunnel(req._tunnel_host) + tunnel_headers = {} + proxy_auth_hdr = "Proxy-Authorization" + if proxy_auth_hdr in headers: + tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] + # Proxy-Authorization should not be sent to origin + # server. + del headers[proxy_auth_hdr] + h._set_tunnel(req._tunnel_host, headers=tunnel_headers) try: h.request(req.get_method(), req.selector, req.data, headers) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Dec 20 08:18:22 2009 @@ -58,6 +58,9 @@ Library ------- +- Issue #7231: urllib2 cannot handle https with proxy requiring auth. Patch by + Tatsuhiro Tsujikawa. + - Issue #4757: `zlib.compress` and other methods in the zlib module now raise a TypeError when given an `str` object (rather than a `bytes`-like object). Patch by Victor Stinner and Florent Xicluna. From python-checkins at python.org Sun Dec 20 08:29:31 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 20 Dec 2009 07:29:31 -0000 Subject: [Python-checkins] r76912 - python/trunk/Doc/library/httplib.rst Message-ID: Author: senthil.kumaran Date: Sun Dec 20 08:29:31 2009 New Revision: 76912 Log: Document the headers parameter for set_tunnel. Modified: python/trunk/Doc/library/httplib.rst Modified: python/trunk/Doc/library/httplib.rst ============================================================================== --- python/trunk/Doc/library/httplib.rst (original) +++ python/trunk/Doc/library/httplib.rst Sun Dec 20 08:29:31 2009 @@ -428,11 +428,14 @@ debug level is ``0``, meaning no debugging output is printed. -.. method:: HTTPConnection.set_tunnel(host,port=None) +.. method:: HTTPConnection.set_tunnel(host,port=None, headers=None) Set the host and the port for HTTP Connect Tunnelling. Normally used when it is required to do HTTPS Conection through a proxy server. + The headers argument should be a mapping of extra HTTP headers to to sent + with the CONNECT request. + .. versionadded:: 2.7 From python-checkins at python.org Sun Dec 20 08:31:22 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 20 Dec 2009 07:31:22 -0000 Subject: [Python-checkins] r76913 - python/branches/py3k/Doc/library/http.client.rst Message-ID: Author: senthil.kumaran Date: Sun Dec 20 08:31:21 2009 New Revision: 76913 Log: Document the headers parameter for set_tunnel. 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 Sun Dec 20 08:31:21 2009 @@ -386,11 +386,14 @@ .. versionadded:: 3.1 -.. method:: HTTPConnection.set_tunnel(host, port=None) +.. method:: HTTPConnection.set_tunnel(host, port=None, headers=None) Set the host and the port for HTTP Connect Tunnelling. Normally used when it is required to a HTTPS Connection through a proxy server. + The headers argument should be a mapping of extra HTTP headers to to sent + with the CONNECT request. + .. versionadded:: 3.2 .. method:: HTTPConnection.connect() From python-checkins at python.org Sun Dec 20 13:24:57 2009 From: python-checkins at python.org (ezio.melotti) Date: Sun, 20 Dec 2009 12:24:57 -0000 Subject: [Python-checkins] r76914 - python/branches/py3k/Doc/library/tokenize.rst Message-ID: Author: ezio.melotti Date: Sun Dec 20 13:24:57 2009 New Revision: 76914 Log: Fixed capitalization and markup; added imports in the example Modified: python/branches/py3k/Doc/library/tokenize.rst Modified: python/branches/py3k/Doc/library/tokenize.rst ============================================================================== --- python/branches/py3k/Doc/library/tokenize.rst (original) +++ python/branches/py3k/Doc/library/tokenize.rst Sun Dec 20 13:24:57 2009 @@ -94,16 +94,19 @@ (as a string) and a list of any lines (not decoded from bytes) it has read in. - It detects the encoding from the presence of a utf-8 bom or an encoding - cookie as specified in pep-0263. If both a bom and a cookie are present, + It detects the encoding from the presence of a UTF-8 BOM or an encoding + cookie as specified in :pep:`263`. If both a BOM and a cookie are present, but disagree, a SyntaxError will be raised. - If no encoding is specified, then the default of 'utf-8' will be returned. + If no encoding is specified, then the default of ``'utf-8'`` will be returned. Example of a script re-writer that transforms float literals into Decimal objects:: + from tokenize import tokenize, untokenize, NUMBER, STRING, NAME, OP + from io import BytesIO + def decistmt(s): """Substitute Decimals for floats in a string of statements. From python-checkins at python.org Sun Dec 20 13:26:45 2009 From: python-checkins at python.org (ezio.melotti) Date: Sun, 20 Dec 2009 12:26:45 -0000 Subject: [Python-checkins] r76915 - in python/branches/release31-maint: Doc/library/tokenize.rst Message-ID: Author: ezio.melotti Date: Sun Dec 20 13:26:45 2009 New Revision: 76915 Log: Merged revisions 76914 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76914 | ezio.melotti | 2009-12-20 14:24:57 +0200 (Sun, 20 Dec 2009) | 1 line Fixed capitalization and markup; added imports in the example ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/tokenize.rst Modified: python/branches/release31-maint/Doc/library/tokenize.rst ============================================================================== --- python/branches/release31-maint/Doc/library/tokenize.rst (original) +++ python/branches/release31-maint/Doc/library/tokenize.rst Sun Dec 20 13:26:45 2009 @@ -94,16 +94,19 @@ (as a string) and a list of any lines (not decoded from bytes) it has read in. - It detects the encoding from the presence of a utf-8 bom or an encoding - cookie as specified in pep-0263. If both a bom and a cookie are present, + It detects the encoding from the presence of a UTF-8 BOM or an encoding + cookie as specified in :pep:`263`. If both a BOM and a cookie are present, but disagree, a SyntaxError will be raised. - If no encoding is specified, then the default of 'utf-8' will be returned. + If no encoding is specified, then the default of ``'utf-8'`` will be returned. Example of a script re-writer that transforms float literals into Decimal objects:: + from tokenize import tokenize, untokenize, NUMBER, STRING, NAME, OP + from io import BytesIO + def decistmt(s): """Substitute Decimals for floats in a string of statements. From python-checkins at python.org Sun Dec 20 14:58:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 13:58:18 -0000 Subject: [Python-checkins] r76916 - python/trunk/Modules/mathmodule.c Message-ID: Author: mark.dickinson Date: Sun Dec 20 14:58:18 2009 New Revision: 76916 Log: math.factorial depends on PyLong_AsLong correctly converting floats; rewrite it to do the conversion explicitly instead. See issue #7550. Modified: python/trunk/Modules/mathmodule.c Modified: python/trunk/Modules/mathmodule.c ============================================================================== --- python/trunk/Modules/mathmodule.c (original) +++ python/trunk/Modules/mathmodule.c Sun Dec 20 14:58:18 2009 @@ -1082,15 +1082,22 @@ PyObject *result, *iobj, *newresult; if (PyFloat_Check(arg)) { + PyObject *lx; double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg); - if (dx != floor(dx)) { + if (!(Py_IS_FINITE(dx) && dx == floor(dx))) { PyErr_SetString(PyExc_ValueError, "factorial() only accepts integral values"); return NULL; } + lx = PyLong_FromDouble(dx); + if (lx == NULL) + return NULL; + x = PyLong_AsLong(lx); + Py_DECREF(lx); } + else + x = PyInt_AsLong(arg); - x = PyInt_AsLong(arg); if (x == -1 && PyErr_Occurred()) return NULL; if (x < 0) { From python-checkins at python.org Sun Dec 20 15:07:48 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 14:07:48 -0000 Subject: [Python-checkins] r76917 - in python/branches/py3k: Modules/mathmodule.c Message-ID: Author: mark.dickinson Date: Sun Dec 20 15:07:47 2009 New Revision: 76917 Log: Merged revisions 76916 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76916 | mark.dickinson | 2009-12-20 13:58:18 +0000 (Sun, 20 Dec 2009) | 3 lines math.factorial depends on PyLong_AsLong correctly converting floats; rewrite it to do the conversion explicitly instead. See issue #7550. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/mathmodule.c Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Sun Dec 20 15:07:47 2009 @@ -1137,15 +1137,22 @@ PyObject *result, *iobj, *newresult; if (PyFloat_Check(arg)) { + PyObject *lx; double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg); - if (dx != floor(dx)) { + if (!(Py_IS_FINITE(dx) && dx == floor(dx))) { PyErr_SetString(PyExc_ValueError, "factorial() only accepts integral values"); return NULL; } + lx = PyLong_FromDouble(dx); + if (lx == NULL) + return NULL; + x = PyLong_AsLong(lx); + Py_DECREF(lx); } + else + x = PyLong_AsLong(arg); - x = PyLong_AsLong(arg); if (x == -1 && PyErr_Occurred()) return NULL; if (x < 0) { From python-checkins at python.org Sun Dec 20 15:08:45 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 14:08:45 -0000 Subject: [Python-checkins] r76918 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sun Dec 20 15:08:45 2009 New Revision: 76918 Log: Blocked revisions 76916 via svnmerge ........ r76916 | mark.dickinson | 2009-12-20 13:58:18 +0000 (Sun, 20 Dec 2009) | 3 lines math.factorial depends on PyLong_AsLong correctly converting floats; rewrite it to do the conversion explicitly instead. See issue #7550. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 20 15:09:20 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 14:09:20 -0000 Subject: [Python-checkins] r76919 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Dec 20 15:09:20 2009 New Revision: 76919 Log: Blocked revisions 76917 via svnmerge ................ r76917 | mark.dickinson | 2009-12-20 14:07:47 +0000 (Sun, 20 Dec 2009) | 10 lines Merged revisions 76916 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76916 | mark.dickinson | 2009-12-20 13:58:18 +0000 (Sun, 20 Dec 2009) | 3 lines math.factorial depends on PyLong_AsLong correctly converting floats; rewrite it to do the conversion explicitly instead. See issue #7550. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Dec 20 15:20:16 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 20 Dec 2009 14:20:16 -0000 Subject: [Python-checkins] r76920 - python/trunk/Doc/faq/programming.rst Message-ID: Author: georg.brandl Date: Sun Dec 20 15:20:16 2009 New Revision: 76920 Log: #7495: backport Programming FAQ review to trunk. Modified: python/trunk/Doc/faq/programming.rst Modified: python/trunk/Doc/faq/programming.rst ============================================================================== --- python/trunk/Doc/faq/programming.rst (original) +++ python/trunk/Doc/faq/programming.rst Sun Dec 20 15:20:16 2009 @@ -176,31 +176,32 @@ it is much shorter and far faster to use :: - L2 = list(L1[:3]) # "list" is redundant if L1 is a list. + L2 = list(L1[:3]) # "list" is redundant if L1 is a list. Note that the functionally-oriented builtins such as :func:`map`, :func:`zip`, and friends can be a convenient accelerator for loops that perform a single task. For example to pair the elements of two lists together:: - >>> zip([1,2,3], [4,5,6]) + >>> zip([1, 2, 3], [4, 5, 6]) [(1, 4), (2, 5), (3, 6)] or to compute a number of sines:: - >>> map( math.sin, (1,2,3,4)) - [0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308] + >>> map(math.sin, (1, 2, 3, 4)) + [0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308] The operation completes very quickly in such cases. -Other examples include the ``join()`` and ``split()`` methods of string objects. +Other examples include the ``join()`` and ``split()`` :ref:`methods +of string objects `. For example if s1..s7 are large (10K+) strings then ``"".join([s1,s2,s3,s4,s5,s6,s7])`` may be far faster than the more obvious ``s1+s2+s3+s4+s5+s6+s7``, since the "summation" will compute many subexpressions, whereas ``join()`` does all the copying in one pass. For -manipulating strings, use the ``replace()`` method on string objects. Use -regular expressions only when you're not dealing with constant string patterns. -Consider using the string formatting operations ``string % tuple`` and ``string -% dictionary``. +manipulating strings, use the ``replace()`` and the ``format()`` :ref:`methods +on string objects `. Use regular expressions only when you're +not dealing with constant string patterns. You may still use :ref:`the old % +operations ` ``string % tuple`` and ``string % dictionary``. Be sure to use the :meth:`list.sort` builtin method to do sorting, and see the `sorting mini-HOWTO `_ for examples @@ -210,7 +211,7 @@ Another common trick is to "push loops into functions or methods." For example suppose you have a program that runs slowly and you use the profiler to determine that a Python function ``ff()`` is being called lots of times. If you -notice that ``ff ()``:: +notice that ``ff()``:: def ff(x): ... # do something with x computing result... @@ -331,24 +332,6 @@ >>> print x 11 -In Python3, you can do a similar thing in a nested scope using the -:keyword:`nonlocal` keyword: - -.. doctest:: - :options: +SKIP - - >>> def foo(): - ... x = 10 - ... def bar(): - ... nonlocal x - ... print x - ... x += 1 - ... bar() - ... print x - >>> foo() - 10 - 11 - What are the rules for local and global variables in Python? ------------------------------------------------------------ @@ -411,7 +394,7 @@ It's good practice if you import modules in the following order: -1. standard library modules -- e.g. ``sys``, ``os``, ``getopt``, ``re``) +1. standard library modules -- e.g. ``sys``, ``os``, ``getopt``, ``re`` 2. third-party library modules (anything installed in Python's site-packages directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc. 3. locally-developed modules @@ -420,7 +403,7 @@ ``package.sub.m1`` module and want to import ``package.sub.m2``, do not just write ``import m2``, even though it's legal. Write ``from package.sub import m2`` instead. Relative imports can lead to a module being initialized twice, -leading to confusing bugs. +leading to confusing bugs. See :pep:`328` for details. It is sometimes necessary to move imports to a function or class to avoid problems with circular imports. Gordon McMillan says: @@ -648,9 +631,9 @@ a = B() b = a print b - <__main__.A instance at 016D07CC> + <__main__.A instance at 0x16D07CC> print a - <__main__.A instance at 016D07CC> + <__main__.A instance at 0x16D07CC> Arguably the class has a name: even though it is bound to two names and invoked through the name B the created instance is still reported as an instance of @@ -680,7 +663,7 @@ Comma is not an operator in Python. Consider this session:: >>> "a" in "b", "a" - (False, '1') + (False, 'a') Since the comma is not an operator, but a separator between expressions the above is evaluated as if you had entered:: @@ -689,7 +672,7 @@ not:: - >>> "a" in ("5", "a") + >>> "a" in ("b", "a") The same is true of the various assignment operators (``=``, ``+=`` etc). They are not truly operators but syntactic delimiters in assignment statements. @@ -731,12 +714,12 @@ if not isfunction(on_true): return on_true else: - return apply(on_true) + return on_true() else: if not isfunction(on_false): return on_false else: - return apply(on_false) + return on_false() In most cases you'll pass b and c directly: ``q(a, b, c)``. To avoid evaluating b or c when they shouldn't be, encapsulate them within a lambda function, e.g.: @@ -766,7 +749,7 @@ map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000))) # First 10 Fibonacci numbers - print map(lambda x,f=lambda x,f:(x<=1) or (f(x-1,f)+f(x-2,f)): f(x,f), + print map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1: f(x,f), range(10)) # Mandelbrot set @@ -792,10 +775,11 @@ How do I specify hexadecimal and octal integers? ------------------------------------------------ -To specify an octal digit, precede the octal value with a zero. For example, to -set the variable "a" to the octal value "10" (8 in decimal), type:: +To specify an octal digit, precede the octal value with a zero, and then a lower +or uppercase "o". For example, to set the variable "a" to the octal value "10" +(8 in decimal), type:: - >>> a = 010 + >>> a = 0o10 >>> a 8 @@ -811,17 +795,17 @@ 178 -Why does -22 / 10 return -3? ----------------------------- +Why does -22 // 10 return -3? +----------------------------- It's primarily driven by the desire that ``i % j`` have the same sign as ``j``. If you want that, and also want:: - i == (i / j) * j + (i % j) + i == (i // j) * j + (i % j) then integer division has to return the floor. C also requires that identity to -hold, and then compilers that truncate ``i / j`` need to make ``i % j`` have the -same sign as ``i``. +hold, and then compilers that truncate ``i // j`` need to make ``i % j`` have +the same sign as ``i``. There are few real use cases for ``i % j`` when ``j`` is negative. When ``j`` is positive, there are many, and in virtually all of them it's more useful for @@ -829,6 +813,12 @@ ago? ``-190 % 12 == 2`` is useful; ``-190 % 12 == -10`` is a bug waiting to bite. +.. note:: + + On Python 2, ``a / b`` returns the same as ``a // b`` if + ``__future__.division`` is not in effect. This is also known as "classic" + division. + How do I convert a string to a number? -------------------------------------- @@ -860,10 +850,11 @@ To convert, e.g., the number 144 to the string '144', use the built-in type constructor :func:`str`. If you want a hexadecimal or octal representation, use -the built-in functions ``hex()`` or ``oct()``. For fancy formatting, use -:ref:`the % operator ` on strings, e.g. ``"%04d" % 144`` -yields ``'0144'`` and ``"%.3f" % (1/3.0)`` yields ``'0.333'``. See the library -reference manual for details. +the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see +the :ref:`formatstrings` section, e.g. ``"{:04d}".format(144)`` yields +``'0144'`` and ``"{:.3f}".format(1/3)`` yields ``'0.333'``. You may also use +:ref:`the % operator ` on strings. See the library reference +manual for details. How do I modify a string in place? @@ -961,12 +952,12 @@ ... "\r\n" ... "\r\n") >>> lines.rstrip("\n\r") - "line 1 " + 'line 1 ' Since this is typically only desired when reading text one line at a time, using ``S.rstrip()`` this way works well. -For older versions of Python, There are two partial substitutes: +For older versions of Python, there are two partial substitutes: - If you want to remove all trailing whitespace, use the ``rstrip()`` method of string objects. This removes all trailing whitespace, not just a single @@ -1092,26 +1083,26 @@ If you don't mind reordering the list, sort it and then scan from the end of the list, deleting duplicates as you go:: - if List: - List.sort() - last = List[-1] - for i in range(len(List)-2, -1, -1): - if last == List[i]: - del List[i] + if mylist: + mylist.sort() + last = mylist[-1] + for i in range(len(mylist)-2, -1, -1): + if last == mylist[i]: + del mylist[i] else: - last = List[i] + last = mylist[i] If all elements of the list may be used as dictionary keys (i.e. they are all hashable) this is often faster :: d = {} - for x in List: - d[x] = x - List = d.values() + for x in mylist: + d[x] = 1 + mylist = list(d.keys()) In Python 2.5 and later, the following is possible instead:: - List = list(set(List)) + mylist = list(set(mylist)) This converts the list into a set, thereby removing duplicates, and then back into a list. @@ -1187,7 +1178,7 @@ Use a list comprehension:: - result = [obj.method() for obj in List] + result = [obj.method() for obj in mylist] More generically, you can try the following function:: @@ -1212,23 +1203,17 @@ case, use the ``pprint`` module to pretty-print the dictionary; the items will be presented in order sorted by the key. -A more complicated solution is to subclass ``UserDict.UserDict`` to create a +A more complicated solution is to subclass ``dict`` to create a ``SortedDict`` class that prints itself in a predictable order. Here's one simpleminded implementation of such a class:: - import UserDict, string - - class SortedDict(UserDict.UserDict): + class SortedDict(dict): def __repr__(self): - result = [] - append = result.append - keys = self.data.keys() - keys.sort() - for k in keys: - append("%s: %s" % (`k`, `self.data[k]`)) - return "{%s}" % string.join(result, ", ") + keys = sorted(self.keys()) + result = ("{!r}: {!r}".format(k, self[k]) for k in keys) + return "{{{}}}".format(", ".join(result)) - __str__ = __repr__ + __str__ = __repr__ This will work for many common situations you might encounter, though it's far from a perfect solution. The largest flaw is that if some values in the @@ -1250,14 +1235,14 @@ sorting is quite simple to do with list comprehensions. To sort a list of strings by their uppercase values:: - tmp1 = [(x.upper(), x) for x in L] # Schwartzian transform + tmp1 = [(x.upper(), x) for x in L] # Schwartzian transform tmp1.sort() Usorted = [x[1] for x in tmp1] To sort by the integer value of a subfield extending from positions 10-15 in each string:: - tmp2 = [(int(s[10:15]), s) for s in L] # Schwartzian transform + tmp2 = [(int(s[10:15]), s) for s in L] # Schwartzian transform tmp2.sort() Isorted = [x[1] for x in tmp2] @@ -1294,8 +1279,8 @@ An alternative for the last step is:: - result = [] - for p in pairs: result.append(p[1]) + >>> result = [] + >>> for p in pairs: result.append(p[1]) If you find this more legible, you might prefer to use this instead of the final list comprehension. However, it is almost twice as slow for long lists. Why? @@ -1363,7 +1348,7 @@ different thing based on what class it is. For example, if you have a function that does something:: - def search (obj): + def search(obj): if isinstance(obj, Mailbox): # ... code to search a mailbox elif isinstance(obj, Document): @@ -1466,8 +1451,8 @@ How do I create static class data and static class methods? ----------------------------------------------------------- -Static data (in the sense of C++ or Java) is easy; static methods (again in the -sense of C++ or Java) are not supported directly. +Both static data and static methods (in the sense of C++ or Java) are supported +in Python. For static data, simply define a class attribute. To assign a new value to the attribute, you have to explicitly use the class name in the assignment:: @@ -1486,9 +1471,9 @@ search path from ``c.__class__`` back to ``C``. Caution: within a method of C, an assignment like ``self.count = 42`` creates a -new and unrelated instance vrbl named "count" in ``self``'s own dict. Rebinding -of a class-static data name must always specify the class whether inside a -method or not:: +new and unrelated instance named "count" in ``self``'s own dict. Rebinding of a +class-static data name must always specify the class whether inside a method or +not:: C.count = 314 From python-checkins at python.org Sun Dec 20 15:20:59 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 20 Dec 2009 14:20:59 -0000 Subject: [Python-checkins] r76921 - python/branches/py3k Message-ID: Author: georg.brandl Date: Sun Dec 20 15:20:59 2009 New Revision: 76921 Log: Blocked revisions 76920 via svnmerge ........ r76920 | georg.brandl | 2009-12-20 15:20:16 +0100 (So, 20 Dez 2009) | 1 line #7495: backport Programming FAQ review to trunk. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Dec 20 15:21:27 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 20 Dec 2009 14:21:27 -0000 Subject: [Python-checkins] r76922 - python/branches/py3k/Doc/faq/programming.rst Message-ID: Author: georg.brandl Date: Sun Dec 20 15:21:27 2009 New Revision: 76922 Log: #7495: more review fixes. Modified: python/branches/py3k/Doc/faq/programming.rst Modified: python/branches/py3k/Doc/faq/programming.rst ============================================================================== --- python/branches/py3k/Doc/faq/programming.rst (original) +++ python/branches/py3k/Doc/faq/programming.rst Sun Dec 20 15:21:27 2009 @@ -182,7 +182,7 @@ and friends can be a convenient accelerator for loops that perform a single task. For example to pair the elements of two lists together:: - >>> list(zip([1,2,3], [4,5,6])) + >>> list(zip([1, 2, 3], [4, 5, 6])) [(1, 4), (2, 5), (3, 6)] or to compute a number of sines:: @@ -192,14 +192,16 @@ The operation completes very quickly in such cases. -Other examples include the ``join()`` and ``split()`` methods of string objects. +Other examples include the ``join()`` and ``split()`` :ref:`methods +of string objects `. + For example if s1..s7 are large (10K+) strings then ``"".join([s1,s2,s3,s4,s5,s6,s7])`` may be far faster than the more obvious ``s1+s2+s3+s4+s5+s6+s7``, since the "summation" will compute many subexpressions, whereas ``join()`` does all the copying in one pass. For -manipulating strings, use the ``replace()`` and the ``format()`` methods on -string objects. Use regular expressions only when you're not dealing with -constant string patterns. +manipulating strings, use the ``replace()`` and the ``format()`` :ref:`methods +on string objects `. Use regular expressions only when you're +not dealing with constant string patterns. Be sure to use the :meth:`list.sort` builtin method to do sorting, and see the `sorting mini-HOWTO `_ for examples @@ -414,8 +416,8 @@ Never use relative package imports. If you're writing code that's in the ``package.sub.m1`` module and want to import ``package.sub.m2``, do not just -write ``from . import m2``, even though it's legal. Write ``from package.sub import -m2`` instead. See :pep:`328` for details. +write ``from . import m2``, even though it's legal. Write ``from package.sub +import m2`` instead. See :pep:`328` for details. It is sometimes necessary to move imports to a function or class to avoid problems with circular imports. Gordon McMillan says: @@ -860,7 +862,7 @@ constructor :func:`str`. If you want a hexadecimal or octal representation, use the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see the :ref:`string-formatting` section, e.g. ``"{:04d}".format(144)`` yields -``'0144'`` and ``"{:.3f}" % (1/3)`` yields ``'0.333'``. +``'0144'`` and ``"{:.3f}".format(1/3)`` yields ``'0.333'``. How do I modify a string in place? From python-checkins at python.org Sun Dec 20 15:24:07 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 20 Dec 2009 14:24:07 -0000 Subject: [Python-checkins] r76923 - python/branches/py3k/Doc/faq/design.rst Message-ID: Author: georg.brandl Date: Sun Dec 20 15:24:06 2009 New Revision: 76923 Log: #7493: more review fixes. Modified: python/branches/py3k/Doc/faq/design.rst Modified: python/branches/py3k/Doc/faq/design.rst ============================================================================== --- python/branches/py3k/Doc/faq/design.rst (original) +++ python/branches/py3k/Doc/faq/design.rst Sun Dec 20 15:24:06 2009 @@ -7,7 +7,7 @@ Guido van Rossum believes that using indentation for grouping is extremely elegant and contributes a lot to the clarity of the average Python program. -Most people learn to love this feature after awhile. +Most people learn to love this feature after a while. Since there are no begin/end brackets there cannot be a disagreement between grouping perceived by the parser and the human reader. Occasionally C @@ -48,7 +48,7 @@ People are often very surprised by results like this:: - >>> 1.2-1.0 + >>> 1.2 - 1.0 0.199999999999999996 and think it is a bug in Python. It's not. This has nothing to do with Python, @@ -85,7 +85,7 @@ ``==`` fails. Instead, you have to check that the difference between the two numbers is less than a certain threshold:: - epsilon = 0.0000000000001 # Tiny allowed error + epsilon = 0.0000000000001 # Tiny allowed error expected_result = 0.4 if expected_result-epsilon <= computation() <= expected_result+epsilon: @@ -131,24 +131,25 @@ Second, it means that no special syntax is necessary if you want to explicitly reference or call the method from a particular class. In C++, if you want to use a method from a base class which is overridden in a derived class, you have -to use the ``::`` operator -- in Python you can write baseclass.methodname(self, -). This is particularly useful for :meth:`__init__` methods, and -in general in cases where a derived class method wants to extend the base class -method of the same name and thus has to call the base class method somehow. +to use the ``::`` operator -- in Python you can write +``baseclass.methodname(self, )``. This is particularly useful +for :meth:`__init__` methods, and in general in cases where a derived class +method wants to extend the base class method of the same name and thus has to +call the base class method somehow. Finally, for instance variables it solves a syntactic problem with assignment: since local variables in Python are (by definition!) those variables to which a -value assigned in a function body (and that aren't explicitly declared global), -there has to be some way to tell the interpreter that an assignment was meant to -assign to an instance variable instead of to a local variable, and it should -preferably be syntactic (for efficiency reasons). C++ does this through +value is assigned in a function body (and that aren't explicitly declared +global), there has to be some way to tell the interpreter that an assignment was +meant to assign to an instance variable instead of to a local variable, and it +should preferably be syntactic (for efficiency reasons). C++ does this through declarations, but Python doesn't have declarations and it would be a pity having -to introduce them just for this purpose. Using the explicit "self.var" solves +to introduce them just for this purpose. Using the explicit ``self.var`` solves this nicely. Similarly, for using instance variables, having to write -"self.var" means that references to unqualified names inside a method don't have -to search the instance's directories. To put it another way, local variables -and instance variables live in two different namespaces, and you need to tell -Python which namespace to use. +``self.var`` means that references to unqualified names inside a method don't +have to search the instance's directories. To put it another way, local +variables and instance variables live in two different namespaces, and you need +to tell Python which namespace to use. Why can't I use an assignment in an expression? @@ -271,26 +272,13 @@ "1, 2, 4, 8, 16".split(", ") is an instruction to a string literal to return the substrings delimited by the -given separator (or, by default, arbitrary runs of white space). In this case a -Unicode string returns a list of Unicode strings, an ASCII string returns a list -of ASCII strings, and everyone is happy. +given separator (or, by default, arbitrary runs of white space). :meth:`~str.join` is a string method because in using it you are telling the separator string to iterate over a sequence of strings and insert itself between adjacent elements. This method can be used with any argument which obeys the rules for sequence objects, including any new classes you might define yourself. - -Because this is a string method it can work for Unicode strings as well as plain -ASCII strings. If ``join()`` were a method of the sequence types then the -sequence types would have to decide which type of string to return depending on -the type of the separator. - -.. XXX remove next paragraph eventually - -If none of these arguments persuade you, then for the moment you can continue to -use the ``join()`` function from the string module, which allows you to write :: - - string.join(['1', '2', '4', '8', '16'], ", ") +Similar methods exist for bytes and bytearray objects. How fast are exceptions? @@ -300,19 +288,19 @@ expensive. In versions of Python prior to 2.0 it was common to use this idiom:: try: - value = dict[key] + value = mydict[key] except KeyError: - dict[key] = getvalue(key) - value = dict[key] + mydict[key] = getvalue(key) + value = mydict[key] This only made sense when you expected the dict to have the key almost all the time. If that wasn't the case, you coded it like this:: - if key in dict(key): - value = dict[key] + if mydict.has_key(key): + value = mydict[key] else: - dict[key] = getvalue(key) - value = dict[key] + mydict[key] = getvalue(key) + value = mydict[key] For this specific case, you could also use ``value = dict.setdefault(key, getvalue(key))``, but only if the ``getvalue()`` call is cheap enough because it @@ -393,7 +381,7 @@ ----------------------------------------------------------------- Not easily. Python's high level data types, dynamic typing of objects and -run-time invocation of the interpreter (using :func:`eval` or :keyword:`exec`) +run-time invocation of the interpreter (using :func:`eval` or :func:`exec`) together mean that a "compiled" Python program would probably consist mostly of calls into the Python run-time system, even for seemingly simple operations like ``x+1``. @@ -435,7 +423,7 @@ `_, `PyInline `_, `Py2Cmod `_, and `Weave -`_. +`_. How does Python manage memory? @@ -453,19 +441,20 @@ difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation. -Sometimes objects get stuck in tracebacks temporarily and hence are not -deallocated when you might expect. Clear the tracebacks with:: +.. XXX relevant for Python 3? - import sys - sys.exc_clear() - sys.exc_traceback = sys.last_traceback = None - -Tracebacks are used for reporting errors, implementing debuggers and related -things. They contain a portion of the program state extracted during the -handling of an exception (usually the most recent exception). + Sometimes objects get stuck in traceback temporarily and hence are not + deallocated when you might expect. Clear the traceback with:: -In the absence of circularities and tracebacks, Python programs need not -explicitly manage memory. + import sys + sys.last_traceback = None + + Tracebacks are used for reporting errors, implementing debuggers and related + things. They contain a portion of the program state extracted during the + handling of an exception (usually the most recent exception). + +In the absence of circularities, Python programs do not need to manage memory +explicitly. Why doesn't Python use a more traditional garbage collection scheme? For one thing, this is not a C standard feature and hence it's not portable. (Yes, we @@ -484,19 +473,19 @@ In Jython, the following code (which is fine in CPython) will probably run out of file descriptors long before it runs out of memory:: - for file in : + for file in very_long_list_of_files: f = open(file) c = f.read(1) Using the current reference counting and destructor scheme, each new assignment to f closes the previous file. Using GC, this is not guaranteed. If you want to write code that will work with any Python implementation, you should -explicitly close the file; this will work regardless of GC:: +explicitly close the file or use the :keyword:`with` statement; this will work +regardless of GC:: - for file in : - f = open(file) - c = f.read(1) - f.close() + for file in very_long_list_of_files: + with open(file) as f: + c = f.read(1) Why isn't all memory freed when Python exits? @@ -592,10 +581,10 @@ - Hash lists by their address (object ID). This doesn't work because if you construct a new list with the same value it won't be found; e.g.:: - d = {[1,2]: '12'} - print d[[1,2]] + mydict = {[1, 2]: '12'} + print(mydict[[1, 2]]) - would raise a KeyError exception because the id of the ``[1,2]`` used in the + would raise a KeyError exception because the id of the ``[1, 2]`` used in the second line differs from that in the first line. In other words, dictionary keys should be compared using ``==``, not using :keyword:`is`. @@ -616,7 +605,7 @@ There is a trick to get around this if you need to, but use it at your own risk: You can wrap a mutable structure inside a class instance which has both a -:meth:`__cmp_` and a :meth:`__hash__` method. You must then make sure that the +:meth:`__eq__` and a :meth:`__hash__` method. You must then make sure that the hash value for all such wrapper objects that reside in a dictionary (or other hash based structure), remain fixed while the object is in the dictionary (or other structure). :: @@ -624,15 +613,15 @@ class ListWrapper: def __init__(self, the_list): self.the_list = the_list - def __cmp__(self, other): + def __eq__(self, other): return self.the_list == other.the_list def __hash__(self): l = self.the_list result = 98767 - len(l)*555 - for i in range(len(l)): + for i, el in enumerate(l): try: - result = result + (hash(l[i]) % 9999999) * 1001 + i - except: + result = result + (hash(el) % 9999999) * 1001 + i + except Exception: result = (result % 7777777) + i * 333 return result @@ -640,8 +629,8 @@ members of the list may be unhashable and also by the possibility of arithmetic overflow. -Furthermore it must always be the case that if ``o1 == o2`` (ie ``o1.__cmp__(o2) -== 0``) then ``hash(o1) == hash(o2)`` (ie, ``o1.__hash__() == o2.__hash__()``), +Furthermore it must always be the case that if ``o1 == o2`` (ie ``o1.__eq__(o2) +is True``) then ``hash(o1) == hash(o2)`` (ie, ``o1.__hash__() == o2.__hash__()``), regardless of whether the object is in a dictionary or not. If you fail to meet these restrictions dictionaries and other hash based structures will misbehave. @@ -664,8 +653,8 @@ creates a new list from a provided iterable, sorts it and returns it. For example, here's how to iterate over the keys of a dictionary in sorted order:: - for key in sorted(dict.iterkeys()): - ... # do whatever with dict[key]... + for key in sorted(mydict): + ... # do whatever with mydict[key]... How do you specify and enforce an interface spec in Python? @@ -714,14 +703,14 @@ This type of bug commonly bites neophyte programmers. Consider this function:: - def foo(D={}): # Danger: shared reference to one dict for all calls + def foo(mydict={}): # Danger: shared reference to one dict for all calls ... compute something ... - D[key] = value - return D + mydict[key] = value + return mydict -The first time you call this function, ``D`` contains a single item. The second -time, ``D`` contains two items because when ``foo()`` begins executing, ``D`` -starts out with an item already in it. +The first time you call this function, ``mydict`` contains a single item. The +second time, ``mydict`` contains two items because when ``foo()`` begins +executing, ``mydict`` starts out with an item already in it. It is often expected that a function call creates new objects for default values. This is not what happens. Default values are created exactly once, when @@ -737,14 +726,14 @@ inside the function, check if the parameter is ``None`` and create a new list/dictionary/whatever if it is. For example, don't write:: - def foo(dict={}): + def foo(mydict={}): ... but:: - def foo(dict=None): - if dict is None: - dict = {} # create a new dict for local namespace + def foo(mydict=None): + if mydict is None: + mydict = {} # create a new dict for local namespace This feature can be useful. When you have a function that's time-consuming to compute, a common technique is to cache the parameters and the resulting value @@ -773,13 +762,13 @@ reasonable uses of the "go" or "goto" constructs of C, Fortran, and other languages. For example:: - class label: pass # declare a label + class label: pass # declare a label try: ... - if (condition): raise label() # goto label + if (condition): raise label() # goto label ... - except label: # where to goto + except label: # where to goto pass ... @@ -804,7 +793,7 @@ If you're trying to build Windows pathnames, note that all Windows system calls accept forward slashes too:: - f = open("/mydir/file.txt") # works fine! + f = open("/mydir/file.txt") # works fine! If you're trying to build a pathname for a DOS command, try e.g. one of :: @@ -841,7 +830,7 @@ def foo(a): with a: - print x + print(x) The snippet assumes that "a" must have a member attribute called "x". However, there is nothing in Python that tells the interpreter this. What should happen @@ -852,21 +841,20 @@ The primary benefit of "with" and similar language features (reduction of code volume) can, however, easily be achieved in Python by assignment. Instead of:: - function(args).dict[index][index].a = 21 - function(args).dict[index][index].b = 42 - function(args).dict[index][index].c = 63 + function(args).mydict[index][index].a = 21 + function(args).mydict[index][index].b = 42 + function(args).mydict[index][index].c = 63 write this:: - ref = function(args).dict[index][index] + ref = function(args).mydict[index][index] ref.a = 21 ref.b = 42 ref.c = 63 This also has the side-effect of increasing execution speed because name bindings are resolved at run-time in Python, and the second version only needs -to perform the resolution once. If the referenced object does not have a, b and -c attributes, of course, the end result is still a run-time exception. +to perform the resolution once. Why are colons required for the if/while/def/class statements? @@ -876,12 +864,12 @@ the experimental ABC language). Consider this:: if a == b - print a + print(a) versus :: if a == b: - print a + print(a) Notice how the second one is slightly easier to read. Notice further how a colon sets off the example in this FAQ answer; it's a standard usage in English. From python-checkins at python.org Sun Dec 20 15:28:06 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 20 Dec 2009 14:28:06 -0000 Subject: [Python-checkins] r76924 - python/trunk/Doc/faq/design.rst Message-ID: Author: georg.brandl Date: Sun Dec 20 15:28:05 2009 New Revision: 76924 Log: Small indentation fix. Modified: python/trunk/Doc/faq/design.rst Modified: python/trunk/Doc/faq/design.rst ============================================================================== --- python/trunk/Doc/faq/design.rst (original) +++ python/trunk/Doc/faq/design.rst Sun Dec 20 15:28:05 2009 @@ -825,7 +825,7 @@ looks like this:: with obj: - a = 1 # equivalent to obj.a = 1 + a = 1 # equivalent to obj.a = 1 total = total + 1 # obj.total = obj.total + 1 In Python, such a construct would be ambiguous. From python-checkins at python.org Sun Dec 20 15:33:21 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 20 Dec 2009 14:33:21 -0000 Subject: [Python-checkins] r76925 - in python/trunk: Doc/library/subprocess.rst Lib/subprocess.py Message-ID: Author: georg.brandl Date: Sun Dec 20 15:33:20 2009 New Revision: 76925 Log: #7381: subprocess documentation and library docstring consistency fixes. Modified: python/trunk/Doc/library/subprocess.rst python/trunk/Lib/subprocess.py Modified: python/trunk/Doc/library/subprocess.rst ============================================================================== --- python/trunk/Doc/library/subprocess.rst (original) +++ python/trunk/Doc/library/subprocess.rst Sun Dec 20 15:33:20 2009 @@ -126,9 +126,10 @@ .. note:: - This feature is only available if Python is built with universal newline support - (the default). Also, the newlines attribute of the file objects :attr:`stdout`, - :attr:`stdin` and :attr:`stderr` are not updated by the communicate() method. + This feature is only available if Python is built with universal newline + support (the default). Also, the newlines attribute of the file objects + :attr:`stdout`, :attr:`stdin` and :attr:`stderr` are not updated by the + communicate() method. The *startupinfo* and *creationflags*, if given, will be passed to the underlying CreateProcess() function. They can specify things such as appearance @@ -162,7 +163,7 @@ The arguments are the same as for the Popen constructor. Example:: - retcode = call(["ls", "-l"]) + >>> retcode = subprocess.call(["ls", "-l"]) .. warning:: @@ -181,7 +182,8 @@ The arguments are the same as for the Popen constructor. Example:: - check_call(["ls", "-l"]) + >>> subprocess.check_call(["ls", "-l"]) + 0 .. versionadded:: 2.5 @@ -208,8 +210,8 @@ To capture standard error in the result, use ``stderr=subprocess.STDOUT``:: >>> subprocess.check_output( - ["/bin/sh", "-c", "ls non_existent_file ; exit 0"], - stderr=subprocess.STDOUT) + ... ["/bin/sh", "-c", "ls non_existent_file; exit 0"], + ... stderr=subprocess.STDOUT) 'ls: non_existent_file: No such file or directory\n' .. versionadded:: 2.7 Modified: python/trunk/Lib/subprocess.py ============================================================================== --- python/trunk/Lib/subprocess.py (original) +++ python/trunk/Lib/subprocess.py Sun Dec 20 15:33:20 2009 @@ -128,15 +128,15 @@ check_call(["ls", "-l"]) check_output(*popenargs, **kwargs): - Run command with arguments and return its output as a byte string. + Run command with arguments and return its output as a byte string. - If the exit code was non-zero it raises a CalledProcessError. The - CalledProcessError object will have the return code in the returncode - attribute and output in the output attribute. + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the returncode + attribute and output in the output attribute. - The arguments are the same as for the Popen constructor. Example: + The arguments are the same as for the Popen constructor. Example: - output = subprocess.check_output(["ls", "-l", "/dev/null"]) + output = subprocess.check_output(["ls", "-l", "/dev/null"]) Exceptions ---------- @@ -505,7 +505,7 @@ def check_output(*popenargs, **kwargs): - """Run command with arguments and return its output as a byte string. + r"""Run command with arguments and return its output as a byte string. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode @@ -520,8 +520,8 @@ To capture standard error in the result, use stderr=subprocess.STDOUT. >>> check_output(["/bin/sh", "-c", - "ls -l non_existent_file ; exit 0"], - stderr=subprocess.STDOUT) + ... "ls -l non_existent_file ; exit 0"], + ... stderr=subprocess.STDOUT) 'ls: non_existent_file: No such file or directory\n' """ if 'stdout' in kwargs: From python-checkins at python.org Sun Dec 20 15:38:24 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 20 Dec 2009 14:38:24 -0000 Subject: [Python-checkins] r76926 - in python/branches/py3k: Doc/library/subprocess.rst Lib/subprocess.py Message-ID: Author: georg.brandl Date: Sun Dec 20 15:38:23 2009 New Revision: 76926 Log: Recorded merge of revisions 76925 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76925 | georg.brandl | 2009-12-20 15:33:20 +0100 (So, 20 Dez 2009) | 1 line #7381: subprocess documentation and library docstring consistency fixes. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/subprocess.rst python/branches/py3k/Lib/subprocess.py Modified: python/branches/py3k/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k/Doc/library/subprocess.rst (original) +++ python/branches/py3k/Doc/library/subprocess.rst Sun Dec 20 15:38:23 2009 @@ -105,10 +105,9 @@ .. note:: - 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`. + 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 @@ -157,7 +156,7 @@ The arguments are the same as for the Popen constructor. Example:: - retcode = call(["ls", "-l"]) + >>> retcode = subprocess.call(["ls", "-l"]) .. warning:: @@ -176,7 +175,8 @@ The arguments are the same as for the Popen constructor. Example:: - check_call(["ls", "-l"]) + >>> subprocess.check_call(["ls", "-l"]) + 0 .. warning:: @@ -195,15 +195,15 @@ 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' + b'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``:: >>> subprocess.check_output( - ["/bin/sh", "-c", "ls non_existent_file ; exit 0"], - stderr=subprocess.STDOUT) - 'ls: non_existent_file: No such file or directory\n' + ... ["/bin/sh", "-c", "ls non_existent_file; exit 0"], + ... stderr=subprocess.STDOUT) + b'ls: non_existent_file: No such file or directory\n' .. versionadded:: 3.1 @@ -217,7 +217,6 @@ stripped from the output. The exit status for the command can be interpreted according to the rules for the C function :cfunc:`wait`. Example:: - >>> import subprocess >>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') >>> subprocess.getstatusoutput('cat /bin/junk') @@ -234,7 +233,6 @@ Like :func:`getstatusoutput`, except the exit status is ignored and the return value is a string containing the command's output. Example:: - >>> import subprocess >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' Modified: python/branches/py3k/Lib/subprocess.py ============================================================================== --- python/branches/py3k/Lib/subprocess.py (original) +++ python/branches/py3k/Lib/subprocess.py Sun Dec 20 15:38:23 2009 @@ -110,7 +110,7 @@ The arguments are the same as for the Popen constructor. Example: - retcode = call(["ls", "-l"]) + >>> retcode = call(["ls", "-l"]) check_call(*popenargs, **kwargs): Run command with arguments. Wait for command to complete. If the @@ -120,7 +120,8 @@ The arguments are the same as for the Popen constructor. Example: - check_call(["ls", "-l"]) + >>> check_call(["ls", "-l"]) + 0 getstatusoutput(cmd): Return (status, output) of executing cmd in a shell. @@ -131,7 +132,6 @@ is stripped from the output. The exit status for the command can be interpreted according to the rules for the C function wait(). Example: - >>> import subprocess >>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') >>> subprocess.getstatusoutput('cat /bin/junk') @@ -145,20 +145,19 @@ Like getstatusoutput(), except the exit status is ignored and the return value is a string containing the command's output. Example: - >>> import subprocess >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' check_output(*popenargs, **kwargs): - Run command with arguments and return its output as a byte string. + Run command with arguments and return its output as a byte string. - If the exit code was non-zero it raises a CalledProcessError. The - CalledProcessError object will have the return code in the returncode - attribute and output in the output attribute. + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the returncode + attribute and output in the output attribute. - The arguments are the same as for the Popen constructor. Example: + The arguments are the same as for the Popen constructor. Example: - output = subprocess.check_output(["ls", "-l", "/dev/null"]) + >>> output = subprocess.check_output(["ls", "-l", "/dev/null"]) Exceptions @@ -438,7 +437,7 @@ def check_output(*popenargs, **kwargs): - """Run command with arguments and return its output as a byte string. + r"""Run command with arguments and return its output as a byte string. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode @@ -447,15 +446,15 @@ The arguments are the same as for the Popen constructor. Example: >>> check_output(["ls", "-l", "/dev/null"]) - 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' + b'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. >>> check_output(["/bin/sh", "-c", - "ls -l non_existent_file ; exit 0"], - stderr=subprocess.STDOUT) - 'ls: non_existent_file: No such file or directory\n' + ... "ls -l non_existent_file ; exit 0"], + ... stderr=subprocess.STDOUT) + b'ls: non_existent_file: No such file or directory\n' """ if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be overridden.') From python-checkins at python.org Sun Dec 20 16:23:22 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 20 Dec 2009 15:23:22 -0000 Subject: [Python-checkins] r76927 - python/trunk/Doc/library/future_builtins.rst Message-ID: Author: benjamin.peterson Date: Sun Dec 20 16:23:22 2009 New Revision: 76927 Log: builtin-ins -> builtins 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 Sun Dec 20 16:23:22 2009 @@ -1,5 +1,5 @@ -:mod:`future_builtins` --- Python 3 built-ins -============================================= +:mod:`future_builtins` --- Python 3 builtins +============================================ .. module:: future_builtins .. sectionauthor:: Georg Brandl @@ -8,7 +8,7 @@ This module provides functions that exist in 2.x, but have different behavior in Python 3, so they cannot be put into the 2.x builtins namespace. -Instead, if you want to write code compatible with Python 3 built-ins, import +Instead, if you want to write code compatible with Python 3 builtins, import them from this module, like this:: from future_builtins import map, filter @@ -16,17 +16,17 @@ ... code using Python 3-style map and filter ... The :term:`2to3` tool that ports Python 2 code to Python 3 will recognize -this usage and leave the new built-ins alone. +this usage and leave the new builtins alone. .. note:: - The Python 3 :func:`print` function is already in the built-ins, but cannot be + The Python 3 :func:`print` function is already in the builtins, but cannot be accessed from Python 2 code unless you use the appropriate future statement:: from __future__ import print_function -Available built-ins are: +Available builtins are: .. function:: ascii(object) From python-checkins at python.org Sun Dec 20 16:24:33 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 20 Dec 2009 15:24:33 -0000 Subject: [Python-checkins] r76928 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Sun Dec 20 16:24:32 2009 New Revision: 76928 Log: Blocked revisions 76927 via svnmerge ........ r76927 | benjamin.peterson | 2009-12-20 09:23:22 -0600 (Sun, 20 Dec 2009) | 1 line builtin-ins -> builtins ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Dec 20 16:25:18 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 20 Dec 2009 15:25:18 -0000 Subject: [Python-checkins] r76929 - in python/branches/release26-maint: Doc/library/future_builtins.rst Message-ID: Author: benjamin.peterson Date: Sun Dec 20 16:25:18 2009 New Revision: 76929 Log: Merged revisions 76927 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76927 | benjamin.peterson | 2009-12-20 09:23:22 -0600 (Sun, 20 Dec 2009) | 1 line builtin-ins -> builtins ........ 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 Sun Dec 20 16:25:18 2009 @@ -1,5 +1,5 @@ -:mod:`future_builtins` --- Python 3 built-ins -============================================= +:mod:`future_builtins` --- Python 3 builtins +============================================ .. module:: future_builtins .. sectionauthor:: Georg Brandl @@ -8,7 +8,7 @@ This module provides functions that exist in 2.x, but have different behavior in Python 3, so they cannot be put into the 2.x builtins namespace. -Instead, if you want to write code compatible with Python 3 built-ins, import +Instead, if you want to write code compatible with Python 3 builtins, import them from this module, like this:: from future_builtins import map, filter @@ -16,17 +16,17 @@ ... code using Python 3-style map and filter ... The :term:`2to3` tool that ports Python 2 code to Python 3 will recognize -this usage and leave the new built-ins alone. +this usage and leave the new builtins alone. .. note:: - The Python 3 :func:`print` function is already in the built-ins, but cannot be + The Python 3 :func:`print` function is already in the builtins, but cannot be accessed from Python 2 code unless you use the appropriate future statement:: from __future__ import print_function -Available built-ins are: +Available builtins are: .. function:: ascii(object) From python-checkins at python.org Sun Dec 20 16:57:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 15:57:56 -0000 Subject: [Python-checkins] r76930 - in python/trunk: Lib/test/test_getargs2.py Modules/_testcapimodule.c Message-ID: Author: mark.dickinson Date: Sun Dec 20 16:57:56 2009 New Revision: 76930 Log: Add missing tests for PyArg_Parse* with format 'h' Modified: python/trunk/Lib/test/test_getargs2.py python/trunk/Modules/_testcapimodule.c Modified: python/trunk/Lib/test/test_getargs2.py ============================================================================== --- python/trunk/Lib/test/test_getargs2.py (original) +++ python/trunk/Lib/test/test_getargs2.py Sun Dec 20 16:57:56 2009 @@ -48,7 +48,8 @@ VERY_LARGE = 0xFF0000121212121212121242L from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, INT_MAX, \ - INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \ + SHRT_MIN, SHRT_MAX # fake, they are not defined in Python's header files LLONG_MAX = 2**63-1 @@ -150,6 +151,22 @@ self.assertEqual(VERY_LARGE & ULONG_MAX, getargs_k(VERY_LARGE)) class Signed_TestCase(unittest.TestCase): + def test_h(self): + from _testcapi import getargs_h + # h returns 'short', and does range checking (SHRT_MIN ... SHRT_MAX) + self.assertEqual(3, getargs_h(3.14)) + self.assertEqual(99, getargs_h(Long())) + self.assertEqual(99, getargs_h(Int())) + + self.assertRaises(OverflowError, getargs_h, SHRT_MIN-1) + self.assertEqual(SHRT_MIN, getargs_h(SHRT_MIN)) + self.assertEqual(SHRT_MAX, getargs_h(SHRT_MAX)) + self.assertRaises(OverflowError, getargs_h, SHRT_MAX+1) + + self.assertEqual(42, getargs_h(42)) + self.assertEqual(42, getargs_h(42L)) + self.assertRaises(OverflowError, getargs_h, VERY_LARGE) + def test_i(self): from _testcapi import getargs_i # i returns 'int', and does range checking (INT_MIN ... INT_MAX) Modified: python/trunk/Modules/_testcapimodule.c ============================================================================== --- python/trunk/Modules/_testcapimodule.c (original) +++ python/trunk/Modules/_testcapimodule.c Sun Dec 20 16:57:56 2009 @@ -454,6 +454,15 @@ } static PyObject * +getargs_h(PyObject *self, PyObject *args) +{ + short value; + if (!PyArg_ParseTuple(args, "h", &value)) + return NULL; + return PyLong_FromLong((long)value); +} + +static PyObject * getargs_H(PyObject *self, PyObject *args) { unsigned short value; @@ -1045,6 +1054,7 @@ METH_VARARGS|METH_KEYWORDS}, {"getargs_b", getargs_b, METH_VARARGS}, {"getargs_B", getargs_B, METH_VARARGS}, + {"getargs_h", getargs_h, METH_VARARGS}, {"getargs_H", getargs_H, METH_VARARGS}, {"getargs_I", getargs_I, METH_VARARGS}, {"getargs_k", getargs_k, METH_VARARGS}, From python-checkins at python.org Sun Dec 20 17:03:30 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 16:03:30 -0000 Subject: [Python-checkins] r76931 - in python/branches/py3k: Lib/test/test_getargs2.py Modules/_testcapimodule.c Message-ID: Author: mark.dickinson Date: Sun Dec 20 17:03:30 2009 New Revision: 76931 Log: Merged revisions 76930 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76930 | mark.dickinson | 2009-12-20 15:57:56 +0000 (Sun, 20 Dec 2009) | 1 line Add missing tests for PyArg_Parse* with format 'h' ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_getargs2.py python/branches/py3k/Modules/_testcapimodule.c Modified: python/branches/py3k/Lib/test/test_getargs2.py ============================================================================== --- python/branches/py3k/Lib/test/test_getargs2.py (original) +++ python/branches/py3k/Lib/test/test_getargs2.py Sun Dec 20 17:03:30 2009 @@ -48,7 +48,8 @@ VERY_LARGE = 0xFF0000121212121212121242 from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, INT_MAX, \ - INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \ + SHRT_MIN, SHRT_MAX # fake, they are not defined in Python's header files LLONG_MAX = 2**63-1 @@ -135,6 +136,20 @@ self.assertEqual(VERY_LARGE & ULONG_MAX, getargs_k(VERY_LARGE)) class Signed_TestCase(unittest.TestCase): + def test_h(self): + from _testcapi import getargs_h + # h returns 'short', and does range checking (SHRT_MIN ... SHRT_MAX) + self.assertRaises(TypeError, getargs_h, 3.14) + self.assertEqual(99, getargs_h(Int())) + + self.assertRaises(OverflowError, getargs_h, SHRT_MIN-1) + self.assertEqual(SHRT_MIN, getargs_h(SHRT_MIN)) + self.assertEqual(SHRT_MAX, getargs_h(SHRT_MAX)) + self.assertRaises(OverflowError, getargs_h, SHRT_MAX+1) + + self.assertEqual(42, getargs_h(42)) + self.assertRaises(OverflowError, getargs_h, VERY_LARGE) + def test_i(self): from _testcapi import getargs_i # i returns 'int', and does range checking (INT_MIN ... INT_MAX) Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Sun Dec 20 17:03:30 2009 @@ -455,6 +455,15 @@ } static PyObject * +getargs_h(PyObject *self, PyObject *args) +{ + short value; + if (!PyArg_ParseTuple(args, "h", &value)) + return NULL; + return PyLong_FromLong((long)value); +} + +static PyObject * getargs_H(PyObject *self, PyObject *args) { unsigned short value; @@ -1566,6 +1575,7 @@ METH_VARARGS|METH_KEYWORDS}, {"getargs_b", getargs_b, METH_VARARGS}, {"getargs_B", getargs_B, METH_VARARGS}, + {"getargs_h", getargs_h, METH_VARARGS}, {"getargs_H", getargs_H, METH_VARARGS}, {"getargs_I", getargs_I, METH_VARARGS}, {"getargs_k", getargs_k, METH_VARARGS}, From python-checkins at python.org Sun Dec 20 17:04:11 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 16:04:11 -0000 Subject: [Python-checkins] r76932 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sun Dec 20 17:04:10 2009 New Revision: 76932 Log: Blocked revisions 76930 via svnmerge ........ r76930 | mark.dickinson | 2009-12-20 15:57:56 +0000 (Sun, 20 Dec 2009) | 1 line Add missing tests for PyArg_Parse* with format 'h' ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 20 17:04:37 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 16:04:37 -0000 Subject: [Python-checkins] r76933 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Dec 20 17:04:37 2009 New Revision: 76933 Log: Blocked revisions 76931 via svnmerge ................ r76931 | mark.dickinson | 2009-12-20 16:03:30 +0000 (Sun, 20 Dec 2009) | 9 lines Merged revisions 76930 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76930 | mark.dickinson | 2009-12-20 15:57:56 +0000 (Sun, 20 Dec 2009) | 1 line Add missing tests for PyArg_Parse* with format 'h' ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Dec 20 17:24:46 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 20 Dec 2009 16:24:46 -0000 Subject: [Python-checkins] r76934 - python/trunk/Lib/runpy.py Message-ID: Author: r.david.murray Date: Sun Dec 20 17:24:46 2009 New Revision: 76934 Log: Fix comment typo. Modified: python/trunk/Lib/runpy.py Modified: python/trunk/Lib/runpy.py ============================================================================== --- python/trunk/Lib/runpy.py (original) +++ python/trunk/Lib/runpy.py Sun Dec 20 17:24:46 2009 @@ -138,7 +138,7 @@ Note that the executed module will have full access to the __main__ namespace. If this is not desirable, the run_module() - function sbould be used to run the module code in a fresh namespace. + function should be used to run the module code in a fresh namespace. At the very least, these variables in __main__ will be overwritten: __name__ From python-checkins at python.org Sun Dec 20 17:46:07 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 20 Dec 2009 16:46:07 -0000 Subject: [Python-checkins] r76935 - in python/trunk: Lib/doctest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sun Dec 20 17:46:06 2009 New Revision: 76935 Log: Issue #7376: When called with no arguments doctest was running a self-test. Because of a change to the way tracebacks are printed, this self-test was failing. The test is run (and passes) during normal regression testing. So instead of running the failing self-test this patch makes doctest emit a usage message. This is better behavior anyway since passing in arguments is the real reason to run doctest as a command. Bug discovery and initial patch by Florent Xicluna. Modified: python/trunk/Lib/doctest.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/doctest.py ============================================================================== --- python/trunk/Lib/doctest.py (original) +++ python/trunk/Lib/doctest.py Sun Dec 20 17:46:06 2009 @@ -2660,27 +2660,31 @@ """, } + def _test(): testfiles = [arg for arg in sys.argv[1:] if arg and arg[0] != '-'] - if testfiles: - for filename in testfiles: - if filename.endswith(".py"): - # It is a module -- insert its dir into sys.path and try to - # import it. If it is part of a package, that possibly won't work - # because of package imports. - dirname, filename = os.path.split(filename) - sys.path.insert(0, dirname) - m = __import__(filename[:-3]) - del sys.path[0] - failures, _ = testmod(m) - else: - failures, _ = testfile(filename, module_relative=False) - if failures: - return 1 - else: - r = unittest.TextTestRunner() - r.run(DocTestSuite()) + if not testfiles: + name = os.path.basename(sys.argv[0]) + if '__loader__' in globals() and name.endswith('.py'): # python -m + name, _ = os.path.splitext(name) + print("usage: {0} [-v] file ...".format(name)) + return 2 + for filename in testfiles: + if filename.endswith(".py"): + # It is a module -- insert its dir into sys.path and try to + # import it. If it is part of a package, that possibly + # won't work because of package imports. + dirname, filename = os.path.split(filename) + sys.path.insert(0, dirname) + m = __import__(filename[:-3]) + del sys.path[0] + failures, _ = testmod(m) + else: + failures, _ = testfile(filename, module_relative=False) + if failures: + return 1 return 0 + if __name__ == "__main__": sys.exit(_test()) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 20 17:46:06 2009 @@ -49,6 +49,9 @@ Tests ----- +- Issue #7376: instead of running a self-test (which was failing) when called + with no arguments, doctest.py now gives a usage message. + - Issue #7396: fix regrtest -s, which was broken by the -j enhancement. - Issue #7498: test_multiprocessing now uses test_support.find_unused_port From python-checkins at python.org Sun Dec 20 18:12:59 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 20 Dec 2009 17:12:59 -0000 Subject: [Python-checkins] r76936 - python/branches/release26-maint Message-ID: Author: r.david.murray Date: Sun Dec 20 18:12:58 2009 New Revision: 76936 Log: Blocked revisions 76934-76935 via svnmerge ........ r76934 | r.david.murray | 2009-12-20 11:24:46 -0500 (Sun, 20 Dec 2009) | 2 lines Fix comment typo. ........ r76935 | r.david.murray | 2009-12-20 11:46:06 -0500 (Sun, 20 Dec 2009) | 10 lines Issue #7376: When called with no arguments doctest was running a self-test. Because of a change to the way tracebacks are printed, this self-test was failing. The test is run (and passes) during normal regression testing. So instead of running the failing self-test this patch makes doctest emit a usage message. This is better behavior anyway since passing in arguments is the real reason to run doctest as a command. Bug discovery and initial patch by Florent Xicluna. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 20 18:28:32 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 20 Dec 2009 17:28:32 -0000 Subject: [Python-checkins] r76937 - in python/branches/py3k: Lib/doctest.py Lib/runpy.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sun Dec 20 18:28:31 2009 New Revision: 76937 Log: Merged revisions 76934-76935 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76934 | r.david.murray | 2009-12-20 11:24:46 -0500 (Sun, 20 Dec 2009) | 2 lines Fix comment typo. ........ r76935 | r.david.murray | 2009-12-20 11:46:06 -0500 (Sun, 20 Dec 2009) | 10 lines Issue #7376: When called with no arguments doctest was running a self-test. Because of a change to the way tracebacks are printed, this self-test was failing. The test is run (and passes) during normal regression testing. So instead of running the failing self-test this patch makes doctest emit a usage message. This is better behavior anyway since passing in arguments is the real reason to run doctest as a command. Bug discovery and initial patch by Florent Xicluna. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/doctest.py python/branches/py3k/Lib/runpy.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/doctest.py ============================================================================== --- python/branches/py3k/Lib/doctest.py (original) +++ python/branches/py3k/Lib/doctest.py Sun Dec 20 18:28:31 2009 @@ -2611,27 +2611,31 @@ """, } + def _test(): testfiles = [arg for arg in sys.argv[1:] if arg and arg[0] != '-'] - if testfiles: - for filename in testfiles: - if filename.endswith(".py"): - # It is a module -- insert its dir into sys.path and try to - # import it. If it is part of a package, that possibly won't work - # because of package imports. - dirname, filename = os.path.split(filename) - sys.path.insert(0, dirname) - m = __import__(filename[:-3]) - del sys.path[0] - failures, _ = testmod(m) - else: - failures, _ = testfile(filename, module_relative=False) - if failures: - return 1 - else: - r = unittest.TextTestRunner() - r.run(DocTestSuite()) + if not testfiles: + name = os.path.basename(sys.argv[0]) + if '__loader__' in globals() and name.endswith('.py'): # python -m + name, _ = os.path.splitext(name) + print("usage: {0} [-v] file ...".format(name)) + return 2 + for filename in testfiles: + if filename.endswith(".py"): + # It is a module -- insert its dir into sys.path and try to + # import it. If it is part of a package, that possibly + # won't work because of package imports. + dirname, filename = os.path.split(filename) + sys.path.insert(0, dirname) + m = __import__(filename[:-3]) + del sys.path[0] + failures, _ = testmod(m) + else: + failures, _ = testfile(filename, module_relative=False) + if failures: + return 1 return 0 + if __name__ == "__main__": sys.exit(_test()) Modified: python/branches/py3k/Lib/runpy.py ============================================================================== --- python/branches/py3k/Lib/runpy.py (original) +++ python/branches/py3k/Lib/runpy.py Sun Dec 20 18:28:31 2009 @@ -125,7 +125,7 @@ Note that the executed module will have full access to the __main__ namespace. If this is not desirable, the run_module() - function sbould be used to run the module code in a fresh namespace. + function should be used to run the module code in a fresh namespace. At the very least, these variables in __main__ will be overwritten: __name__ Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Dec 20 18:28:31 2009 @@ -511,6 +511,9 @@ Tests ----- +- Issue #7376: instead of running a self-test (which was failing) when called + with no arguments, doctest.py now gives a usage message. + - Issue #7396: fix regrtest -s, which was broken by the -j enhancement. - Issue #7498: test_multiprocessing now uses test.support.find_unused_port From python-checkins at python.org Sun Dec 20 18:37:25 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 20 Dec 2009 17:37:25 -0000 Subject: [Python-checkins] r76938 - in python/branches/release31-maint: Lib/doctest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sun Dec 20 18:37:25 2009 New Revision: 76938 Log: Merged revisions 76937 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k r76934 does not apply and was deleted in the merge. ................ r76937 | r.david.murray | 2009-12-20 12:28:31 -0500 (Sun, 20 Dec 2009) | 20 lines Merged revisions 76934-76935 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76934 | r.david.murray | 2009-12-20 11:24:46 -0500 (Sun, 20 Dec 2009) | 2 lines Fix comment typo. ........ r76935 | r.david.murray | 2009-12-20 11:46:06 -0500 (Sun, 20 Dec 2009) | 10 lines Issue #7376: When called with no arguments doctest was running a self-test. Because of a change to the way tracebacks are printed, this self-test was failing. The test is run (and passes) during normal regression testing. So instead of running the failing self-test this patch makes doctest emit a usage message. This is better behavior anyway since passing in arguments is the real reason to run doctest as a command. Bug discovery and initial patch by Florent Xicluna. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/doctest.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/doctest.py ============================================================================== --- python/branches/release31-maint/Lib/doctest.py (original) +++ python/branches/release31-maint/Lib/doctest.py Sun Dec 20 18:37:25 2009 @@ -2611,27 +2611,31 @@ """, } + def _test(): testfiles = [arg for arg in sys.argv[1:] if arg and arg[0] != '-'] - if testfiles: - for filename in testfiles: - if filename.endswith(".py"): - # It is a module -- insert its dir into sys.path and try to - # import it. If it is part of a package, that possibly won't work - # because of package imports. - dirname, filename = os.path.split(filename) - sys.path.insert(0, dirname) - m = __import__(filename[:-3]) - del sys.path[0] - failures, _ = testmod(m) - else: - failures, _ = testfile(filename, module_relative=False) - if failures: - return 1 - else: - r = unittest.TextTestRunner() - r.run(DocTestSuite()) + if not testfiles: + name = os.path.basename(sys.argv[0]) + if '__loader__' in globals() and name.endswith('.py'): # python -m + name, _ = os.path.splitext(name) + print("usage: {0} [-v] file ...".format(name)) + return 2 + for filename in testfiles: + if filename.endswith(".py"): + # It is a module -- insert its dir into sys.path and try to + # import it. If it is part of a package, that possibly + # won't work because of package imports. + dirname, filename = os.path.split(filename) + sys.path.insert(0, dirname) + m = __import__(filename[:-3]) + del sys.path[0] + failures, _ = testmod(m) + else: + failures, _ = testfile(filename, module_relative=False) + if failures: + return 1 return 0 + if __name__ == "__main__": sys.exit(_test()) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Dec 20 18:37:25 2009 @@ -217,6 +217,9 @@ Tests ----- +- Issue #7376: instead of running a self-test (which was failing) when called + with no arguments, doctest.py now gives a usage message. + - Issue #7498: test_multiprocessing now uses test.support.find_unused_port instead of a hardcoded port number in test_rapid_restart. From python-checkins at python.org Sun Dec 20 20:45:38 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 19:45:38 -0000 Subject: [Python-checkins] r76939 - python/trunk/Lib/test/test_cmath.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 20:45:37 2009 New Revision: 76939 Log: Issue #7554: Fix incorrect usage of rAssertAlmostEqual. Thanks Florent Xicluna. Modified: python/trunk/Lib/test/test_cmath.py Modified: python/trunk/Lib/test/test_cmath.py ============================================================================== --- python/trunk/Lib/test/test_cmath.py (original) +++ python/trunk/Lib/test/test_cmath.py Sun Dec 20 20:45:37 2009 @@ -130,9 +130,9 @@ def test_constants(self): e_expected = 2.71828182845904523536 pi_expected = 3.14159265358979323846 - self.rAssertAlmostEqual(cmath.pi, pi_expected, 9, + self.assertAlmostEqual(cmath.pi, pi_expected, 9, "cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) - self.rAssertAlmostEqual(cmath.e, e_expected, 9, + self.assertAlmostEqual(cmath.e, e_expected, 9, "cmath.e is %s; should be %s" % (cmath.e, e_expected)) def test_user_object(self): From python-checkins at python.org Sun Dec 20 20:47:06 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 19:47:06 -0000 Subject: [Python-checkins] r76940 - in python/branches/release26-maint: Lib/test/test_cmath.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 20:47:04 2009 New Revision: 76940 Log: Merged revisions 76939 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76939 | mark.dickinson | 2009-12-20 19:45:37 +0000 (Sun, 20 Dec 2009) | 1 line Issue #7554: Fix incorrect usage of rAssertAlmostEqual. Thanks Florent Xicluna. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_cmath.py Modified: python/branches/release26-maint/Lib/test/test_cmath.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_cmath.py (original) +++ python/branches/release26-maint/Lib/test/test_cmath.py Sun Dec 20 20:47:04 2009 @@ -130,9 +130,9 @@ def test_constants(self): e_expected = 2.71828182845904523536 pi_expected = 3.14159265358979323846 - self.rAssertAlmostEqual(cmath.pi, pi_expected, 9, + self.assertAlmostEqual(cmath.pi, pi_expected, 9, "cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) - self.rAssertAlmostEqual(cmath.e, e_expected, 9, + self.assertAlmostEqual(cmath.e, e_expected, 9, "cmath.e is %s; should be %s" % (cmath.e, e_expected)) def test_user_object(self): From python-checkins at python.org Sun Dec 20 20:52:37 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 19:52:37 -0000 Subject: [Python-checkins] r76941 - python/trunk/Lib/test/test_cmath.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 20:52:36 2009 New Revision: 76941 Log: Fix for consistency with py3k keyword-only version of assertAlmostEqual Modified: python/trunk/Lib/test/test_cmath.py Modified: python/trunk/Lib/test/test_cmath.py ============================================================================== --- python/trunk/Lib/test/test_cmath.py (original) +++ python/trunk/Lib/test/test_cmath.py Sun Dec 20 20:52:36 2009 @@ -130,10 +130,10 @@ def test_constants(self): e_expected = 2.71828182845904523536 pi_expected = 3.14159265358979323846 - self.assertAlmostEqual(cmath.pi, pi_expected, 9, - "cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) - self.assertAlmostEqual(cmath.e, e_expected, 9, - "cmath.e is %s; should be %s" % (cmath.e, e_expected)) + self.assertAlmostEqual(cmath.pi, pi_expected, places=9, + msg="cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) + self.assertAlmostEqual(cmath.e, e_expected, places=9, + msg="cmath.e is %s; should be %s" % (cmath.e, e_expected)) def test_user_object(self): # Test automatic calling of __complex__ and __float__ by cmath From python-checkins at python.org Sun Dec 20 20:53:25 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 19:53:25 -0000 Subject: [Python-checkins] r76942 - in python/branches/release26-maint: Lib/test/test_cmath.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 20:53:25 2009 New Revision: 76942 Log: Merged revisions 76941 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76941 | mark.dickinson | 2009-12-20 19:52:36 +0000 (Sun, 20 Dec 2009) | 1 line Fix for consistency with py3k keyword-only version of assertAlmostEqual ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_cmath.py Modified: python/branches/release26-maint/Lib/test/test_cmath.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_cmath.py (original) +++ python/branches/release26-maint/Lib/test/test_cmath.py Sun Dec 20 20:53:25 2009 @@ -130,10 +130,10 @@ def test_constants(self): e_expected = 2.71828182845904523536 pi_expected = 3.14159265358979323846 - self.assertAlmostEqual(cmath.pi, pi_expected, 9, - "cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) - self.assertAlmostEqual(cmath.e, e_expected, 9, - "cmath.e is %s; should be %s" % (cmath.e, e_expected)) + self.assertAlmostEqual(cmath.pi, pi_expected, places=9, + msg="cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) + self.assertAlmostEqual(cmath.e, e_expected, places=9, + msg="cmath.e is %s; should be %s" % (cmath.e, e_expected)) def test_user_object(self): # Test automatic calling of __complex__ and __float__ by cmath From python-checkins at python.org Sun Dec 20 20:56:10 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 19:56:10 -0000 Subject: [Python-checkins] r76943 - in python/branches/py3k: Lib/test/test_cmath.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 20:56:09 2009 New Revision: 76943 Log: Merged revisions 76939,76941 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76939 | mark.dickinson | 2009-12-20 19:45:37 +0000 (Sun, 20 Dec 2009) | 1 line Issue #7554: Fix incorrect usage of rAssertAlmostEqual. Thanks Florent Xicluna. ........ r76941 | mark.dickinson | 2009-12-20 19:52:36 +0000 (Sun, 20 Dec 2009) | 1 line Fix for consistency with py3k keyword-only version of assertAlmostEqual ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_cmath.py Modified: python/branches/py3k/Lib/test/test_cmath.py ============================================================================== --- python/branches/py3k/Lib/test/test_cmath.py (original) +++ python/branches/py3k/Lib/test/test_cmath.py Sun Dec 20 20:56:09 2009 @@ -130,8 +130,10 @@ def test_constants(self): e_expected = 2.71828182845904523536 pi_expected = 3.14159265358979323846 - self.assertAlmostEqual(cmath.pi, pi_expected) - self.assertAlmostEqual(cmath.e, e_expected) + self.assertAlmostEqual(cmath.pi, pi_expected, places=9, + msg="cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) + self.assertAlmostEqual(cmath.e, e_expected, places=9, + msg="cmath.e is %s; should be %s" % (cmath.e, e_expected)) def test_user_object(self): # Test automatic calling of __complex__ and __float__ by cmath From python-checkins at python.org Sun Dec 20 20:57:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 19:57:24 -0000 Subject: [Python-checkins] r76944 - in python/branches/release31-maint: Lib/test/test_cmath.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 20:57:24 2009 New Revision: 76944 Log: Merged revisions 76943 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76943 | mark.dickinson | 2009-12-20 19:56:09 +0000 (Sun, 20 Dec 2009) | 13 lines Merged revisions 76939,76941 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76939 | mark.dickinson | 2009-12-20 19:45:37 +0000 (Sun, 20 Dec 2009) | 1 line Issue #7554: Fix incorrect usage of rAssertAlmostEqual. Thanks Florent Xicluna. ........ r76941 | mark.dickinson | 2009-12-20 19:52:36 +0000 (Sun, 20 Dec 2009) | 1 line Fix for consistency with py3k keyword-only version of assertAlmostEqual ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_cmath.py Modified: python/branches/release31-maint/Lib/test/test_cmath.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_cmath.py (original) +++ python/branches/release31-maint/Lib/test/test_cmath.py Sun Dec 20 20:57:24 2009 @@ -130,8 +130,10 @@ def test_constants(self): e_expected = 2.71828182845904523536 pi_expected = 3.14159265358979323846 - self.assertAlmostEqual(cmath.pi, pi_expected) - self.assertAlmostEqual(cmath.e, e_expected) + self.assertAlmostEqual(cmath.pi, pi_expected, places=9, + msg="cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) + self.assertAlmostEqual(cmath.e, e_expected, places=9, + msg="cmath.e is %s; should be %s" % (cmath.e, e_expected)) def test_user_object(self): # Test automatic calling of __complex__ and __float__ by cmath From python-checkins at python.org Sun Dec 20 21:23:01 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 20:23:01 -0000 Subject: [Python-checkins] r76945 - python/trunk/Lib/test/test_math.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 21:23:01 2009 New Revision: 76945 Log: Silence -3 warnings. Thanks Florent Xicluna. 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 Sun Dec 20 21:23:01 2009 @@ -433,7 +433,8 @@ def testFrexp(self): self.assertRaises(TypeError, math.frexp) - def testfrexp(name, (mant, exp), (emant, eexp)): + def testfrexp(name, result, expected): + (mant, exp), (emant, eexp) = result, expected if abs(mant-emant) > eps or exp != eexp: self.fail('%s returned %r, expected %r'%\ (name, (mant, exp), (emant,eexp))) @@ -618,7 +619,8 @@ def testModf(self): self.assertRaises(TypeError, math.modf) - def testmodf(name, (v1, v2), (e1, e2)): + def testmodf(name, result, expected): + (v1, v2), (e1, e2) = result, expected if abs(v1-e1) > eps or abs(v2-e2): self.fail('%s returned %r, expected %r'%\ (name, (v1,v2), (e1,e2))) From python-checkins at python.org Sun Dec 20 21:23:50 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 20:23:50 -0000 Subject: [Python-checkins] r76946 - in python/branches/release26-maint: Lib/test/test_math.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 21:23:49 2009 New Revision: 76946 Log: Merged revisions 76945 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76945 | mark.dickinson | 2009-12-20 20:23:01 +0000 (Sun, 20 Dec 2009) | 1 line Silence -3 warnings. Thanks Florent Xicluna. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_math.py Modified: python/branches/release26-maint/Lib/test/test_math.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_math.py (original) +++ python/branches/release26-maint/Lib/test/test_math.py Sun Dec 20 21:23:49 2009 @@ -350,7 +350,8 @@ def testFrexp(self): self.assertRaises(TypeError, math.frexp) - def testfrexp(name, (mant, exp), (emant, eexp)): + def testfrexp(name, result, expected): + (mant, exp), (emant, eexp) = result, expected if abs(mant-emant) > eps or exp != eexp: self.fail('%s returned %r, expected %r'%\ (name, (mant, exp), (emant,eexp))) @@ -540,7 +541,8 @@ def testModf(self): self.assertRaises(TypeError, math.modf) - def testmodf(name, (v1, v2), (e1, e2)): + def testmodf(name, result, expected): + (v1, v2), (e1, e2) = result, expected if abs(v1-e1) > eps or abs(v2-e2): self.fail('%s returned %r, expected %r'%\ (name, (v1,v2), (e1,e2))) From python-checkins at python.org Sun Dec 20 21:24:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 20:24:18 -0000 Subject: [Python-checkins] r76947 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Sun Dec 20 21:24:18 2009 New Revision: 76947 Log: Blocked revisions 76945 via svnmerge ........ r76945 | mark.dickinson | 2009-12-20 20:23:01 +0000 (Sun, 20 Dec 2009) | 1 line Silence -3 warnings. Thanks Florent Xicluna. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Dec 20 21:34:45 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 20:34:45 -0000 Subject: [Python-checkins] r76948 - python/trunk/Lib/test/test_cmath.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 21:34:44 2009 New Revision: 76948 Log: Issue #7554: Various fixups in test_cmath.py: remove code duplication, use new-style formatting. Thanks Florent Xicluna for the patch. Modified: python/trunk/Lib/test/test_cmath.py Modified: python/trunk/Lib/test/test_cmath.py ============================================================================== --- python/trunk/Lib/test/test_cmath.py (original) +++ python/trunk/Lib/test/test_cmath.py Sun Dec 20 21:34:44 2009 @@ -46,37 +46,6 @@ (INF, NAN) ]] -def almostEqualF(a, b, rel_err=2e-15, abs_err = 5e-323): - """Determine whether floating-point values a and b are equal to within - a (small) rounding error. The default values for rel_err and - abs_err are chosen to be suitable for platforms where a float is - represented by an IEEE 754 double. They allow an error of between - 9 and 19 ulps.""" - - # special values testing - if math.isnan(a): - return math.isnan(b) - if math.isinf(a): - return a == b - - # if both a and b are zero, check whether they have the same sign - # (in theory there are examples where it would be legitimate for a - # and b to have opposite signs; in practice these hardly ever - # occur). - if not a and not b: - return math.copysign(1., a) == math.copysign(1., b) - - # if a-b overflows, or b is infinite, return False. Again, in - # theory there are examples where a is within a few ulps of the - # max representable float, and then b could legitimately be - # infinite. In practice these examples are rare. - try: - absolute_error = abs(b-a) - except OverflowError: - return False - else: - return absolute_error <= max(abs_err, rel_err * abs(a)) - class CMathTests(unittest.TestCase): # list of all functions in cmath test_functions = [getattr(cmath, fname) for fname in [ @@ -93,47 +62,63 @@ def tearDown(self): self.test_values.close() - def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323): - """Check that two floating-point numbers are almost equal.""" + def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323, + msg=None): + """Fail if the two floating-point numbers are not almost equal. + + Determine whether floating-point values a and b are equal to within + a (small) rounding error. The default values for rel_err and + abs_err are chosen to be suitable for platforms where a float is + represented by an IEEE 754 double. They allow an error of between + 9 and 19 ulps. + """ # special values testing if math.isnan(a): if math.isnan(b): return - self.fail("%s should be nan" % repr(b)) + self.fail(msg or '{!r} should be nan'.format(b)) if math.isinf(a): if a == b: return - self.fail("finite result where infinity excpected: " - "expected %s, got %s" % (repr(a), repr(b))) + self.fail(msg or 'finite result where infinity expected: ' + 'expected {!r}, got {!r}'.format(a, b)) + # if both a and b are zero, check whether they have the same sign + # (in theory there are examples where it would be legitimate for a + # and b to have opposite signs; in practice these hardly ever + # occur). if not a and not b: - if math.atan2(a, -1.) != math.atan2(b, -1.): - self.fail("zero has wrong sign: expected %s, got %s" % - (repr(a), repr(b))) - - # test passes if either the absolute error or the relative - # error is sufficiently small. The defaults amount to an - # error of between 9 ulps and 19 ulps on an IEEE-754 compliant - # machine. - + if math.copysign(1., a) != math.copysign(1., b): + self.fail(msg or 'zero has wrong sign: expected {!r}, ' + 'got {!r}'.format(a, b)) + + # if a-b overflows, or b is infinite, return False. Again, in + # theory there are examples where a is within a few ulps of the + # max representable float, and then b could legitimately be + # infinite. In practice these examples are rare. try: absolute_error = abs(b-a) except OverflowError: pass else: + # test passes if either the absolute error or the relative + # error is sufficiently small. The defaults amount to an + # error of between 9 ulps and 19 ulps on an IEEE-754 compliant + # machine. if absolute_error <= max(abs_err, rel_err * abs(a)): return - self.fail("%s and %s are not sufficiently close" % (repr(a), repr(b))) + self.fail(msg or + '{!r} and {!r} are not sufficiently close'.format(a, b)) def test_constants(self): e_expected = 2.71828182845904523536 pi_expected = 3.14159265358979323846 self.assertAlmostEqual(cmath.pi, pi_expected, places=9, - msg="cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) + msg="cmath.pi is {}; should be {}".format(cmath.pi, pi_expected)) self.assertAlmostEqual(cmath.e, e_expected, places=9, - msg="cmath.e is %s; should be %s" % (cmath.e, e_expected)) + msg="cmath.e is {}; should be {}".format(cmath.e, e_expected)) def test_user_object(self): # Test automatic calling of __complex__ and __float__ by cmath @@ -325,8 +310,8 @@ except ValueError: continue else: - test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai) - self.fail('ValueError not raised in test %s' % test_str) + self.fail('ValueError not raised in test ' + '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai)) if 'overflow' in flags: try: @@ -334,8 +319,8 @@ except OverflowError: continue else: - test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai) - self.fail('OverflowError not raised in test %s' % test_str) + self.fail('OverflowError not raised in test ' + '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai)) actual = function(arg) @@ -353,17 +338,19 @@ else: real_abs_err = 5e-323 - if not (almostEqualF(expected.real, actual.real, - abs_err = real_abs_err) and - almostEqualF(expected.imag, actual.imag)): - error_message = ( - "%s: %s(complex(%r, %r))\n" % (id, fn, ar, ai) + - "Expected: complex(%r, %r)\n" % - (expected.real, expected.imag) + - "Received: complex(%r, %r)\n" % - (actual.real, actual.imag) + - "Received value insufficiently close to expected value.") - self.fail(error_message) + error_message = ( + '{}: {}(complex({!r}, {!r}))\n' + 'Expected: complex({!r}, {!r})\n' + 'Received: complex({!r}, {!r})\n' + 'Received value insufficiently close to expected value.' + ).format(id, fn, ar, ai, + expected.real, expected.imag, + actual.real, actual.imag) + self.rAssertAlmostEqual(expected.real, actual.real, + abs_err=real_abs_err, + msg=error_message) + self.rAssertAlmostEqual(expected.imag, actual.imag, + msg=error_message) def assertCISEqual(self, a, b): eps = 1E-7 From python-checkins at python.org Sun Dec 20 21:36:34 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 20:36:34 -0000 Subject: [Python-checkins] r76949 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sun Dec 20 21:36:34 2009 New Revision: 76949 Log: Blocked revisions 76948 via svnmerge ........ r76948 | mark.dickinson | 2009-12-20 20:34:44 +0000 (Sun, 20 Dec 2009) | 3 lines Issue #7554: Various fixups in test_cmath.py: remove code duplication, use new-style formatting. Thanks Florent Xicluna for the patch. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 20 21:37:57 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 20:37:57 -0000 Subject: [Python-checkins] r76950 - in python/branches/py3k: Lib/test/test_cmath.py Message-ID: Author: mark.dickinson Date: Sun Dec 20 21:37:56 2009 New Revision: 76950 Log: Merged revisions 76948 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76948 | mark.dickinson | 2009-12-20 20:34:44 +0000 (Sun, 20 Dec 2009) | 3 lines Issue #7554: Various fixups in test_cmath.py: remove code duplication, use new-style formatting. Thanks Florent Xicluna for the patch. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_cmath.py Modified: python/branches/py3k/Lib/test/test_cmath.py ============================================================================== --- python/branches/py3k/Lib/test/test_cmath.py (original) +++ python/branches/py3k/Lib/test/test_cmath.py Sun Dec 20 21:37:56 2009 @@ -46,37 +46,6 @@ (INF, NAN) ]] -def almostEqualF(a, b, rel_err=2e-15, abs_err = 5e-323): - """Determine whether floating-point values a and b are equal to within - a (small) rounding error. The default values for rel_err and - abs_err are chosen to be suitable for platforms where a float is - represented by an IEEE 754 double. They allow an error of between - 9 and 19 ulps.""" - - # special values testing - if math.isnan(a): - return math.isnan(b) - if math.isinf(a): - return a == b - - # if both a and b are zero, check whether they have the same sign - # (in theory there are examples where it would be legitimate for a - # and b to have opposite signs; in practice these hardly ever - # occur). - if not a and not b: - return math.copysign(1., a) == math.copysign(1., b) - - # if a-b overflows, or b is infinite, return False. Again, in - # theory there are examples where a is within a few ulps of the - # max representable float, and then b could legitimately be - # infinite. In practice these examples are rare. - try: - absolute_error = abs(b-a) - except OverflowError: - return False - else: - return absolute_error <= max(abs_err, rel_err * abs(a)) - class CMathTests(unittest.TestCase): # list of all functions in cmath test_functions = [getattr(cmath, fname) for fname in [ @@ -93,47 +62,63 @@ def tearDown(self): self.test_values.close() - def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323): - """Check that two floating-point numbers are almost equal.""" + def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323, + msg=None): + """Fail if the two floating-point numbers are not almost equal. + + Determine whether floating-point values a and b are equal to within + a (small) rounding error. The default values for rel_err and + abs_err are chosen to be suitable for platforms where a float is + represented by an IEEE 754 double. They allow an error of between + 9 and 19 ulps. + """ # special values testing if math.isnan(a): if math.isnan(b): return - self.fail("%s should be nan" % repr(b)) + self.fail(msg or '{!r} should be nan'.format(b)) if math.isinf(a): if a == b: return - self.fail("finite result where infinity excpected: " - "expected %s, got %s" % (repr(a), repr(b))) + self.fail(msg or 'finite result where infinity expected: ' + 'expected {!r}, got {!r}'.format(a, b)) + # if both a and b are zero, check whether they have the same sign + # (in theory there are examples where it would be legitimate for a + # and b to have opposite signs; in practice these hardly ever + # occur). if not a and not b: - if math.atan2(a, -1.) != math.atan2(b, -1.): - self.fail("zero has wrong sign: expected %s, got %s" % - (repr(a), repr(b))) - - # test passes if either the absolute error or the relative - # error is sufficiently small. The defaults amount to an - # error of between 9 ulps and 19 ulps on an IEEE-754 compliant - # machine. - + if math.copysign(1., a) != math.copysign(1., b): + self.fail(msg or 'zero has wrong sign: expected {!r}, ' + 'got {!r}'.format(a, b)) + + # if a-b overflows, or b is infinite, return False. Again, in + # theory there are examples where a is within a few ulps of the + # max representable float, and then b could legitimately be + # infinite. In practice these examples are rare. try: absolute_error = abs(b-a) except OverflowError: pass else: + # test passes if either the absolute error or the relative + # error is sufficiently small. The defaults amount to an + # error of between 9 ulps and 19 ulps on an IEEE-754 compliant + # machine. if absolute_error <= max(abs_err, rel_err * abs(a)): return - self.fail("%s and %s are not sufficiently close" % (repr(a), repr(b))) + self.fail(msg or + '{!r} and {!r} are not sufficiently close'.format(a, b)) def test_constants(self): e_expected = 2.71828182845904523536 pi_expected = 3.14159265358979323846 self.assertAlmostEqual(cmath.pi, pi_expected, places=9, - msg="cmath.pi is %s; should be %s" % (cmath.pi, pi_expected)) + msg="cmath.pi is {}; should be {}".format(cmath.pi, pi_expected)) self.assertAlmostEqual(cmath.e, e_expected, places=9, - msg="cmath.e is %s; should be %s" % (cmath.e, e_expected)) + msg="cmath.e is {}; should be {}".format(cmath.e, e_expected)) def test_user_object(self): # Test automatic calling of __complex__ and __float__ by cmath @@ -323,8 +308,8 @@ except ValueError: continue else: - test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai) - self.fail('ValueError not raised in test %s' % test_str) + self.fail('ValueError not raised in test ' + '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai)) if 'overflow' in flags: try: @@ -332,8 +317,8 @@ except OverflowError: continue else: - test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai) - self.fail('OverflowError not raised in test %s' % test_str) + self.fail('OverflowError not raised in test ' + '{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai)) actual = function(arg) @@ -351,17 +336,19 @@ else: real_abs_err = 5e-323 - if not (almostEqualF(expected.real, actual.real, - abs_err = real_abs_err) and - almostEqualF(expected.imag, actual.imag)): - error_message = ( - "%s: %s(complex(%r, %r))\n" % (id, fn, ar, ai) + - "Expected: complex(%r, %r)\n" % - (expected.real, expected.imag) + - "Received: complex(%r, %r)\n" % - (actual.real, actual.imag) + - "Received value insufficiently close to expected value.") - self.fail(error_message) + error_message = ( + '{}: {}(complex({!r}, {!r}))\n' + 'Expected: complex({!r}, {!r})\n' + 'Received: complex({!r}, {!r})\n' + 'Received value insufficiently close to expected value.' + ).format(id, fn, ar, ai, + expected.real, expected.imag, + actual.real, actual.imag) + self.rAssertAlmostEqual(expected.real, actual.real, + abs_err=real_abs_err, + msg=error_message) + self.rAssertAlmostEqual(expected.imag, actual.imag, + msg=error_message) def assertCISEqual(self, a, b): eps = 1E-7 From python-checkins at python.org Sun Dec 20 21:38:25 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Dec 2009 20:38:25 -0000 Subject: [Python-checkins] r76951 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Dec 20 21:38:25 2009 New Revision: 76951 Log: Blocked revisions 76950 via svnmerge ................ r76950 | mark.dickinson | 2009-12-20 20:37:56 +0000 (Sun, 20 Dec 2009) | 10 lines Merged revisions 76948 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76948 | mark.dickinson | 2009-12-20 20:34:44 +0000 (Sun, 20 Dec 2009) | 3 lines Issue #7554: Various fixups in test_cmath.py: remove code duplication, use new-style formatting. Thanks Florent Xicluna for the patch. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Dec 21 00:23:34 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Dec 2009 23:23:34 -0000 Subject: [Python-checkins] r76952 - in python/trunk: Lib/distutils/command/upload.py Lib/distutils/tests/test_upload.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Mon Dec 21 00:23:34 2009 New Revision: 76952 Log: Fixed #7552: fixed distutils.command.upload failure on very long passwords Modified: python/trunk/Lib/distutils/command/upload.py python/trunk/Lib/distutils/tests/test_upload.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/command/upload.py ============================================================================== --- python/trunk/Lib/distutils/command/upload.py (original) +++ python/trunk/Lib/distutils/command/upload.py Mon Dec 21 00:23:34 2009 @@ -6,7 +6,7 @@ import socket import platform from urllib2 import urlopen, Request, HTTPError -import base64 +from base64 import standard_b64encode import urlparse import cStringIO as StringIO from ConfigParser import ConfigParser @@ -129,8 +129,8 @@ open(filename+".asc").read()) # set up the authentication - auth = "Basic " + base64.encodestring(self.username + ":" + - self.password).strip() + auth = "Basic " + standard_b64encode(self.username + ":" + + self.password) # Build up the MIME payload for the POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' Modified: python/trunk/Lib/distutils/tests/test_upload.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_upload.py (original) +++ python/trunk/Lib/distutils/tests/test_upload.py Mon Dec 21 00:23:34 2009 @@ -10,6 +10,25 @@ from distutils.tests import support from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase +PYPIRC_LONG_PASSWORD = """\ +[distutils] + +index-servers = + server1 + server2 + +[server1] +username:me +password:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +[server2] +username:meagain +password: secret +realm:acme +repository:http://another.pypi/ +""" + + PYPIRC_NOPASSWORD = """\ [distutils] @@ -85,7 +104,7 @@ self.write_file(path) command, pyversion, filename = 'xxx', '2.6', path dist_files = [(command, pyversion, filename)] - self.write_file(self.rc, PYPIRC) + self.write_file(self.rc, PYPIRC_LONG_PASSWORD) # lets run it pkg_dir, dist = self.create_dist(dist_files=dist_files) @@ -101,6 +120,8 @@ self.assertEquals(self.last_open.req.get_full_url(), 'http://pypi.python.org/pypi') self.assertTrue('xxx' in self.last_open.req.data) + auth = self.last_open.req.headers['Authorization'] + self.assertFalse('\n' in auth) def test_suite(): return unittest.makeSuite(uploadTestCase) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Dec 21 00:23:34 2009 @@ -24,7 +24,11 @@ Library ------- -- Issue #7231: urllib2 cannot handle https with proxy requiring auth. +- Issue #7552: Removed line feed in the base64 Authorization header in + the Distutils upload command to avoid an error when PyPI reads it. + This occurs on long passwords. Initial patch by JP St. Pierre. + +- Issue #7231: urllib2 cannot handle https with proxy requiring auth. Patch by Tatsuhiro Tsujikawa. - Issue #7349: Make methods of file objects in the io module accept None as an @@ -42,7 +46,7 @@ - Issue #5949: fixed IMAP4_SSL hang when the IMAP server response is missing proper end-of-line termination. -- Issue #7457: added a read_pkg_file method to +- Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata. @@ -560,7 +564,7 @@ - logging: Added optional `secure` parameter to SMTPHandler, to enable use of TLS with authentication credentials. -- Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is +- Issue #1923: Fixed the removal of meaningful spaces when PKG-INFO is generated in Distutils. Patch by Stephen Emslie. - Issue #4120: Drop reference to CRT from manifest when building extensions with @@ -1764,7 +1768,7 @@ Tests ----- -- Issue #7431: use TESTFN in test_linecache instead of trying to create a +- Issue #7431: use TESTFN in test_linecache instead of trying to create a file in the Lib/test directory, which might be read-only for the user running the tests. From solipsis at pitrou.net Mon Dec 21 00:48:34 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 21 Dec 2009 00:48:34 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76950): sum=18 Message-ID: <20091220234834.DFC8E17759@ns6635.ovh.net> py3k results for svn r76950 (hg cset c9c503f6f2e6) -------------------------------------------------- test_urllib2 leaked [6, 6, 6] references, sum=18 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog1GSpCZ', '-x', 'test_httpservers'] From g.brandl at gmx.net Mon Dec 21 01:48:00 2009 From: g.brandl at gmx.net (Georg Brandl) Date: Mon, 21 Dec 2009 01:48:00 +0100 Subject: [Python-checkins] r76892 - python/trunk/Doc/library/stdtypes.rst In-Reply-To: <20091220014640.E0BE61F86BC@kimball.webabinitio.net> References: <4b2d196c.0467f10a.549d.5580SMTPIN_ADDED@mx.google.com> <4B2D65CF.8040707@gmail.com> <20091220014640.E0BE61F86BC@kimball.webabinitio.net> Message-ID: Am 20.12.2009 02:46, schrieb R. David Murray: > On Sun, 20 Dec 2009 09:46:23 +1000, Nick Coghlan wrote: >> georg.brandl wrote: >> > Modified: python/trunk/Doc/library/stdtypes.rst >> > ============================================================================== >> > --- python/trunk/Doc/library/stdtypes.rst (original) >> > +++ python/trunk/Doc/library/stdtypes.rst Sat Dec 19 19:20:18 2009 >> > @@ -2828,8 +2828,7 @@ >> > >> > .. attribute:: class.__bases__ >> > >> > - The tuple of base classes of a class object. If there are no base classes, this >> > - will be an empty tuple. >> > + The tuple of base classes of a class object. >> >> Hmm, I never found that redundant - it makes it clear the terminal value >> is () rather than None. > > Since it says 'The tuple of...' its value should not be able to be > anything other than a tuple unless that is explicitly documented, IMO. > At least, that's what I'd expect. That, and it's also kind-of wrong in Py3k, where "no base classes" as in "no base given in the class statement" actually gives you (object,) as __bases__. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out. From python-checkins at python.org Mon Dec 21 00:54:53 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Dec 2009 23:54:53 -0000 Subject: [Python-checkins] r76953 - in python/branches/release26-maint: Lib/distutils/command/upload.py Lib/distutils/tests/support.py Lib/distutils/tests/test_upload.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Mon Dec 21 00:54:52 2009 New Revision: 76953 Log: Merged revisions 76952 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76952 | tarek.ziade | 2009-12-21 00:23:34 +0100 (Mon, 21 Dec 2009) | 1 line Fixed #7552: fixed distutils.command.upload failure on very long passwords ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/command/upload.py python/branches/release26-maint/Lib/distutils/tests/support.py python/branches/release26-maint/Lib/distutils/tests/test_upload.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/distutils/command/upload.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/command/upload.py (original) +++ python/branches/release26-maint/Lib/distutils/command/upload.py Mon Dec 21 00:54:52 2009 @@ -11,7 +11,7 @@ import socket import platform import httplib -import base64 +from base64 import standard_b64encode import urlparse import cStringIO as StringIO from ConfigParser import ConfigParser @@ -115,7 +115,8 @@ open(filename+".asc").read()) # set up the authentication - auth = "Basic " + base64.encodestring(self.username + ":" + self.password).strip() + auth = "Basic " + standard_b64encode(self.username + ":" + + self.password) # Build up the MIME payload for the POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' Modified: python/branches/release26-maint/Lib/distutils/tests/support.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/tests/support.py (original) +++ python/branches/release26-maint/Lib/distutils/tests/support.py Mon Dec 21 00:54:52 2009 @@ -1,10 +1,10 @@ """Support code for distutils test cases.""" - +import os import shutil import tempfile from distutils import log - +from distutils.dist import Distribution class LoggingSilencer(object): @@ -55,6 +55,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/release26-maint/Lib/distutils/tests/test_upload.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/tests/test_upload.py (original) +++ python/branches/release26-maint/Lib/distutils/tests/test_upload.py Mon Dec 21 00:54:52 2009 @@ -2,6 +2,7 @@ import sys import os import unittest +import httplib from distutils.command.upload import upload from distutils.core import Distribution @@ -9,8 +10,66 @@ from distutils.tests import support from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase +PYPIRC_LONG_PASSWORD = """\ +[distutils] + +index-servers = + server1 + server2 + +[server1] +username:me +password:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +[server2] +username:meagain +password: secret +realm:acme +repository:http://another.pypi/ +""" + +class _Resp(object): + def __init__(self, status): + self.status = status + self.reason = 'OK' + +_CONNECTIONS = [] + +class _FakeHTTPConnection(object): + def __init__(self, netloc): + self.requests = [] + self.headers = {} + self.body = None + self.netloc = netloc + _CONNECTIONS.append(self) + + def connect(self): + pass + endheaders = connect + + def send(self, body): + self.body = body + + def putrequest(self, type_, data): + self.requests.append((type_, data)) + + def putheader(self, name, value): + self.headers[name] = value + + def getresponse(self): + return _Resp(200) + class uploadTestCase(PyPIRCCommandTestCase): + def setUp(self): + super(uploadTestCase, self).setUp() + self.old_klass = httplib.HTTPConnection + httplib.HTTPConnection = _FakeHTTPConnection + + def tearDown(self): + httplib.HTTPConnection = self.old_klass + super(uploadTestCase, self).tearDown() + def test_finalize_options(self): # new format @@ -27,6 +86,33 @@ self.assertEquals(getattr(cmd, attr), waited) + 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_LONG_PASSWORD) + + # 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 ? + res = _CONNECTIONS[-1] + + headers = res.headers + self.assertEquals(headers['Content-length'], '2086') + self.assertTrue(headers['Content-type'].startswith('multipart/form-data')) + + method, request = res.requests[-1] + self.assertEquals(method, 'POST') + self.assertEquals(res.netloc, 'pypi.python.org') + self.assertTrue('xxx' in res.body) + self.assertFalse('\n' in headers['Authorization']) + def test_suite(): return unittest.makeSuite(uploadTestCase) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Dec 21 00:54:52 2009 @@ -35,6 +35,10 @@ Library ------- +- Issue #7552: Removed line feed in the base64 Authorization header in + the Distutils upload command to avoid an error when PyPI reads it. + This occurs on long passwords. Initial patch by JP St. Pierre. + - Issue #7231: urllib2 cannot handle https with proxy requiring auth. Patch by Tatsuhiro Tsujikawa. From python-checkins at python.org Mon Dec 21 01:02:20 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 00:02:20 -0000 Subject: [Python-checkins] r76954 - in python/branches/py3k: Lib/distutils/command/upload.py Lib/distutils/tests/test_upload.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Mon Dec 21 01:02:20 2009 New Revision: 76954 Log: Merged revisions 76952 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76952 | tarek.ziade | 2009-12-21 00:23:34 +0100 (Mon, 21 Dec 2009) | 1 line Fixed #7552: fixed distutils.command.upload failure on very long passwords ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/command/upload.py python/branches/py3k/Lib/distutils/tests/test_upload.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/command/upload.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/upload.py (original) +++ python/branches/py3k/Lib/distutils/command/upload.py Mon Dec 21 01:02:20 2009 @@ -6,7 +6,7 @@ import socket import platform from urllib.request import urlopen, Request, HTTPError -import base64 +from base64 import standard_b64encode from urllib.parse import urlparse from hashlib import md5 @@ -130,7 +130,7 @@ user_pass = (self.username + ":" + self.password).encode('ascii') # The exact encoding of the authentication string is debated. # Anyway PyPI only accepts ascii for both username or password. - auth = "Basic " + base64.encodebytes(user_pass).strip().decode('ascii') + auth = "Basic " + standard_b64encode(user_pass).decode('ascii') # Build up the MIME payload for the POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' Modified: python/branches/py3k/Lib/distutils/tests/test_upload.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_upload.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_upload.py Mon Dec 21 01:02:20 2009 @@ -10,6 +10,25 @@ from distutils.tests import support from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase +PYPIRC_LONG_PASSWORD = """\ +[distutils] + +index-servers = + server1 + server2 + +[server1] +username:me +password:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +[server2] +username:meagain +password: secret +realm:acme +repository:http://another.pypi/ +""" + + PYPIRC_NOPASSWORD = """\ [distutils] @@ -85,7 +104,7 @@ self.write_file(path) command, pyversion, filename = 'xxx', '2.6', path dist_files = [(command, pyversion, filename)] - self.write_file(self.rc, PYPIRC) + self.write_file(self.rc, PYPIRC_LONG_PASSWORD) # lets run it pkg_dir, dist = self.create_dist(dist_files=dist_files) @@ -101,6 +120,8 @@ self.assertEquals(self.last_open.req.get_full_url(), 'http://pypi.python.org/pypi') self.assertTrue(b'xxx' in self.last_open.req.data) + auth = self.last_open.req.headers['Authorization'] + self.assertFalse('\n' in auth) def test_suite(): return unittest.makeSuite(uploadTestCase) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Dec 21 01:02:20 2009 @@ -157,6 +157,10 @@ Library ------- +- Issue #7552: Removed line feed in the base64 Authorization header in + the Distutils upload command to avoid an error when PyPI reads it. + This occurs on long passwords. Initial patch by JP St. Pierre. + - Issue #7231: urllib2 cannot handle https with proxy requiring auth. Patch by Tatsuhiro Tsujikawa. From python-checkins at python.org Mon Dec 21 01:08:17 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 00:08:17 -0000 Subject: [Python-checkins] r76955 - in python/branches/release31-maint: Lib/distutils/command/upload.py Lib/distutils/tests/test_upload.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Mon Dec 21 01:08:17 2009 New Revision: 76955 Log: Merged revisions 76954 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76954 | tarek.ziade | 2009-12-21 01:02:20 +0100 (Mon, 21 Dec 2009) | 9 lines Merged revisions 76952 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76952 | tarek.ziade | 2009-12-21 00:23:34 +0100 (Mon, 21 Dec 2009) | 1 line Fixed #7552: fixed distutils.command.upload failure on very long passwords ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/distutils/command/upload.py python/branches/release31-maint/Lib/distutils/tests/test_upload.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/distutils/command/upload.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/command/upload.py (original) +++ python/branches/release31-maint/Lib/distutils/command/upload.py Mon Dec 21 01:08:17 2009 @@ -12,7 +12,7 @@ import platform import configparser import http.client as httpclient -import base64 +from base64 import standard_b64encode import urllib.parse # this keeps compatibility for 2.3 and 2.4 @@ -127,7 +127,7 @@ user_pass = (self.username + ":" + self.password).encode('ascii') # The exact encoding of the authentication string is debated. # Anyway PyPI only accepts ascii for both username or password. - auth = "Basic " + base64.encodebytes(user_pass).strip().decode('ascii') + auth = "Basic " + standard_b64encode(user_pass).decode('ascii') # Build up the MIME payload for the POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' Modified: python/branches/release31-maint/Lib/distutils/tests/test_upload.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/tests/test_upload.py (original) +++ python/branches/release31-maint/Lib/distutils/tests/test_upload.py Mon Dec 21 01:08:17 2009 @@ -10,6 +10,25 @@ from distutils.tests import support from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase +PYPIRC_LONG_PASSWORD = """\ +[distutils] + +index-servers = + server1 + server2 + +[server1] +username:me +password:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +[server2] +username:meagain +password: secret +realm:acme +repository:http://another.pypi/ +""" + + PYPIRC_NOPASSWORD = """\ [distutils] @@ -96,7 +115,7 @@ self.write_file(path) command, pyversion, filename = 'xxx', '2.6', path dist_files = [(command, pyversion, filename)] - self.write_file(self.rc, PYPIRC) + self.write_file(self.rc, PYPIRC_LONG_PASSWORD) # lets run it pkg_dir, dist = self.create_dist(dist_files=dist_files) @@ -108,6 +127,7 @@ headers = dict(self.conn.headers) self.assertEquals(headers['Content-length'], '2087') self.assertTrue(headers['Content-type'].startswith('multipart/form-data')) + self.assertFalse('\n' in headers['Authorization']) self.assertEquals(self.conn.requests, [('POST', '/pypi')]) self.assert_((b'xxx') in self.conn.body) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Dec 21 01:08:17 2009 @@ -58,6 +58,10 @@ Library ------- +- Issue #7552: Removed line feed in the base64 Authorization header in + the Distutils upload command to avoid an error when PyPI reads it. + This occurs on long passwords. Initial patch by JP St. Pierre. + - Issue #7231: urllib2 cannot handle https with proxy requiring auth. Patch by Tatsuhiro Tsujikawa. From python-checkins at python.org Mon Dec 21 02:22:47 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 01:22:47 -0000 Subject: [Python-checkins] r76956 - in python/trunk/Lib/distutils: bcppcompiler.py ccompiler.py command/bdist.py command/bdist_msi.py command/bdist_rpm.py command/bdist_wininst.py command/build_clib.py command/build_ext.py command/build_py.py command/config.py command/register.py command/sdist.py command/upload.py config.py core.py cygwinccompiler.py dir_util.py dist.py emxccompiler.py extension.py fancy_getopt.py msvc9compiler.py msvccompiler.py text_file.py Message-ID: Author: tarek.ziade Date: Mon Dec 21 02:22:46 2009 New Revision: 76956 Log: massive import cleaning in Distutils Modified: python/trunk/Lib/distutils/bcppcompiler.py python/trunk/Lib/distutils/ccompiler.py python/trunk/Lib/distutils/command/bdist.py python/trunk/Lib/distutils/command/bdist_msi.py python/trunk/Lib/distutils/command/bdist_rpm.py python/trunk/Lib/distutils/command/bdist_wininst.py python/trunk/Lib/distutils/command/build_clib.py python/trunk/Lib/distutils/command/build_ext.py python/trunk/Lib/distutils/command/build_py.py python/trunk/Lib/distutils/command/config.py python/trunk/Lib/distutils/command/register.py python/trunk/Lib/distutils/command/sdist.py python/trunk/Lib/distutils/command/upload.py python/trunk/Lib/distutils/config.py python/trunk/Lib/distutils/core.py python/trunk/Lib/distutils/cygwinccompiler.py python/trunk/Lib/distutils/dir_util.py python/trunk/Lib/distutils/dist.py python/trunk/Lib/distutils/emxccompiler.py python/trunk/Lib/distutils/extension.py python/trunk/Lib/distutils/fancy_getopt.py python/trunk/Lib/distutils/msvc9compiler.py python/trunk/Lib/distutils/msvccompiler.py python/trunk/Lib/distutils/text_file.py Modified: python/trunk/Lib/distutils/bcppcompiler.py ============================================================================== --- python/trunk/Lib/distutils/bcppcompiler.py (original) +++ python/trunk/Lib/distutils/bcppcompiler.py Mon Dec 21 02:22:46 2009 @@ -13,13 +13,11 @@ __revision__ = "$Id$" - import os -from distutils.errors import \ - DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError, UnknownFileError -from distutils.ccompiler import \ - CCompiler, gen_preprocess_options, gen_lib_options + +from distutils.errors import (DistutilsExecError, CompileError, LibError, + LinkError, UnknownFileError) +from distutils.ccompiler import CCompiler, gen_preprocess_options from distutils.file_util import write_file from distutils.dep_util import newer from distutils import log Modified: python/trunk/Lib/distutils/ccompiler.py ============================================================================== --- python/trunk/Lib/distutils/ccompiler.py (original) +++ python/trunk/Lib/distutils/ccompiler.py Mon Dec 21 02:22:46 2009 @@ -5,9 +5,11 @@ __revision__ = "$Id$" -import sys, os, re -from types import * -from distutils.errors import * +import sys +import os +import re + +from distutils.errors import CompileError, LinkError, UnknownFileError from distutils.spawn import spawn from distutils.file_util import move_file from distutils.dir_util import mkpath @@ -165,7 +167,7 @@ # set_executables () def set_executable(self, key, value): - if type(value) is StringType: + if isinstance(value, str): setattr(self, key, split_quoted(value)) else: setattr(self, key, value) @@ -187,11 +189,11 @@ nothing if all definitions are OK, raise TypeError otherwise. """ for defn in definitions: - if not (type (defn) is TupleType and + if not (isinstance(defn, tuple) and (len (defn) == 1 or (len (defn) == 2 and - (type (defn[1]) is StringType or defn[1] is None))) and - type (defn[0]) is StringType): + (isinstance(defn[1], str) or defn[1] is None))) and + isinstance(defn[0], str)): raise TypeError, \ ("invalid macro definition '%s': " % defn) + \ "must be tuple (string,), (string, string), or " + \ @@ -341,19 +343,19 @@ """ if outdir is None: outdir = self.output_dir - elif type(outdir) is not StringType: + elif not isinstance(outdir, str): raise TypeError, "'output_dir' must be a string or None" if macros is None: macros = self.macros - elif type(macros) is ListType: + elif isinstance(macros, list): macros = macros + (self.macros or []) else: raise TypeError, "'macros' (if supplied) must be a list of tuples" if incdirs is None: incdirs = self.include_dirs - elif type(incdirs) in (ListType, TupleType): + elif isinstance(incdirs, (list, tuple)): incdirs = list(incdirs) + (self.include_dirs or []) else: raise TypeError, \ @@ -444,14 +446,14 @@ if macros is None: macros = self.macros - elif type (macros) is ListType: + elif isinstance(macros, list): macros = macros + (self.macros or []) else: raise TypeError, "'macros' (if supplied) must be a list of tuples" if include_dirs is None: include_dirs = self.include_dirs - elif type (include_dirs) in (ListType, TupleType): + elif isinstance(include_dirs, (list, tuple)): include_dirs = list (include_dirs) + (self.include_dirs or []) else: raise TypeError, \ @@ -517,14 +519,14 @@ None, replace with self.output_dir. Return fixed versions of 'objects' and 'output_dir'. """ - if type (objects) not in (ListType, TupleType): + if not isinstance(objects, (list, tuple)): raise TypeError, \ "'objects' must be a list or tuple of strings" objects = list (objects) if output_dir is None: output_dir = self.output_dir - elif type (output_dir) is not StringType: + elif not isinstance(output_dir, str): raise TypeError, "'output_dir' must be a string or None" return (objects, output_dir) @@ -539,7 +541,7 @@ """ if libraries is None: libraries = self.libraries - elif type (libraries) in (ListType, TupleType): + elif isinstance(libraries, (list, tuple)): libraries = list (libraries) + (self.libraries or []) else: raise TypeError, \ @@ -547,7 +549,7 @@ if library_dirs is None: library_dirs = self.library_dirs - elif type (library_dirs) in (ListType, TupleType): + elif isinstance(library_dirs, (list, tuple)): library_dirs = list (library_dirs) + (self.library_dirs or []) else: raise TypeError, \ @@ -555,7 +557,7 @@ if runtime_library_dirs is None: runtime_library_dirs = self.runtime_library_dirs - elif type (runtime_library_dirs) in (ListType, TupleType): + elif isinstance(runtime_library_dirs, (list, tuple)): runtime_library_dirs = (list (runtime_library_dirs) + (self.runtime_library_dirs or [])) else: @@ -587,7 +589,7 @@ """Detect the language of a given file, or list of files. Uses language_map, and language_order to do the job. """ - if type(sources) is not ListType: + if not isinstance(sources, list): sources = [sources] lang = None index = len(self.language_order) @@ -1194,7 +1196,7 @@ pp_opts = [] for macro in macros: - if not (type (macro) is TupleType and + if not (isinstance(macro, tuple) and 1 <= len (macro) <= 2): raise TypeError, \ ("bad macro definition '%s': " + Modified: python/trunk/Lib/distutils/command/bdist.py ============================================================================== --- python/trunk/Lib/distutils/command/bdist.py (original) +++ python/trunk/Lib/distutils/command/bdist.py Mon Dec 21 02:22:46 2009 @@ -6,9 +6,9 @@ __revision__ = "$Id$" import os -from types import * + from distutils.core import Command -from distutils.errors import * +from distutils.errors import DistutilsPlatformError, DistutilsOptionError from distutils.util import get_platform @@ -16,7 +16,7 @@ """Print list of available formats (arguments to "--format" option). """ from distutils.fancy_getopt import FancyGetopt - formats=[] + formats = [] for format in bdist.format_commands: formats.append(("formats=" + format, None, bdist.format_command[format][1])) Modified: python/trunk/Lib/distutils/command/bdist_msi.py ============================================================================== --- python/trunk/Lib/distutils/command/bdist_msi.py (original) +++ python/trunk/Lib/distutils/command/bdist_msi.py Mon Dec 21 02:22:46 2009 @@ -28,7 +28,6 @@ default, cancel, bitmap=true)""" Dialog.__init__(self, *args) ruler = self.h - 36 - bmwidth = 152*ruler/328 #if kw.get("bitmap", True): # self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin") self.line("BottomLine", 0, ruler, self.w, 0) @@ -420,7 +419,6 @@ # see "Dialog Style Bits" modal = 3 # visible | modal modeless = 1 # visible - track_disk_space = 32 # UI customization properties add_data(db, "Property", Modified: python/trunk/Lib/distutils/command/bdist_rpm.py ============================================================================== --- python/trunk/Lib/distutils/command/bdist_rpm.py (original) +++ python/trunk/Lib/distutils/command/bdist_rpm.py Mon Dec 21 02:22:46 2009 @@ -5,14 +5,15 @@ __revision__ = "$Id$" -import sys, os, string -from types import * +import sys +import os +import string + from distutils.core import Command from distutils.debug import DEBUG -from distutils.util import get_platform from distutils.file_util import write_file -from distutils.errors import * -from distutils.sysconfig import get_python_version +from distutils.errors import (DistutilsOptionError, DistutilsPlatformError, + DistutilsFileError, DistutilsExecError) from distutils import log class bdist_rpm (Command): @@ -225,7 +226,7 @@ self.distribution.get_contact_email())) self.ensure_string('packager') self.ensure_string_list('doc_files') - if type(self.doc_files) is ListType: + if isinstance(self.doc_files, list): for readme in ('README', 'README.txt'): if os.path.exists(readme) and readme not in self.doc_files: self.doc_files.append(readme) @@ -444,7 +445,7 @@ 'Obsoletes', ): val = getattr(self, string.lower(field)) - if type(val) is ListType: + if isinstance(val, list): spec_file.append('%s: %s' % (field, string.join(val))) elif val is not None: spec_file.append('%s: %s' % (field, val)) 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 Mon Dec 21 02:22:46 2009 @@ -5,11 +5,14 @@ __revision__ = "$Id$" -import sys, os, string +import sys +import os +import string + from distutils.core import Command from distutils.util import get_platform -from distutils.dir_util import create_tree, remove_tree -from distutils.errors import * +from distutils.dir_util import remove_tree +from distutils.errors import DistutilsOptionError, DistutilsPlatformError from distutils.sysconfig import get_python_version from distutils import log Modified: python/trunk/Lib/distutils/command/build_clib.py ============================================================================== --- python/trunk/Lib/distutils/command/build_clib.py (original) +++ python/trunk/Lib/distutils/command/build_clib.py Mon Dec 21 02:22:46 2009 @@ -18,7 +18,7 @@ import os from distutils.core import Command -from distutils.errors import * +from distutils.errors import DistutilsSetupError from distutils.sysconfig import customize_compiler from distutils import log 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 Mon Dec 21 02:22:46 2009 @@ -10,7 +10,8 @@ from warnings import warn from distutils.core import Command -from distutils.errors import * +from distutils.errors import (CCompilerError, DistutilsError, CompileError, + DistutilsSetupError, DistutilsPlatformError) from distutils.sysconfig import customize_compiler, get_python_version from distutils.dep_util import newer_group from distutils.extension import Extension Modified: python/trunk/Lib/distutils/command/build_py.py ============================================================================== --- python/trunk/Lib/distutils/command/build_py.py (original) +++ python/trunk/Lib/distutils/command/build_py.py Mon Dec 21 02:22:46 2009 @@ -133,7 +133,6 @@ def build_package_data(self): """Copy data files into build directory""" - lastdir = None for package, src_dir, build_dir, filenames in self.data_files: for filename in filenames: target = os.path.join(build_dir, filename) Modified: python/trunk/Lib/distutils/command/config.py ============================================================================== --- python/trunk/Lib/distutils/command/config.py (original) +++ python/trunk/Lib/distutils/command/config.py Mon Dec 21 02:22:46 2009 @@ -11,7 +11,8 @@ __revision__ = "$Id$" -import sys, os, re +import os +import re from distutils.core import Command from distutils.errors import DistutilsExecError Modified: python/trunk/Lib/distutils/command/register.py ============================================================================== --- python/trunk/Lib/distutils/command/register.py (original) +++ python/trunk/Lib/distutils/command/register.py Mon Dec 21 02:22:46 2009 @@ -7,12 +7,13 @@ __revision__ = "$Id$" -import os, string, urllib2, getpass, urlparse +import urllib2 +import getpass +import urlparse import StringIO from warnings import warn from distutils.core import PyPIRCCommand -from distutils.errors import * from distutils import log class register(PyPIRCCommand): Modified: python/trunk/Lib/distutils/command/sdist.py ============================================================================== --- python/trunk/Lib/distutils/command/sdist.py (original) +++ python/trunk/Lib/distutils/command/sdist.py Mon Dec 21 02:22:46 2009 @@ -4,16 +4,17 @@ __revision__ = "$Id$" -import os, string +import os +import string import sys -from types import * from glob import glob from warnings import warn from distutils.core import Command from distutils import dir_util, dep_util, file_util, archive_util from distutils.text_file import TextFile -from distutils.errors import * +from distutils.errors import (DistutilsPlatformError, DistutilsOptionError, + DistutilsTemplateError) from distutils.filelist import FileList from distutils import log from distutils.util import convert_path @@ -256,7 +257,7 @@ standards = [('README', 'README.txt'), self.distribution.script_name] for fn in standards: - if type(fn) is TupleType: + if isinstance(fn, tuple): alts = fn got_it = 0 for fn in alts: Modified: python/trunk/Lib/distutils/command/upload.py ============================================================================== --- python/trunk/Lib/distutils/command/upload.py (original) +++ python/trunk/Lib/distutils/command/upload.py Mon Dec 21 02:22:46 2009 @@ -1,7 +1,6 @@ """distutils.command.upload Implements the Distutils 'upload' subcommand (upload package to PyPI).""" -import sys import os import socket import platform @@ -9,10 +8,9 @@ from base64 import standard_b64encode import urlparse import cStringIO as StringIO -from ConfigParser import ConfigParser from hashlib import md5 -from distutils.errors import * +from distutils.errors import DistutilsOptionError from distutils.core import PyPIRCCommand from distutils.spawn import spawn from distutils import log Modified: python/trunk/Lib/distutils/config.py ============================================================================== --- python/trunk/Lib/distutils/config.py (original) +++ python/trunk/Lib/distutils/config.py Mon Dec 21 02:22:46 2009 @@ -4,7 +4,6 @@ that uses .pypirc in the distutils.command package. """ import os -import sys from ConfigParser import ConfigParser from distutils.cmd import Command @@ -60,8 +59,6 @@ if os.path.exists(rc): self.announce('Using PyPI login from %s' % rc) repository = self.repository or self.DEFAULT_REPOSITORY - realm = self.realm or self.DEFAULT_REALM - config = ConfigParser() config.read(rc) sections = config.sections() Modified: python/trunk/Lib/distutils/core.py ============================================================================== --- python/trunk/Lib/distutils/core.py (original) +++ python/trunk/Lib/distutils/core.py Mon Dec 21 02:22:46 2009 @@ -8,10 +8,12 @@ __revision__ = "$Id$" -import sys, os +import sys +import os from distutils.debug import DEBUG -from distutils.errors import * +from distutils.errors import (DistutilsSetupError, DistutilsArgError, + DistutilsError, CCompilerError) from distutils.util import grok_environment_error # Mainly import these so setup scripts can "from distutils.core import" them. @@ -31,7 +33,7 @@ or: %(script)s cmd --help """ -def gen_usage (script_name): +def gen_usage(script_name): script = os.path.basename(script_name) return USAGE % vars() @@ -56,7 +58,7 @@ 'extra_objects', 'extra_compile_args', 'extra_link_args', 'swig_opts', 'export_symbols', 'depends', 'language') -def setup (**attrs): +def setup(**attrs): """The gateway to the Distutils: do everything your setup script needs to do, in a highly flexible and user-driven way. Briefly: create a Distribution instance; find and parse config files; parse the command @@ -168,10 +170,8 @@ return dist -# setup () - -def run_setup (script_name, script_args=None, stop_after="run"): +def run_setup(script_name, script_args=None, stop_after="run"): """Run a setup script in a somewhat controlled environment, and return the Distribution instance that drives things. This is useful if you need to find out the distribution meta-data (passed as @@ -235,7 +235,4 @@ # I wonder if the setup script's namespace -- g and l -- would be of # any interest to callers? - #print "_setup_distribution:", _setup_distribution return _setup_distribution - -# run_setup () Modified: python/trunk/Lib/distutils/cygwinccompiler.py ============================================================================== --- python/trunk/Lib/distutils/cygwinccompiler.py (original) +++ python/trunk/Lib/distutils/cygwinccompiler.py Mon Dec 21 02:22:46 2009 @@ -53,11 +53,9 @@ import re from warnings import warn -from distutils.ccompiler import gen_preprocess_options, gen_lib_options from distutils.unixccompiler import UnixCCompiler from distutils.file_util import write_file from distutils.errors import DistutilsExecError, CompileError, UnknownFileError -from distutils import log from distutils.util import get_compiler_versions def get_msvcr(): Modified: python/trunk/Lib/distutils/dir_util.py ============================================================================== --- python/trunk/Lib/distutils/dir_util.py (original) +++ python/trunk/Lib/distutils/dir_util.py Mon Dec 21 02:22:46 2009 @@ -4,7 +4,7 @@ __revision__ = "$Id$" -import os, sys +import os from distutils.errors import DistutilsFileError, DistutilsInternalError from distutils import log Modified: python/trunk/Lib/distutils/dist.py ============================================================================== --- python/trunk/Lib/distutils/dist.py (original) +++ python/trunk/Lib/distutils/dist.py Mon Dec 21 02:22:46 2009 @@ -14,7 +14,8 @@ except ImportError: warnings = None -from distutils.errors import * +from distutils.errors import (DistutilsOptionError, DistutilsArgError, + DistutilsModuleError, DistutilsClassError) from distutils.fancy_getopt import FancyGetopt, translate_longopt from distutils.util import check_environ, strtobool, rfc822_escape from distutils import log Modified: python/trunk/Lib/distutils/emxccompiler.py ============================================================================== --- python/trunk/Lib/distutils/emxccompiler.py (original) +++ python/trunk/Lib/distutils/emxccompiler.py Mon Dec 21 02:22:46 2009 @@ -24,11 +24,9 @@ import os, sys, copy from warnings import warn -from distutils.ccompiler import gen_preprocess_options, gen_lib_options from distutils.unixccompiler import UnixCCompiler from distutils.file_util import write_file from distutils.errors import DistutilsExecError, CompileError, UnknownFileError -from distutils import log from distutils.util import get_compiler_versions class EMXCCompiler (UnixCCompiler): Modified: python/trunk/Lib/distutils/extension.py ============================================================================== --- python/trunk/Lib/distutils/extension.py (original) +++ python/trunk/Lib/distutils/extension.py Mon Dec 21 02:22:46 2009 @@ -6,7 +6,6 @@ __revision__ = "$Id$" import os -import sys import warnings # This class is really only used by the "build_ext" command, so it might Modified: python/trunk/Lib/distutils/fancy_getopt.py ============================================================================== --- python/trunk/Lib/distutils/fancy_getopt.py (original) +++ python/trunk/Lib/distutils/fancy_getopt.py Mon Dec 21 02:22:46 2009 @@ -10,10 +10,11 @@ __revision__ = "$Id$" -import sys, string, re -from types import * +import sys +import string +import re import getopt -from distutils.errors import * +from distutils.errors import DistutilsGetoptError, DistutilsArgError # Much like command_re in distutils.core, this is close to but not quite # the same as a Python NAME -- except, in the spirit of most GNU @@ -117,7 +118,7 @@ def _check_alias_dict (self, aliases, what): - assert type(aliases) is DictionaryType + assert isinstance(aliases, dict) for (alias, opt) in aliases.items(): if alias not in self.option_index: raise DistutilsGetoptError, \ @@ -164,13 +165,13 @@ raise ValueError, "invalid option tuple: %r" % (option,) # Type- and value-check the option names - if type(long) is not StringType or len(long) < 2: + if not isinstance(long, str) or len(long) < 2: raise DistutilsGetoptError, \ ("invalid long option '%s': " "must be a string of length >= 2") % long if (not ((short is None) or - (type(short) is StringType and len(short) == 1))): + (isinstance(short, str) and len(short) == 1))): raise DistutilsGetoptError, \ ("invalid short option '%s': " "must a single character or None") % short @@ -464,10 +465,8 @@ return lines -# wrap_text () - -def translate_longopt (opt): +def translate_longopt(opt): """Convert a long option name to a valid Python identifier by changing "-" to "_". """ @@ -483,18 +482,3 @@ 'options' will be initialized to None.""" for opt in options: setattr(self, opt, None) - -# class OptionDummy - - -if __name__ == "__main__": - text = """\ -Tra-la-la, supercalifragilisticexpialidocious. -How *do* you spell that odd word, anyways? -(Someone ask Mary -- she'll know [or she'll -say, "How should I know?"].)""" - - for w in (10, 20, 30, 40): - print "width: %d" % w - print string.join(wrap_text(text, w), "\n") - print Modified: python/trunk/Lib/distutils/msvc9compiler.py ============================================================================== --- python/trunk/Lib/distutils/msvc9compiler.py (original) +++ python/trunk/Lib/distutils/msvc9compiler.py Mon Dec 21 02:22:46 2009 @@ -19,10 +19,9 @@ import sys import re -from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import CCompiler, gen_preprocess_options, \ - gen_lib_options +from distutils.errors import (DistutilsExecError, DistutilsPlatformError, + CompileError, LibError, LinkError) +from distutils.ccompiler import CCompiler, gen_lib_options from distutils import log from distutils.util import get_platform Modified: python/trunk/Lib/distutils/msvccompiler.py ============================================================================== --- python/trunk/Lib/distutils/msvccompiler.py (original) +++ python/trunk/Lib/distutils/msvccompiler.py Mon Dec 21 02:22:46 2009 @@ -10,12 +10,13 @@ __revision__ = "$Id$" -import sys, os, string -from distutils.errors import \ - DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import \ - CCompiler, gen_preprocess_options, gen_lib_options +import sys +import os +import string + +from distutils.errors import (DistutilsExecError, DistutilsPlatformError, + CompileError, LibError, LinkError) +from distutils.ccompiler import CCompiler, gen_lib_options from distutils import log _can_read_reg = 0 @@ -127,7 +128,7 @@ self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1") else: self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") - except KeyError, exc: # + except KeyError: raise DistutilsPlatformError, \ ("""Python was built with Visual Studio 2003; extensions must be built with a compiler than can generate compatible binaries. Modified: python/trunk/Lib/distutils/text_file.py ============================================================================== --- python/trunk/Lib/distutils/text_file.py (original) +++ python/trunk/Lib/distutils/text_file.py Mon Dec 21 02:22:46 2009 @@ -6,8 +6,7 @@ __revision__ = "$Id$" -from types import * -import sys, os, string +import sys class TextFile: @@ -137,12 +136,12 @@ if line is None: line = self.current_line outmsg.append(self.filename + ", ") - if type (line) in (ListType, TupleType): + if isinstance(line, (list, tuple)): outmsg.append("lines %d-%d: " % tuple (line)) else: outmsg.append("line %d: " % line) outmsg.append(str(msg)) - return string.join(outmsg, "") + return ''.join(outmsg) def error (self, msg, line=None): @@ -196,7 +195,7 @@ # unescape it (and any other escaped "#"'s that might be # lurking in there) and otherwise leave the line alone. - pos = string.find (line, "#") + pos = line.find("#") if pos == -1: # no "#" -- no comments pass @@ -219,11 +218,11 @@ # # comment that should be ignored # there # result in "hello there". - if string.strip(line) == "": + if line.strip() == "": continue else: # it's an escaped "#" - line = string.replace (line, "\\#", "#") + line = line.replace("\\#", "#") # did previous line end with a backslash? then accumulate @@ -235,11 +234,11 @@ return buildup_line if self.collapse_join: - line = string.lstrip (line) + line = line.lstrip() line = buildup_line + line # careful: pay attention to line number when incrementing it - if type (self.current_line) is ListType: + if isinstance(self.current_line, list): self.current_line[1] = self.current_line[1] + 1 else: self.current_line = [self.current_line, @@ -250,7 +249,7 @@ return None # still have to be careful about incrementing the line number! - if type (self.current_line) is ListType: + if isinstance(self.current_line, list): self.current_line = self.current_line[1] + 1 else: self.current_line = self.current_line + 1 @@ -259,11 +258,11 @@ # strip whitespace however the client wants (leading and # trailing, or one or the other, or neither) if self.lstrip_ws and self.rstrip_ws: - line = string.strip (line) + line = line.strip() elif self.lstrip_ws: - line = string.lstrip (line) + line = line.lstrip() elif self.rstrip_ws: - line = string.rstrip (line) + line = line.rstrip() # blank line (whether we rstrip'ed or not)? skip to next line # if appropriate From python-checkins at python.org Mon Dec 21 02:23:42 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 01:23:42 -0000 Subject: [Python-checkins] r76957 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Mon Dec 21 02:23:41 2009 New Revision: 76957 Log: Blocked revisions 76956 via svnmerge ........ r76956 | tarek.ziade | 2009-12-21 02:22:46 +0100 (Mon, 21 Dec 2009) | 1 line massive import cleaning in Distutils ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 21 02:49:01 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 01:49:01 -0000 Subject: [Python-checkins] r76958 - in python/branches/py3k: Lib/distutils/bcppcompiler.py Lib/distutils/ccompiler.py Lib/distutils/command/bdist.py Lib/distutils/command/bdist_msi.py Lib/distutils/command/bdist_rpm.py Lib/distutils/command/bdist_wininst.py Lib/distutils/command/build_clib.py Lib/distutils/command/build_ext.py Lib/distutils/command/build_py.py Lib/distutils/command/config.py Lib/distutils/command/register.py Lib/distutils/command/sdist.py Lib/distutils/command/upload.py Lib/distutils/config.py Lib/distutils/core.py Lib/distutils/cygwinccompiler.py Lib/distutils/dir_util.py Lib/distutils/dist.py Lib/distutils/emxccompiler.py Lib/distutils/extension.py Lib/distutils/fancy_getopt.py Lib/distutils/msvc9compiler.py Lib/distutils/msvccompiler.py Lib/distutils/text_file.py Message-ID: Author: tarek.ziade Date: Mon Dec 21 02:49:00 2009 New Revision: 76958 Log: Merged revisions 76956 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76956 | tarek.ziade | 2009-12-21 02:22:46 +0100 (Mon, 21 Dec 2009) | 1 line massive import cleaning in Distutils ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/bcppcompiler.py python/branches/py3k/Lib/distutils/ccompiler.py python/branches/py3k/Lib/distutils/command/bdist.py python/branches/py3k/Lib/distutils/command/bdist_msi.py python/branches/py3k/Lib/distutils/command/bdist_rpm.py python/branches/py3k/Lib/distutils/command/bdist_wininst.py python/branches/py3k/Lib/distutils/command/build_clib.py python/branches/py3k/Lib/distutils/command/build_ext.py python/branches/py3k/Lib/distutils/command/build_py.py python/branches/py3k/Lib/distutils/command/config.py python/branches/py3k/Lib/distutils/command/register.py python/branches/py3k/Lib/distutils/command/sdist.py python/branches/py3k/Lib/distutils/command/upload.py python/branches/py3k/Lib/distutils/config.py python/branches/py3k/Lib/distutils/core.py python/branches/py3k/Lib/distutils/cygwinccompiler.py python/branches/py3k/Lib/distutils/dir_util.py python/branches/py3k/Lib/distutils/dist.py python/branches/py3k/Lib/distutils/emxccompiler.py python/branches/py3k/Lib/distutils/extension.py python/branches/py3k/Lib/distutils/fancy_getopt.py python/branches/py3k/Lib/distutils/msvc9compiler.py python/branches/py3k/Lib/distutils/msvccompiler.py python/branches/py3k/Lib/distutils/text_file.py Modified: python/branches/py3k/Lib/distutils/bcppcompiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/bcppcompiler.py (original) +++ python/branches/py3k/Lib/distutils/bcppcompiler.py Mon Dec 21 02:49:00 2009 @@ -13,13 +13,11 @@ __revision__ = "$Id$" - import os -from distutils.errors import \ - DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError, UnknownFileError -from distutils.ccompiler import \ - CCompiler, gen_preprocess_options, gen_lib_options + +from distutils.errors import (DistutilsExecError, CompileError, LibError, + LinkError, UnknownFileError) +from distutils.ccompiler import CCompiler, gen_preprocess_options from distutils.file_util import write_file from distutils.dep_util import newer from distutils import log Modified: python/branches/py3k/Lib/distutils/ccompiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/ccompiler.py (original) +++ python/branches/py3k/Lib/distutils/ccompiler.py Mon Dec 21 02:49:00 2009 @@ -5,8 +5,11 @@ __revision__ = "$Id$" -import sys, os, re -from distutils.errors import * +import sys +import os +import re + +from distutils.errors import CompileError, LinkError, UnknownFileError from distutils.spawn import spawn from distutils.file_util import move_file from distutils.dir_util import mkpath 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 Dec 21 02:49:00 2009 @@ -6,8 +6,9 @@ __revision__ = "$Id$" import os + from distutils.core import Command -from distutils.errors import * +from distutils.errors import DistutilsPlatformError, DistutilsOptionError from distutils.util import get_platform Modified: python/branches/py3k/Lib/distutils/command/bdist_msi.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/bdist_msi.py (original) +++ python/branches/py3k/Lib/distutils/command/bdist_msi.py Mon Dec 21 02:49:00 2009 @@ -28,7 +28,6 @@ default, cancel, bitmap=true)""" Dialog.__init__(self, *args) ruler = self.h - 36 - bmwidth = 152*ruler/328 #if kw.get("bitmap", True): # self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin") self.line("BottomLine", 0, ruler, self.w, 0) @@ -419,7 +418,6 @@ # see "Dialog Style Bits" modal = 3 # visible | modal modeless = 1 # visible - track_disk_space = 32 # UI customization properties add_data(db, "Property", Modified: python/branches/py3k/Lib/distutils/command/bdist_rpm.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/bdist_rpm.py (original) +++ python/branches/py3k/Lib/distutils/command/bdist_rpm.py Mon Dec 21 02:49:00 2009 @@ -5,13 +5,14 @@ __revision__ = "$Id$" -import sys, os +import sys +import os + from distutils.core import Command from distutils.debug import DEBUG -from distutils.util import get_platform from distutils.file_util import write_file -from distutils.errors import * -from distutils.sysconfig import get_python_version +from distutils.errors import (DistutilsOptionError, DistutilsPlatformError, + DistutilsFileError, DistutilsExecError) from distutils import log class bdist_rpm(Command): 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 Mon Dec 21 02:49:00 2009 @@ -5,11 +5,13 @@ __revision__ = "$Id$" -import sys, os +import sys +import os + from distutils.core import Command from distutils.util import get_platform -from distutils.dir_util import create_tree, remove_tree -from distutils.errors import * +from distutils.dir_util import remove_tree +from distutils.errors import DistutilsOptionError, DistutilsPlatformError from distutils.sysconfig import get_python_version from distutils import log Modified: python/branches/py3k/Lib/distutils/command/build_clib.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/build_clib.py (original) +++ python/branches/py3k/Lib/distutils/command/build_clib.py Mon Dec 21 02:49:00 2009 @@ -18,7 +18,7 @@ import os from distutils.core import Command -from distutils.errors import * +from distutils.errors import DistutilsSetupError from distutils.sysconfig import customize_compiler from distutils import log 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 Mon Dec 21 02:49:00 2009 @@ -10,7 +10,8 @@ from warnings import warn from distutils.core import Command -from distutils.errors import * +from distutils.errors import (CCompilerError, DistutilsError, CompileError, + DistutilsSetupError, DistutilsPlatformError) from distutils.sysconfig import customize_compiler, get_python_version from distutils.dep_util import newer_group from distutils.extension import Extension Modified: python/branches/py3k/Lib/distutils/command/build_py.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/build_py.py (original) +++ python/branches/py3k/Lib/distutils/command/build_py.py Mon Dec 21 02:49:00 2009 @@ -133,7 +133,6 @@ def build_package_data(self): """Copy data files into build directory""" - lastdir = None for package, src_dir, build_dir, filenames in self.data_files: for filename in filenames: target = os.path.join(build_dir, filename) 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 Mon Dec 21 02:49:00 2009 @@ -11,7 +11,8 @@ __revision__ = "$Id$" -import sys, os, re +import os +import re from distutils.core import Command from distutils.errors import DistutilsExecError Modified: python/branches/py3k/Lib/distutils/command/register.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/register.py (original) +++ python/branches/py3k/Lib/distutils/command/register.py Mon Dec 21 02:49:00 2009 @@ -7,13 +7,15 @@ __revision__ = "$Id$" -import os, string, getpass +import os +import string +import getpass import io -import urllib.parse, urllib.request +import urllib.parse +import urllib.request from warnings import warn from distutils.core import PyPIRCCommand -from distutils.errors import * from distutils import log class register(PyPIRCCommand): Modified: python/branches/py3k/Lib/distutils/command/sdist.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/sdist.py (original) +++ python/branches/py3k/Lib/distutils/command/sdist.py Mon Dec 21 02:49:00 2009 @@ -7,14 +7,14 @@ import os import string import sys -from types import * from glob import glob from warnings import warn from distutils.core import Command from distutils import dir_util, dep_util, file_util, archive_util from distutils.text_file import TextFile -from distutils.errors import * +from distutils.errors import (DistutilsPlatformError, DistutilsOptionError, + DistutilsTemplateError) from distutils.filelist import FileList from distutils import log from distutils.util import convert_path Modified: python/branches/py3k/Lib/distutils/command/upload.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/upload.py (original) +++ python/branches/py3k/Lib/distutils/command/upload.py Mon Dec 21 02:49:00 2009 @@ -1,8 +1,8 @@ """distutils.command.upload Implements the Distutils 'upload' subcommand (upload package to PyPI).""" -import sys -import os, io +import os +import io import socket import platform from urllib.request import urlopen, Request, HTTPError @@ -10,7 +10,7 @@ from urllib.parse import urlparse from hashlib import md5 -from distutils.errors import * +from distutils.errors import DistutilsOptionError from distutils.core import PyPIRCCommand from distutils.spawn import spawn from distutils import log Modified: python/branches/py3k/Lib/distutils/config.py ============================================================================== --- python/branches/py3k/Lib/distutils/config.py (original) +++ python/branches/py3k/Lib/distutils/config.py Mon Dec 21 02:49:00 2009 @@ -4,7 +4,6 @@ that uses .pypirc in the distutils.command package. """ import os -import sys from configparser import ConfigParser from distutils.cmd import Command @@ -60,8 +59,6 @@ if os.path.exists(rc): self.announce('Using PyPI login from %s' % rc) repository = self.repository or self.DEFAULT_REPOSITORY - realm = self.realm or self.DEFAULT_REALM - config = ConfigParser() config.read(rc) sections = config.sections() Modified: python/branches/py3k/Lib/distutils/core.py ============================================================================== --- python/branches/py3k/Lib/distutils/core.py (original) +++ python/branches/py3k/Lib/distutils/core.py Mon Dec 21 02:49:00 2009 @@ -8,10 +8,12 @@ __revision__ = "$Id$" -import sys, os +import sys +import os from distutils.debug import DEBUG -from distutils.errors import * +from distutils.errors import (DistutilsSetupError, DistutilsArgError, + DistutilsError, CCompilerError) from distutils.util import grok_environment_error # Mainly import these so setup scripts can "from distutils.core import" them. @@ -31,7 +33,7 @@ or: %(script)s cmd --help """ -def gen_usage (script_name): +def gen_usage(script_name): script = os.path.basename(script_name) return USAGE % vars() @@ -56,7 +58,7 @@ 'extra_objects', 'extra_compile_args', 'extra_link_args', 'swig_opts', 'export_symbols', 'depends', 'language') -def setup (**attrs): +def setup(**attrs): """The gateway to the Distutils: do everything your setup script needs to do, in a highly flexible and user-driven way. Briefly: create a Distribution instance; find and parse config files; parse the command @@ -168,10 +170,8 @@ return dist -# setup () - -def run_setup (script_name, script_args=None, stop_after="run"): +def run_setup(script_name, script_args=None, stop_after="run"): """Run a setup script in a somewhat controlled environment, and return the Distribution instance that drives things. This is useful if you need to find out the distribution meta-data (passed as @@ -234,7 +234,4 @@ # I wonder if the setup script's namespace -- g and l -- would be of # any interest to callers? - #print "_setup_distribution:", _setup_distribution return _setup_distribution - -# run_setup () Modified: python/branches/py3k/Lib/distutils/cygwinccompiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/cygwinccompiler.py (original) +++ python/branches/py3k/Lib/distutils/cygwinccompiler.py Mon Dec 21 02:49:00 2009 @@ -53,11 +53,9 @@ import re from warnings import warn -from distutils.ccompiler import gen_preprocess_options, gen_lib_options from distutils.unixccompiler import UnixCCompiler from distutils.file_util import write_file from distutils.errors import DistutilsExecError, CompileError, UnknownFileError -from distutils import log from distutils.util import get_compiler_versions def get_msvcr(): Modified: python/branches/py3k/Lib/distutils/dir_util.py ============================================================================== --- python/branches/py3k/Lib/distutils/dir_util.py (original) +++ python/branches/py3k/Lib/distutils/dir_util.py Mon Dec 21 02:49:00 2009 @@ -4,7 +4,7 @@ __revision__ = "$Id$" -import os, sys +import os from distutils.errors import DistutilsFileError, DistutilsInternalError from distutils import log Modified: python/branches/py3k/Lib/distutils/dist.py ============================================================================== --- python/branches/py3k/Lib/distutils/dist.py (original) +++ python/branches/py3k/Lib/distutils/dist.py Mon Dec 21 02:49:00 2009 @@ -14,7 +14,8 @@ except ImportError: warnings = None -from distutils.errors import * +from distutils.errors import (DistutilsOptionError, DistutilsArgError, + DistutilsModuleError, DistutilsClassError) from distutils.fancy_getopt import FancyGetopt, translate_longopt from distutils.util import check_environ, strtobool, rfc822_escape from distutils import log Modified: python/branches/py3k/Lib/distutils/emxccompiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/emxccompiler.py (original) +++ python/branches/py3k/Lib/distutils/emxccompiler.py Mon Dec 21 02:49:00 2009 @@ -24,11 +24,9 @@ import os, sys, copy from warnings import warn -from distutils.ccompiler import gen_preprocess_options, gen_lib_options from distutils.unixccompiler import UnixCCompiler from distutils.file_util import write_file from distutils.errors import DistutilsExecError, CompileError, UnknownFileError -from distutils import log from distutils.util import get_compiler_versions class EMXCCompiler (UnixCCompiler): Modified: python/branches/py3k/Lib/distutils/extension.py ============================================================================== --- python/branches/py3k/Lib/distutils/extension.py (original) +++ python/branches/py3k/Lib/distutils/extension.py Mon Dec 21 02:49:00 2009 @@ -6,7 +6,6 @@ __revision__ = "$Id$" import os -import sys import warnings # This class is really only used by the "build_ext" command, so it might Modified: python/branches/py3k/Lib/distutils/fancy_getopt.py ============================================================================== --- python/branches/py3k/Lib/distutils/fancy_getopt.py (original) +++ python/branches/py3k/Lib/distutils/fancy_getopt.py Mon Dec 21 02:49:00 2009 @@ -10,9 +10,11 @@ __revision__ = "$Id$" -import sys, string, re +import sys +import string +import re import getopt -from distutils.errors import * +from distutils.errors import DistutilsGetoptError, DistutilsArgError # Much like command_re in distutils.core, this is close to but not quite # the same as a Python NAME -- except, in the spirit of most GNU @@ -444,16 +446,3 @@ 'options' will be initialized to None.""" for opt in options: setattr(self, opt, None) - - -if __name__ == "__main__": - text = """\ -Tra-la-la, supercalifragilisticexpialidocious. -How *do* you spell that odd word, anyways? -(Someone ask Mary -- she'll know [or she'll -say, "How should I know?"].)""" - - for w in (10, 20, 30, 40): - print("width: %d" % w) - print("\n".join(wrap_text(text, w))) - print() Modified: python/branches/py3k/Lib/distutils/msvc9compiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/msvc9compiler.py (original) +++ python/branches/py3k/Lib/distutils/msvc9compiler.py Mon Dec 21 02:49:00 2009 @@ -19,10 +19,9 @@ import sys import re -from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import CCompiler, gen_preprocess_options, \ - gen_lib_options +from distutils.errors import (DistutilsExecError, DistutilsPlatformError, + CompileError, LibError, LinkError) +from distutils.ccompiler import CCompiler, gen_lib_options from distutils import log from distutils.util import get_platform Modified: python/branches/py3k/Lib/distutils/msvccompiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/msvccompiler.py (original) +++ python/branches/py3k/Lib/distutils/msvccompiler.py Mon Dec 21 02:49:00 2009 @@ -10,12 +10,12 @@ __revision__ = "$Id$" -import sys, os -from distutils.errors import \ - DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import \ - CCompiler, gen_preprocess_options, gen_lib_options +import sys +import os + +from distutils.errors import (DistutilsExecError, DistutilsPlatformError, + CompileError, LibError, LinkError) +from distutils.ccompiler import CCompiler, gen_lib_options from distutils import log _can_read_reg = False @@ -124,7 +124,7 @@ self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1") else: self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") - except KeyError as exc: # + except KeyError: raise DistutilsPlatformError( """Python was built with Visual Studio 2003; extensions must be built with a compiler than can generate compatible binaries. Modified: python/branches/py3k/Lib/distutils/text_file.py ============================================================================== --- python/branches/py3k/Lib/distutils/text_file.py (original) +++ python/branches/py3k/Lib/distutils/text_file.py Mon Dec 21 02:49:00 2009 @@ -6,8 +6,8 @@ __revision__ = "$Id$" -import sys, os, io - +import sys +import io class TextFile: """Provides a file-like object that takes care of all the things you From python-checkins at python.org Mon Dec 21 02:49:47 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 01:49:47 -0000 Subject: [Python-checkins] r76959 - python/branches/release31-maint Message-ID: Author: tarek.ziade Date: Mon Dec 21 02:49:47 2009 New Revision: 76959 Log: Blocked revisions 76958 via svnmerge ................ r76958 | tarek.ziade | 2009-12-21 02:49:00 +0100 (Mon, 21 Dec 2009) | 9 lines Merged revisions 76956 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76956 | tarek.ziade | 2009-12-21 02:22:46 +0100 (Mon, 21 Dec 2009) | 1 line massive import cleaning in Distutils ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Dec 21 11:43:39 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 10:43:39 -0000 Subject: [Python-checkins] r76960 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Mon Dec 21 11:43:39 2009 New Revision: 76960 Log: replaced *-URL by Project-URL (multiple-use) Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Mon Dec 21 11:43:39 2009 @@ -416,28 +416,15 @@ Copyright: Public Domain -Repository-URL - A string containing the URL for the project repository. +Project-URL (multiple-use) : + A string containing a browsable URL for the project and a label for it, + separated by a comma. Example:: - Repository-URL: http://svn.python.org/projects/python/trunk/ + Bug Tracker, http://bitbucket.org/tarek/distribute/issues/ - -Repository-Browse-URL - A string containing the URL for the project browsable repository. - - Example:: - - Repository-Browse-URL: http://svn.python.org/view/python/trunk - - -Bug-Tracker-URL - A string containing the URL for the package's bug tracker - - Example:: - - Bug-Tracker-URL: http://bugs.python.org/ + The label length is a free text limited to 32 signs. Version Specifiers @@ -520,9 +507,7 @@ - Requires-Dist - Provides-Dist - Obsoletes-Dist - - Repository-URL - - Repository-Browser-URL - - Bug-Tracker-URL + - Project-URL * Deprecated fields: From python-checkins at python.org Mon Dec 21 11:48:33 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 10:48:33 -0000 Subject: [Python-checkins] r76961 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Mon Dec 21 11:48:32 2009 New Revision: 76961 Log: typo Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Mon Dec 21 11:48:32 2009 @@ -424,7 +424,7 @@ Bug Tracker, http://bitbucket.org/tarek/distribute/issues/ - The label length is a free text limited to 32 signs. + The label is a free text limited to 32 signs. Version Specifiers From python-checkins at python.org Mon Dec 21 12:21:26 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 11:21:26 -0000 Subject: [Python-checkins] r76963 - in python/trunk: Doc/c-api/long.rst Include/longobject.h Misc/NEWS Modules/_testcapimodule.c Objects/longobject.c Message-ID: Author: mark.dickinson Date: Mon Dec 21 12:21:25 2009 New Revision: 76963 Log: Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk. Thanks Case Van Horsen for the patch. Modified: python/trunk/Doc/c-api/long.rst python/trunk/Include/longobject.h python/trunk/Misc/NEWS python/trunk/Modules/_testcapimodule.c python/trunk/Objects/longobject.c Modified: python/trunk/Doc/c-api/long.rst ============================================================================== --- python/trunk/Doc/c-api/long.rst (original) +++ python/trunk/Doc/c-api/long.rst Mon Dec 21 12:21:25 2009 @@ -133,6 +133,19 @@ and ``-1`` will be returned. +.. cfunction:: long PyLong_AsLongAndOverflow(PyObject *pylong, int* overflow) + + Return a C :ctype:`long` representation of the contents of + *pylong*. If *pylong* is greater than :const:`LONG_MAX` or less + than :const:`LONG_MIN`, set `*overflow` to ``1`` or ``-1``, + respectively, and return ``-1``; otherwise, set `*overflow` to + ``0``. If any other exception occurs (for example a TypeError or + MemoryError), then ``-1`` will be returned and ``*overflow`` will + be ``0``. + + .. versionadded:: 2.7 + + .. cfunction:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong) .. index:: Modified: python/trunk/Include/longobject.h ============================================================================== --- python/trunk/Include/longobject.h (original) +++ python/trunk/Include/longobject.h Mon Dec 21 12:21:25 2009 @@ -21,6 +21,7 @@ PyAPI_FUNC(PyObject *) PyLong_FromSize_t(size_t); PyAPI_FUNC(PyObject *) PyLong_FromSsize_t(Py_ssize_t); PyAPI_FUNC(long) PyLong_AsLong(PyObject *); +PyAPI_FUNC(long) PyLong_AsLongAndOverflow(PyObject *, int *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *); Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Dec 21 12:21:25 2009 @@ -1648,6 +1648,8 @@ C-API ----- +- Issue #7528: Add PyLong_AsLongAndOverflow (backported from py3k). + - Issue #7228: Add '%lld' and '%llu' support to PyString_FromFormat(V) and PyErr_Format, on machines with HAVE_LONG_LONG defined. Modified: python/trunk/Modules/_testcapimodule.c ============================================================================== --- python/trunk/Modules/_testcapimodule.c (original) +++ python/trunk/Modules/_testcapimodule.c Mon Dec 21 12:21:25 2009 @@ -358,6 +358,75 @@ #undef F_U_TO_PY #undef F_PY_TO_U +/* Test the PyLong_AsLongAndOverflow API. General conversion to PY_LONG + is tested by test_long_api_inner. This test will concentrate on proper + handling of overflow. +*/ + +static PyObject * +test_long_and_overflow(PyObject *self) +{ + PyObject *num; + long value; + int overflow; + + /* a number larger than LONG_MAX even on 64-bit platforms */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + + /* Test that overflow is set properly for a large value. */ + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + if (overflow != 1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to 1"); + + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + if (overflow != 1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to 0"); + + /* a number smaller than LONG_MIN even on 64-bit platforms */ + num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + + /* Test that overflow is set properly for a large negative value. */ + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + if (overflow != -1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to -1"); + + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + if (overflow != -1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to 0"); + + num = PyLong_FromString("FF", NULL, 16); + if (num == NULL) + return NULL; + + /* Test that overflow is cleared properly for a small value. */ + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was set incorrectly"); + + Py_INCREF(Py_None); + return Py_None; +} + /* Test the L code for PyArg_ParseTuple. This should deliver a PY_LONG_LONG for both long and int arguments. The test may leak a little memory if it fails. @@ -1041,6 +1110,7 @@ {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, {"test_lazy_hash_inheritance", (PyCFunction)test_lazy_hash_inheritance,METH_NOARGS}, {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS}, + {"test_long_and_overflow", (PyCFunction)test_long_and_overflow, METH_NOARGS}, {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, Modified: python/trunk/Objects/longobject.c ============================================================================== --- python/trunk/Objects/longobject.c (original) +++ python/trunk/Objects/longobject.c Mon Dec 21 12:21:25 2009 @@ -223,53 +223,123 @@ #define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) #define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN) -/* Get a C long int from a long int object. - Returns -1 and sets an error condition if overflow occurs. */ +/* Get a C long int from a Python long or Python int object. + On overflow, returns -1 and sets *overflow to 1 or -1 depending + on the sign of the result. Otherwise *overflow is 0. + + For other errors (e.g., type error), returns -1 and sets an error + condition. +*/ long -PyLong_AsLong(PyObject *vv) +PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) { /* This version by Tim Peters */ register PyLongObject *v; unsigned long x, prev; + long res; Py_ssize_t i; int sign; + int do_decref = 0; /* if nb_int was called */ - if (vv == NULL || !PyLong_Check(vv)) { - if (vv != NULL && PyInt_Check(vv)) - return PyInt_AsLong(vv); + *overflow = 0; + if (vv == NULL) { PyErr_BadInternalCall(); return -1; } - v = (PyLongObject *)vv; - i = v->ob_size; - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } - while (--i >= 0) { - prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; - if ((x >> PyLong_SHIFT) != prev) - goto overflow; + + if(PyInt_Check(vv)) + return PyInt_AsLong(vv); + + if (!PyLong_Check(vv)) { + PyNumberMethods *nb; + nb = vv->ob_type->tp_as_number; + if (nb == NULL || nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + return -1; + } + vv = (*nb->nb_int) (vv); + if (vv == NULL) + return -1; + do_decref = 1; + if(PyInt_Check(vv)) { + res = PyInt_AsLong(vv); + goto exit; + } + if (!PyLong_Check(vv)) { + Py_DECREF(vv); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return -1; + } } - /* Haven't lost any bits, but casting to long requires extra care - * (see comment above). - */ - if (x <= (unsigned long)LONG_MAX) { - return (long)x * sign; + + res = -1; + v = (PyLongObject *)vv; + i = Py_SIZE(v); + + switch (i) { + case -1: + res = -(sdigit)v->ob_digit[0]; + break; + case 0: + res = 0; + break; + case 1: + res = v->ob_digit[0]; + break; + default: + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) + v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + *overflow = sign; + goto exit; + } + } + /* Haven't lost any bits, but casting to long requires extra + * care (see comment above). + */ + if (x <= (unsigned long)LONG_MAX) { + res = (long)x * sign; + } + else if (sign < 0 && x == PY_ABS_LONG_MIN) { + res = LONG_MIN; + } + else { + *overflow = sign; + /* res is already set to -1 */ + } } - else if (sign < 0 && x == PY_ABS_LONG_MIN) { - return LONG_MIN; + exit: + if (do_decref) { + Py_DECREF(vv); } - /* else overflow */ + return res; +} - overflow: - PyErr_SetString(PyExc_OverflowError, - "long int too large to convert to int"); - return -1; +/* Get a C long int from a long int object. + Returns -1 and sets an error condition if overflow occurs. */ + +long +PyLong_AsLong(PyObject *obj) +{ + int overflow; + long result = PyLong_AsLongAndOverflow(obj, &overflow); + if (overflow) { + /* XXX: could be cute and give a different + message for overflow == -1 */ + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C long"); + } + return result; } /* Get a Py_ssize_t from a long int object. From python-checkins at python.org Mon Dec 21 12:21:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 11:21:59 -0000 Subject: [Python-checkins] r76964 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Dec 21 12:21:59 2009 New Revision: 76964 Log: Blocked revisions 76963 via svnmerge ........ r76963 | mark.dickinson | 2009-12-21 11:21:25 +0000 (Mon, 21 Dec 2009) | 3 lines Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk. Thanks Case Van Horsen for the patch. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 21 12:22:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 11:22:47 -0000 Subject: [Python-checkins] r76965 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Mon Dec 21 12:22:47 2009 New Revision: 76965 Log: Blocked revisions 76963 via svnmerge ........ r76963 | mark.dickinson | 2009-12-21 11:21:25 +0000 (Mon, 21 Dec 2009) | 3 lines Issue #7528: Backport PyLong_AsLongAndOverflow from py3k to trunk. Thanks Case Van Horsen for the patch. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Dec 21 12:26:17 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 11:26:17 -0000 Subject: [Python-checkins] r76966 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Mon Dec 21 12:26:17 2009 New Revision: 76966 Log: fixed import Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Mon Dec 21 12:26:17 2009 @@ -453,7 +453,7 @@ function ``interpret_marker`` provided in the ``distutils.util`` module in the stdlib:: - >>> from distutils.util import + >>> from distutils.util import interpret_marker >>> interpret_marker("sys.platform == 'win32'") True From python-checkins at python.org Mon Dec 21 12:31:55 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 11:31:55 -0000 Subject: [Python-checkins] r76967 - python/trunk/Modules/_testcapimodule.c Message-ID: Author: mark.dickinson Date: Mon Dec 21 12:31:54 2009 New Revision: 76967 Log: Fix reference counts for test_long_and_overflow. Modified: python/trunk/Modules/_testcapimodule.c Modified: python/trunk/Modules/_testcapimodule.c ============================================================================== --- python/trunk/Modules/_testcapimodule.c (original) +++ python/trunk/Modules/_testcapimodule.c Mon Dec 21 12:31:54 2009 @@ -388,6 +388,8 @@ return raiseTestError("test_long_and_overflow", "overflow was not set to 0"); + Py_DECREF(num); + /* a number smaller than LONG_MIN even on 64-bit platforms */ num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); if (num == NULL) @@ -406,6 +408,8 @@ return raiseTestError("test_long_and_overflow", "overflow was not set to 0"); + Py_DECREF(num); + num = PyLong_FromString("FF", NULL, 16); if (num == NULL) return NULL; @@ -423,6 +427,8 @@ return raiseTestError("test_long_and_overflow", "overflow was set incorrectly"); + Py_DECREF(num); + Py_INCREF(Py_None); return Py_None; } From python-checkins at python.org Mon Dec 21 13:15:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 12:15:49 -0000 Subject: [Python-checkins] r76968 - python/trunk/Modules/_testcapimodule.c Message-ID: Author: mark.dickinson Date: Mon Dec 21 13:15:48 2009 New Revision: 76968 Log: Additional edge-case tests for test_long_and_overflow. Modified: python/trunk/Modules/_testcapimodule.c Modified: python/trunk/Modules/_testcapimodule.c ============================================================================== --- python/trunk/Modules/_testcapimodule.c (original) +++ python/trunk/Modules/_testcapimodule.c Mon Dec 21 13:15:48 2009 @@ -366,68 +366,158 @@ static PyObject * test_long_and_overflow(PyObject *self) { - PyObject *num; + PyObject *num, *one, *temp; long value; int overflow; - /* a number larger than LONG_MAX even on 64-bit platforms */ + /* Test that overflow is set properly for a large value. */ + /* num is a number larger than LONG_MAX even on 64-bit platforms */ num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); if (num == NULL) return NULL; - - /* Test that overflow is set properly for a large value. */ overflow = 1234; value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); if (overflow != 1) return raiseTestError("test_long_and_overflow", "overflow was not set to 1"); + /* Same again, with num = LONG_MAX + 1 */ + num = PyLong_FromLong(LONG_MAX); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Add(num, one); + Py_DECREF(one); + Py_DECREF(num); + num = temp; + if (num == NULL) + return NULL; overflow = 0; value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); if (overflow != 1) return raiseTestError("test_long_and_overflow", - "overflow was not set to 0"); - - Py_DECREF(num); + "overflow was not set to 1"); - /* a number smaller than LONG_MIN even on 64-bit platforms */ + /* Test that overflow is set properly for a large negative value. */ + /* num is a number smaller than LONG_MIN even on 64-bit platforms */ num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); if (num == NULL) return NULL; - - /* Test that overflow is set properly for a large negative value. */ overflow = 1234; value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); if (overflow != -1) return raiseTestError("test_long_and_overflow", "overflow was not set to -1"); + /* Same again, with num = LONG_MIN - 1 */ + num = PyLong_FromLong(LONG_MIN); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Subtract(num, one); + Py_DECREF(one); + Py_DECREF(num); + num = temp; + if (num == NULL) + return NULL; overflow = 0; value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); if (overflow != -1) return raiseTestError("test_long_and_overflow", - "overflow was not set to 0"); - - Py_DECREF(num); + "overflow was not set to -1"); + /* Test that overflow is cleared properly for small values. */ num = PyLong_FromString("FF", NULL, 16); if (num == NULL) return NULL; - - /* Test that overflow is cleared properly for a small value. */ overflow = 1234; value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != 0xFF) + return raiseTestError("test_long_and_overflow", + "expected return value 0xFF"); if (overflow != 0) return raiseTestError("test_long_and_overflow", "overflow was not cleared"); + num = PyLong_FromString("-FF", NULL, 16); + if (num == NULL) + return NULL; overflow = 0; value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -0xFF) + return raiseTestError("test_long_and_overflow", + "expected return value 0xFF"); if (overflow != 0) return raiseTestError("test_long_and_overflow", "overflow was set incorrectly"); + num = PyLong_FromLong(LONG_MAX); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LONG_MAX) + return raiseTestError("test_long_and_overflow", + "expected return value LONG_MAX"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromLong(LONG_MIN); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LONG_MIN) + return raiseTestError("test_long_and_overflow", + "expected return value LONG_MIN"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); Py_INCREF(Py_None); return Py_None; @@ -1116,7 +1206,8 @@ {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, {"test_lazy_hash_inheritance", (PyCFunction)test_lazy_hash_inheritance,METH_NOARGS}, {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS}, - {"test_long_and_overflow", (PyCFunction)test_long_and_overflow, METH_NOARGS}, + {"test_long_and_overflow", (PyCFunction)test_long_and_overflow, + METH_NOARGS}, {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, From python-checkins at python.org Mon Dec 21 13:17:43 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 12:17:43 -0000 Subject: [Python-checkins] r76969 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Dec 21 13:17:43 2009 New Revision: 76969 Log: Blocked revisions 76967-76968 via svnmerge ........ r76967 | mark.dickinson | 2009-12-21 11:31:54 +0000 (Mon, 21 Dec 2009) | 1 line Fix reference counts for test_long_and_overflow. ........ r76968 | mark.dickinson | 2009-12-21 12:15:48 +0000 (Mon, 21 Dec 2009) | 1 line Additional edge-case tests for test_long_and_overflow. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 21 13:18:09 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 12:18:09 -0000 Subject: [Python-checkins] r76970 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Mon Dec 21 13:18:09 2009 New Revision: 76970 Log: Blocked revisions 76967-76968 via svnmerge ........ r76967 | mark.dickinson | 2009-12-21 11:31:54 +0000 (Mon, 21 Dec 2009) | 1 line Fix reference counts for test_long_and_overflow. ........ r76968 | mark.dickinson | 2009-12-21 12:15:48 +0000 (Mon, 21 Dec 2009) | 1 line Additional edge-case tests for test_long_and_overflow. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Dec 21 13:37:07 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 12:37:07 -0000 Subject: [Python-checkins] r76971 - in python/branches/py3k: Doc/c-api/long.rst Modules/_testcapimodule.c Objects/longobject.c Message-ID: Author: mark.dickinson Date: Mon Dec 21 13:37:06 2009 New Revision: 76971 Log: Keep PyLong_AsLongAndOverflow documentation and implementation in sync between py3k and trunk; merge new tests from trunk to py3k. (See issue #7528.) Modified: python/branches/py3k/Doc/c-api/long.rst python/branches/py3k/Modules/_testcapimodule.c python/branches/py3k/Objects/longobject.c 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 Dec 21 13:37:06 2009 @@ -121,10 +121,13 @@ .. cfunction:: long PyLong_AsLongAndOverflow(PyObject *pylong, int* overflow) - Return a C :ctype:`long` representation of the contents of *pylong*. If - *pylong* is greater than :const:`LONG_MAX`, return -1 and - set `*overflow` to 1 (for overflow) or -1 (for underflow). - If an exception is set because of type errors, also return -1. + Return a C :ctype:`long` representation of the contents of + *pylong*. If *pylong* is greater than :const:`LONG_MAX` or less + than :const:`LONG_MIN`, set `*overflow` to ``1`` or ``-1``, + respectively, and return ``-1``; otherwise, set `*overflow` to + ``0``. If any other exception occurs (for example a TypeError or + MemoryError), then ``-1`` will be returned and ``*overflow`` will + be ``0``. .. cfunction:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong) Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Mon Dec 21 13:37:06 2009 @@ -359,6 +359,171 @@ #undef F_U_TO_PY #undef F_PY_TO_U +/* Test the PyLong_AsLongAndOverflow API. General conversion to PY_LONG + is tested by test_long_api_inner. This test will concentrate on proper + handling of overflow. +*/ + +static PyObject * +test_long_and_overflow(PyObject *self) +{ + PyObject *num, *one, *temp; + long value; + int overflow; + + /* Test that overflow is set properly for a large value. */ + /* num is a number larger than LONG_MAX even on 64-bit platforms */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to 1"); + + /* Same again, with num = LONG_MAX + 1 */ + num = PyLong_FromLong(LONG_MAX); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Add(num, one); + Py_DECREF(one); + Py_DECREF(num); + num = temp; + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to 1"); + + /* Test that overflow is set properly for a large negative value. */ + /* num is a number smaller than LONG_MIN even on 64-bit platforms */ + num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to -1"); + + /* Same again, with num = LONG_MIN - 1 */ + num = PyLong_FromLong(LONG_MIN); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Subtract(num, one); + Py_DECREF(one); + Py_DECREF(num); + num = temp; + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to -1"); + + /* Test that overflow is cleared properly for small values. */ + num = PyLong_FromString("FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != 0xFF) + return raiseTestError("test_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromString("-FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -0xFF) + return raiseTestError("test_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was set incorrectly"); + + num = PyLong_FromLong(LONG_MAX); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LONG_MAX) + return raiseTestError("test_long_and_overflow", + "expected return value LONG_MAX"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromLong(LONG_MIN); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LONG_MIN) + return raiseTestError("test_long_and_overflow", + "expected return value LONG_MIN"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + Py_INCREF(Py_None); + return Py_None; +} + /* Test the L code for PyArg_ParseTuple. This should deliver a PY_LONG_LONG for both long and int arguments. The test may leak a little memory if it fails. @@ -1560,6 +1725,8 @@ {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, {"test_lazy_hash_inheritance", (PyCFunction)test_lazy_hash_inheritance,METH_NOARGS}, {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS}, + {"test_long_and_overflow", (PyCFunction)test_long_and_overflow, + METH_NOARGS}, {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Mon Dec 21 13:37:06 2009 @@ -346,9 +346,10 @@ if (!PyLong_Check(vv)) { PyNumberMethods *nb; - if ((nb = vv->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); + nb = vv->ob_type->tp_as_number; + if (nb == NULL || nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); return -1; } vv = (*nb->nb_int) (vv); @@ -388,13 +389,13 @@ prev = x; x = (x << PyLong_SHIFT) | v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { - *overflow = Py_SIZE(v) > 0 ? 1 : -1; + *overflow = sign; goto exit; } } - /* Haven't lost any bits, but casting to long requires extra care - * (see comment above). - */ + /* Haven't lost any bits, but casting to long requires extra + * care (see comment above). + */ if (x <= (unsigned long)LONG_MAX) { res = (long)x * sign; } @@ -402,9 +403,9 @@ res = LONG_MIN; } else { - *overflow = Py_SIZE(v) > 0 ? 1 : -1; + *overflow = sign; /* res is already set to -1 */ - } + } } exit: if (do_decref) { From python-checkins at python.org Mon Dec 21 13:37:39 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 12:37:39 -0000 Subject: [Python-checkins] r76972 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Mon Dec 21 13:37:38 2009 New Revision: 76972 Log: Blocked revisions 76971 via svnmerge ........ r76971 | mark.dickinson | 2009-12-21 12:37:06 +0000 (Mon, 21 Dec 2009) | 4 lines Keep PyLong_AsLongAndOverflow documentation and implementation in sync between py3k and trunk; merge new tests from trunk to py3k. (See issue #7528.) ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Dec 21 13:45:42 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 21 Dec 2009 12:45:42 -0000 Subject: [Python-checkins] r76973 - python/trunk/Lib/doctest.py Message-ID: Author: r.david.murray Date: Mon Dec 21 13:45:41 2009 New Revision: 76973 Log: Remove a leftover from a previous iteration of the issue 7376 patch. Modified: python/trunk/Lib/doctest.py Modified: python/trunk/Lib/doctest.py ============================================================================== --- python/trunk/Lib/doctest.py (original) +++ python/trunk/Lib/doctest.py Mon Dec 21 13:45:41 2009 @@ -2665,7 +2665,7 @@ testfiles = [arg for arg in sys.argv[1:] if arg and arg[0] != '-'] if not testfiles: name = os.path.basename(sys.argv[0]) - if '__loader__' in globals() and name.endswith('.py'): # python -m + if '__loader__' in globals(): # python -m name, _ = os.path.splitext(name) print("usage: {0} [-v] file ...".format(name)) return 2 From python-checkins at python.org Mon Dec 21 13:46:56 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 21 Dec 2009 12:46:56 -0000 Subject: [Python-checkins] r76974 - python/branches/release26-maint Message-ID: Author: r.david.murray Date: Mon Dec 21 13:46:56 2009 New Revision: 76974 Log: Blocked revisions 76973 via svnmerge ........ r76973 | r.david.murray | 2009-12-21 07:45:41 -0500 (Mon, 21 Dec 2009) | 2 lines Remove a leftover from a previous iteration of the issue 7376 patch. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 21 13:50:02 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 21 Dec 2009 12:50:02 -0000 Subject: [Python-checkins] r76975 - in python/branches/py3k: Lib/doctest.py Message-ID: Author: r.david.murray Date: Mon Dec 21 13:50:02 2009 New Revision: 76975 Log: Merged revisions 76973 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76973 | r.david.murray | 2009-12-21 07:45:41 -0500 (Mon, 21 Dec 2009) | 2 lines Remove a leftover from a previous iteration of the issue 7376 patch. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/doctest.py Modified: python/branches/py3k/Lib/doctest.py ============================================================================== --- python/branches/py3k/Lib/doctest.py (original) +++ python/branches/py3k/Lib/doctest.py Mon Dec 21 13:50:02 2009 @@ -2616,7 +2616,7 @@ testfiles = [arg for arg in sys.argv[1:] if arg and arg[0] != '-'] if not testfiles: name = os.path.basename(sys.argv[0]) - if '__loader__' in globals() and name.endswith('.py'): # python -m + if '__loader__' in globals(): # python -m name, _ = os.path.splitext(name) print("usage: {0} [-v] file ...".format(name)) return 2 From python-checkins at python.org Mon Dec 21 13:53:36 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 21 Dec 2009 12:53:36 -0000 Subject: [Python-checkins] r76976 - in python/branches/release31-maint: Lib/doctest.py Message-ID: Author: r.david.murray Date: Mon Dec 21 13:53:36 2009 New Revision: 76976 Log: Merged revisions 76975 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76975 | r.david.murray | 2009-12-21 07:50:02 -0500 (Mon, 21 Dec 2009) | 9 lines Merged revisions 76973 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76973 | r.david.murray | 2009-12-21 07:45:41 -0500 (Mon, 21 Dec 2009) | 2 lines Remove a leftover from a previous iteration of the issue 7376 patch. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/doctest.py Modified: python/branches/release31-maint/Lib/doctest.py ============================================================================== --- python/branches/release31-maint/Lib/doctest.py (original) +++ python/branches/release31-maint/Lib/doctest.py Mon Dec 21 13:53:36 2009 @@ -2616,7 +2616,7 @@ testfiles = [arg for arg in sys.argv[1:] if arg and arg[0] != '-'] if not testfiles: name = os.path.basename(sys.argv[0]) - if '__loader__' in globals() and name.endswith('.py'): # python -m + if '__loader__' in globals(): # python -m name, _ = os.path.splitext(name) print("usage: {0} [-v] file ...".format(name)) return 2 From python-checkins at python.org Mon Dec 21 16:22:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 15:22:00 -0000 Subject: [Python-checkins] r76978 - in python/trunk: Include/pymath.h Modules/Setup.dist Modules/_math.c Modules/_math.h Modules/cmathmodule.c Modules/mathmodule.c Python/pymath.c setup.py Message-ID: Author: mark.dickinson Date: Mon Dec 21 16:22:00 2009 New Revision: 76978 Log: Issue #7518: Move substitute definitions of C99 math functions from pymath.c to Modules/_math.c. Modified: python/trunk/Include/pymath.h python/trunk/Modules/Setup.dist python/trunk/Modules/_math.c python/trunk/Modules/_math.h python/trunk/Modules/cmathmodule.c python/trunk/Modules/mathmodule.c python/trunk/Python/pymath.c python/trunk/setup.py Modified: python/trunk/Include/pymath.h ============================================================================== --- python/trunk/Include/pymath.h (original) +++ python/trunk/Include/pymath.h Mon Dec 21 16:22:00 2009 @@ -8,9 +8,9 @@ functions and constants **************************************************************************/ -/* Python provides implementations for copysign, acosh, asinh, atanh, - * log1p and hypot in Python/pymath.c just in case your math library doesn't - * provide the functions. +/* Python provides implementations for copysign, round and hypot in + * Python/pymath.c just in case your math library doesn't provide the + * functions. * *Note: PC/pyconfig.h defines copysign as _copysign */ @@ -22,22 +22,6 @@ extern double round(double); #endif -#ifndef HAVE_ACOSH -extern double acosh(double); -#endif - -#ifndef HAVE_ASINH -extern double asinh(double); -#endif - -#ifndef HAVE_ATANH -extern double atanh(double); -#endif - -#ifndef HAVE_LOG1P -extern double log1p(double); -#endif - #ifndef HAVE_HYPOT extern double hypot(double, double); #endif Modified: python/trunk/Modules/Setup.dist ============================================================================== --- python/trunk/Modules/Setup.dist (original) +++ python/trunk/Modules/Setup.dist Mon Dec 21 16:22:00 2009 @@ -168,7 +168,7 @@ # Modules that should always be present (non UNIX dependent): #array arraymodule.c # array objects -#cmath cmathmodule.c # -lm # complex math library functions +#cmath cmathmodule.c _math.c # -lm # complex math library functions #math mathmodule.c _math.c # -lm # math library functions, e.g. sin() #_struct _struct.c # binary structure packing/unpacking #time timemodule.c # -lm # time operations and variables Modified: python/trunk/Modules/_math.c ============================================================================== --- python/trunk/Modules/_math.c (original) +++ python/trunk/Modules/_math.c Mon Dec 21 16:22:00 2009 @@ -1,8 +1,161 @@ /* Definitions of some C99 math library functions, for those platforms that don't implement these functions already. */ +#include "Python.h" #include -#include + +/* The following copyright notice applies to the original + implementations of acosh, asinh and atanh. */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +static const double ln2 = 6.93147180559945286227E-01; +static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */ +static const double two_pow_p28 = 268435456.0; /* 2**28 */ +static const double zero = 0.0; + +/* acosh(x) + * Method : + * Based on + * acosh(x) = log [ x + sqrt(x*x-1) ] + * we have + * acosh(x) := log(x)+ln2, if x is large; else + * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else + * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. + * + * Special cases: + * acosh(x) is NaN with signal if x<1. + * acosh(NaN) is NaN without signal. + */ + +double +_Py_acosh(double x) +{ + if (Py_IS_NAN(x)) { + return x+x; + } + if (x < 1.) { /* x < 1; return a signaling NaN */ + errno = EDOM; +#ifdef Py_NAN + return Py_NAN; +#else + return (x-x)/(x-x); +#endif + } + else if (x >= two_pow_p28) { /* x > 2**28 */ + if (Py_IS_INFINITY(x)) { + return x+x; + } else { + return log(x)+ln2; /* acosh(huge)=log(2x) */ + } + } + else if (x == 1.) { + return 0.0; /* acosh(1) = 0 */ + } + else if (x > 2.) { /* 2 < x < 2**28 */ + double t = x*x; + return log(2.0*x - 1.0 / (x + sqrt(t - 1.0))); + } + else { /* 1 < x <= 2 */ + double t = x - 1.0; + return log1p(t + sqrt(2.0*t + t*t)); + } +} + + +/* asinh(x) + * Method : + * Based on + * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] + * we have + * asinh(x) := x if 1+x*x=1, + * := sign(x)*(log(x)+ln2)) for large |x|, else + * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else + * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) + */ + +double +_Py_asinh(double x) +{ + double w; + double absx = fabs(x); + + if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { + return x+x; + } + if (absx < two_pow_m28) { /* |x| < 2**-28 */ + return x; /* return x inexact except 0 */ + } + if (absx > two_pow_p28) { /* |x| > 2**28 */ + w = log(absx)+ln2; + } + else if (absx > 2.0) { /* 2 < |x| < 2**28 */ + w = log(2.0*absx + 1.0 / (sqrt(x*x + 1.0) + absx)); + } + else { /* 2**-28 <= |x| < 2= */ + double t = x*x; + w = log1p(absx + t / (1.0 + sqrt(1.0 + t))); + } + return copysign(w, x); + +} + +/* atanh(x) + * Method : + * 1.Reduced x to positive by atanh(-x) = -atanh(x) + * 2.For x>=0.5 + * 1 2x x + * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + * 2 1 - x 1 - x + * + * For x<0.5 + * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) + * + * Special cases: + * atanh(x) is NaN if |x| >= 1 with signal; + * atanh(NaN) is that NaN with no signal; + * + */ + +double +_Py_atanh(double x) +{ + double absx; + double t; + + if (Py_IS_NAN(x)) { + return x+x; + } + absx = fabs(x); + if (absx >= 1.) { /* |x| >= 1 */ + errno = EDOM; +#ifdef Py_NAN + return Py_NAN; +#else + return x/zero; +#endif + } + if (absx < two_pow_m28) { /* |x| < 2**-28 */ + return x; + } + if (absx < 0.5) { /* |x| < 0.5 */ + t = absx+absx; + t = 0.5 * log1p(t + t*absx / (1.0 - absx)); + } + else { /* 0.5 <= |x| <= 1.0 */ + t = 0.5 * log1p((absx + absx) / (1.0 - absx)); + } + return copysign(t, x); +} /* Mathematically, expm1(x) = exp(x) - 1. The expm1 function is designed to avoid the significant loss of precision that arises from direct @@ -29,3 +182,47 @@ else return exp(x) - 1.0; } + +/* log1p(x) = log(1+x). The log1p function is designed to avoid the + significant loss of precision that arises from direct evaluation when x is + small. */ + +double +_Py_log1p(double x) +{ + /* For x small, we use the following approach. Let y be the nearest float + to 1+x, then + + 1+x = y * (1 - (y-1-x)/y) + + so log(1+x) = log(y) + log(1-(y-1-x)/y). Since (y-1-x)/y is tiny, the + second term is well approximated by (y-1-x)/y. If abs(x) >= + DBL_EPSILON/2 or the rounding-mode is some form of round-to-nearest + then y-1-x will be exactly representable, and is computed exactly by + (y-1)-x. + + If abs(x) < DBL_EPSILON/2 and the rounding mode is not known to be + round-to-nearest then this method is slightly dangerous: 1+x could be + rounded up to 1+DBL_EPSILON instead of down to 1, and in that case + y-1-x will not be exactly representable any more and the result can be + off by many ulps. But this is easily fixed: for a floating-point + number |x| < DBL_EPSILON/2., the closest floating-point number to + log(1+x) is exactly x. + */ + + double y; + if (fabs(x) < DBL_EPSILON/2.) { + return x; + } else if (-0.5 <= x && x <= 1.) { + /* WARNING: it's possible than an overeager compiler + will incorrectly optimize the following two lines + to the equivalent of "return log(1.+x)". If this + happens, then results from log1p will be inaccurate + for small x. */ + y = 1.+x; + return log(y)-((y-1.)-x)/y; + } else { + /* NaNs and infinities should end up here */ + return log(1.+x); + } +} Modified: python/trunk/Modules/_math.h ============================================================================== --- python/trunk/Modules/_math.h (original) +++ python/trunk/Modules/_math.h Mon Dec 21 16:22:00 2009 @@ -1,4 +1,32 @@ +double _Py_acosh(double x); +double _Py_asinh(double x); +double _Py_atanh(double x); double _Py_expm1(double x); +double _Py_log1p(double x); + +#ifdef HAVE_ACOSH +#define m_acosh acosh +#else +/* if the system doesn't have acosh, use the substitute + function defined in Modules/_math.c. */ +#define m_acosh _Py_acosh +#endif + +#ifdef HAVE_ASINH +#define m_asinh asinh +#else +/* if the system doesn't have asinh, use the substitute + function defined in Modules/_math.c. */ +#define m_asinh _Py_asinh +#endif + +#ifdef HAVE_ATANH +#define m_atanh atanh +#else +/* if the system doesn't have atanh, use the substitute + function defined in Modules/_math.c. */ +#define m_atanh _Py_atanh +#endif #ifdef HAVE_EXPM1 #define m_expm1 expm1 @@ -7,3 +35,11 @@ function defined in Modules/_math.c. */ #define m_expm1 _Py_expm1 #endif + +#ifdef HAVE_LOG1P +#define m_log1p log1p +#else +/* if the system doesn't have log1p, use the substitute + function defined in Modules/_math.c. */ +#define m_log1p _Py_log1p +#endif Modified: python/trunk/Modules/cmathmodule.c ============================================================================== --- python/trunk/Modules/cmathmodule.c (original) +++ python/trunk/Modules/cmathmodule.c Mon Dec 21 16:22:00 2009 @@ -3,6 +3,7 @@ /* much code borrowed from mathmodule.c */ #include "Python.h" +#include "_math.h" /* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from float.h. We assume that FLT_RADIX is either 2 or 16. */ #include @@ -149,7 +150,7 @@ s2.imag = z.imag; s2 = c_sqrt(s2); r.real = 2.*atan2(s1.real, s2.real); - r.imag = asinh(s2.real*s1.imag - s2.imag*s1.real); + r.imag = m_asinh(s2.real*s1.imag - s2.imag*s1.real); } errno = 0; return r; @@ -181,7 +182,7 @@ s2.real = z.real + 1.; s2.imag = z.imag; s2 = c_sqrt(s2); - r.real = asinh(s1.real*s2.real + s1.imag*s2.imag); + r.real = m_asinh(s1.real*s2.real + s1.imag*s2.imag); r.imag = 2.*atan2(s1.imag, s2.real); } errno = 0; @@ -238,7 +239,7 @@ s2.real = 1.-z.imag; s2.imag = z.real; s2 = c_sqrt(s2); - r.real = asinh(s1.real*s2.imag-s2.real*s1.imag); + r.real = m_asinh(s1.real*s2.imag-s2.real*s1.imag); r.imag = atan2(z.imag, s1.real*s2.real-s1.imag*s2.imag); } errno = 0; @@ -342,7 +343,7 @@ errno = 0; } } else { - r.real = log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.; + r.real = m_log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.; r.imag = -atan2(-2.*z.imag, (1-z.real)*(1+z.real) - ay*ay)/2.; errno = 0; } @@ -552,7 +553,7 @@ if (0.71 <= h && h <= 1.73) { am = ax > ay ? ax : ay; /* max(ax, ay) */ an = ax > ay ? ay : ax; /* min(ax, ay) */ - r.real = log1p((am-1)*(am+1)+an*an)/2.; + r.real = m_log1p((am-1)*(am+1)+an*an)/2.; } else { r.real = log(h); } Modified: python/trunk/Modules/mathmodule.c ============================================================================== --- python/trunk/Modules/mathmodule.c (original) +++ python/trunk/Modules/mathmodule.c Mon Dec 21 16:22:00 2009 @@ -799,18 +799,18 @@ FUNC1(acos, acos, 0, "acos(x)\n\nReturn the arc cosine (measured in radians) of x.") -FUNC1(acosh, acosh, 0, +FUNC1(acosh, m_acosh, 0, "acosh(x)\n\nReturn the hyperbolic arc cosine (measured in radians) of x.") FUNC1(asin, asin, 0, "asin(x)\n\nReturn the arc sine (measured in radians) of x.") -FUNC1(asinh, asinh, 0, +FUNC1(asinh, m_asinh, 0, "asinh(x)\n\nReturn the hyperbolic arc sine (measured in radians) of x.") FUNC1(atan, atan, 0, "atan(x)\n\nReturn the arc tangent (measured in radians) of x.") FUNC2(atan2, m_atan2, "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n" "Unlike atan(y/x), the signs of both x and y are considered.") -FUNC1(atanh, atanh, 0, +FUNC1(atanh, m_atanh, 0, "atanh(x)\n\nReturn the hyperbolic arc tangent (measured in radians) of x.") FUNC1(ceil, ceil, 0, "ceil(x)\n\nReturn the ceiling of x as a float.\n" @@ -840,7 +840,7 @@ "gamma(x)\n\nGamma function at x.") FUNC1A(lgamma, m_lgamma, "lgamma(x)\n\nNatural logarithm of absolute value of Gamma function at x.") -FUNC1(log1p, log1p, 1, +FUNC1(log1p, m_log1p, 1, "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n" "The result is computed in a way which is accurate for x near zero.") FUNC1(sin, sin, 0, Modified: python/trunk/Python/pymath.c ============================================================================== --- python/trunk/Python/pymath.c (original) +++ python/trunk/Python/pymath.c Mon Dec 21 16:22:00 2009 @@ -77,202 +77,3 @@ return copysign(y, x); } #endif /* HAVE_ROUND */ - -#ifndef HAVE_LOG1P -#include - -double -log1p(double x) -{ - /* For x small, we use the following approach. Let y be the nearest - float to 1+x, then - - 1+x = y * (1 - (y-1-x)/y) - - so log(1+x) = log(y) + log(1-(y-1-x)/y). Since (y-1-x)/y is tiny, - the second term is well approximated by (y-1-x)/y. If abs(x) >= - DBL_EPSILON/2 or the rounding-mode is some form of round-to-nearest - then y-1-x will be exactly representable, and is computed exactly - by (y-1)-x. - - If abs(x) < DBL_EPSILON/2 and the rounding mode is not known to be - round-to-nearest then this method is slightly dangerous: 1+x could - be rounded up to 1+DBL_EPSILON instead of down to 1, and in that - case y-1-x will not be exactly representable any more and the - result can be off by many ulps. But this is easily fixed: for a - floating-point number |x| < DBL_EPSILON/2., the closest - floating-point number to log(1+x) is exactly x. - */ - - double y; - if (fabs(x) < DBL_EPSILON/2.) { - return x; - } else if (-0.5 <= x && x <= 1.) { - /* WARNING: it's possible than an overeager compiler - will incorrectly optimize the following two lines - to the equivalent of "return log(1.+x)". If this - happens, then results from log1p will be inaccurate - for small x. */ - y = 1.+x; - return log(y)-((y-1.)-x)/y; - } else { - /* NaNs and infinities should end up here */ - return log(1.+x); - } -} -#endif /* HAVE_LOG1P */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -static const double ln2 = 6.93147180559945286227E-01; -static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */ -static const double two_pow_p28 = 268435456.0; /* 2**28 */ -static const double zero = 0.0; - -/* asinh(x) - * Method : - * Based on - * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] - * we have - * asinh(x) := x if 1+x*x=1, - * := sign(x)*(log(x)+ln2)) for large |x|, else - * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else - * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) - */ - -#ifndef HAVE_ASINH -double -asinh(double x) -{ - double w; - double absx = fabs(x); - - if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { - return x+x; - } - if (absx < two_pow_m28) { /* |x| < 2**-28 */ - return x; /* return x inexact except 0 */ - } - if (absx > two_pow_p28) { /* |x| > 2**28 */ - w = log(absx)+ln2; - } - else if (absx > 2.0) { /* 2 < |x| < 2**28 */ - w = log(2.0*absx + 1.0 / (sqrt(x*x + 1.0) + absx)); - } - else { /* 2**-28 <= |x| < 2= */ - double t = x*x; - w = log1p(absx + t / (1.0 + sqrt(1.0 + t))); - } - return copysign(w, x); - -} -#endif /* HAVE_ASINH */ - -/* acosh(x) - * Method : - * Based on - * acosh(x) = log [ x + sqrt(x*x-1) ] - * we have - * acosh(x) := log(x)+ln2, if x is large; else - * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else - * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. - * - * Special cases: - * acosh(x) is NaN with signal if x<1. - * acosh(NaN) is NaN without signal. - */ - -#ifndef HAVE_ACOSH -double -acosh(double x) -{ - if (Py_IS_NAN(x)) { - return x+x; - } - if (x < 1.) { /* x < 1; return a signaling NaN */ - errno = EDOM; -#ifdef Py_NAN - return Py_NAN; -#else - return (x-x)/(x-x); -#endif - } - else if (x >= two_pow_p28) { /* x > 2**28 */ - if (Py_IS_INFINITY(x)) { - return x+x; - } else { - return log(x)+ln2; /* acosh(huge)=log(2x) */ - } - } - else if (x == 1.) { - return 0.0; /* acosh(1) = 0 */ - } - else if (x > 2.) { /* 2 < x < 2**28 */ - double t = x*x; - return log(2.0*x - 1.0 / (x + sqrt(t - 1.0))); - } - else { /* 1 < x <= 2 */ - double t = x - 1.0; - return log1p(t + sqrt(2.0*t + t*t)); - } -} -#endif /* HAVE_ACOSH */ - -/* atanh(x) - * Method : - * 1.Reduced x to positive by atanh(-x) = -atanh(x) - * 2.For x>=0.5 - * 1 2x x - * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) - * 2 1 - x 1 - x - * - * For x<0.5 - * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) - * - * Special cases: - * atanh(x) is NaN if |x| >= 1 with signal; - * atanh(NaN) is that NaN with no signal; - * - */ - -#ifndef HAVE_ATANH -double -atanh(double x) -{ - double absx; - double t; - - if (Py_IS_NAN(x)) { - return x+x; - } - absx = fabs(x); - if (absx >= 1.) { /* |x| >= 1 */ - errno = EDOM; -#ifdef Py_NAN - return Py_NAN; -#else - return x/zero; -#endif - } - if (absx < two_pow_m28) { /* |x| < 2**-28 */ - return x; - } - if (absx < 0.5) { /* |x| < 0.5 */ - t = absx+absx; - t = 0.5 * log1p(t + t*absx / (1.0 - absx)); - } - else { /* 0.5 <= |x| <= 1.0 */ - t = 0.5 * log1p((absx + absx) / (1.0 - absx)); - } - return copysign(t, x); -} -#endif /* HAVE_ATANH */ Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Mon Dec 21 16:22:00 2009 @@ -410,9 +410,9 @@ # array objects exts.append( Extension('array', ['arraymodule.c']) ) # complex math library functions - exts.append( Extension('cmath', ['cmathmodule.c'], + exts.append( Extension('cmath', ['cmathmodule.c', '_math.c'], + depends=['_math.h'], libraries=math_libs) ) - # math library functions, e.g. sin() exts.append( Extension('math', ['mathmodule.c', '_math.c'], depends=['_math.h'], From python-checkins at python.org Mon Dec 21 16:22:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 15:22:24 -0000 Subject: [Python-checkins] r76979 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Dec 21 16:22:24 2009 New Revision: 76979 Log: Blocked revisions 76978 via svnmerge ........ r76978 | mark.dickinson | 2009-12-21 15:22:00 +0000 (Mon, 21 Dec 2009) | 3 lines Issue #7518: Move substitute definitions of C99 math functions from pymath.c to Modules/_math.c. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 21 16:27:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 15:27:41 -0000 Subject: [Python-checkins] r76980 - in python/branches/py3k: Include/pymath.h Modules/Setup.dist Modules/_math.c Modules/_math.h Modules/cmathmodule.c Modules/mathmodule.c Python/pymath.c setup.py Message-ID: Author: mark.dickinson Date: Mon Dec 21 16:27:41 2009 New Revision: 76980 Log: Merged revisions 76978 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76978 | mark.dickinson | 2009-12-21 15:22:00 +0000 (Mon, 21 Dec 2009) | 3 lines Issue #7518: Move substitute definitions of C99 math functions from pymath.c to Modules/_math.c. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/pymath.h python/branches/py3k/Modules/Setup.dist python/branches/py3k/Modules/_math.c python/branches/py3k/Modules/_math.h python/branches/py3k/Modules/cmathmodule.c python/branches/py3k/Modules/mathmodule.c python/branches/py3k/Python/pymath.c python/branches/py3k/setup.py Modified: python/branches/py3k/Include/pymath.h ============================================================================== --- python/branches/py3k/Include/pymath.h (original) +++ python/branches/py3k/Include/pymath.h Mon Dec 21 16:27:41 2009 @@ -8,9 +8,9 @@ functions and constants **************************************************************************/ -/* Python provides implementations for copysign, acosh, asinh, atanh, - * log1p and hypot in Python/pymath.c just in case your math library doesn't - * provide the functions. +/* Python provides implementations for copysign, round and hypot in + * Python/pymath.c just in case your math library doesn't provide the + * functions. * *Note: PC/pyconfig.h defines copysign as _copysign */ @@ -22,22 +22,6 @@ extern double round(double); #endif -#ifndef HAVE_ACOSH -extern double acosh(double); -#endif - -#ifndef HAVE_ASINH -extern double asinh(double); -#endif - -#ifndef HAVE_ATANH -extern double atanh(double); -#endif - -#ifndef HAVE_LOG1P -extern double log1p(double); -#endif - #ifndef HAVE_HYPOT extern double hypot(double, double); #endif Modified: python/branches/py3k/Modules/Setup.dist ============================================================================== --- python/branches/py3k/Modules/Setup.dist (original) +++ python/branches/py3k/Modules/Setup.dist Mon Dec 21 16:27:41 2009 @@ -157,7 +157,7 @@ # Modules that should always be present (non UNIX dependent): #array arraymodule.c # array objects -#cmath cmathmodule.c # -lm # complex math library functions +#cmath cmathmodule.c _math.c # -lm # complex math library functions #math mathmodule.c _math.c # -lm # math library functions, e.g. sin() #_struct _struct.c # binary structure packing/unpacking #time timemodule.c # -lm # time operations and variables Modified: python/branches/py3k/Modules/_math.c ============================================================================== --- python/branches/py3k/Modules/_math.c (original) +++ python/branches/py3k/Modules/_math.c Mon Dec 21 16:27:41 2009 @@ -1,8 +1,161 @@ /* Definitions of some C99 math library functions, for those platforms that don't implement these functions already. */ +#include "Python.h" #include -#include + +/* The following copyright notice applies to the original + implementations of acosh, asinh and atanh. */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +static const double ln2 = 6.93147180559945286227E-01; +static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */ +static const double two_pow_p28 = 268435456.0; /* 2**28 */ +static const double zero = 0.0; + +/* acosh(x) + * Method : + * Based on + * acosh(x) = log [ x + sqrt(x*x-1) ] + * we have + * acosh(x) := log(x)+ln2, if x is large; else + * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else + * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. + * + * Special cases: + * acosh(x) is NaN with signal if x<1. + * acosh(NaN) is NaN without signal. + */ + +double +_Py_acosh(double x) +{ + if (Py_IS_NAN(x)) { + return x+x; + } + if (x < 1.) { /* x < 1; return a signaling NaN */ + errno = EDOM; +#ifdef Py_NAN + return Py_NAN; +#else + return (x-x)/(x-x); +#endif + } + else if (x >= two_pow_p28) { /* x > 2**28 */ + if (Py_IS_INFINITY(x)) { + return x+x; + } else { + return log(x)+ln2; /* acosh(huge)=log(2x) */ + } + } + else if (x == 1.) { + return 0.0; /* acosh(1) = 0 */ + } + else if (x > 2.) { /* 2 < x < 2**28 */ + double t = x*x; + return log(2.0*x - 1.0 / (x + sqrt(t - 1.0))); + } + else { /* 1 < x <= 2 */ + double t = x - 1.0; + return log1p(t + sqrt(2.0*t + t*t)); + } +} + + +/* asinh(x) + * Method : + * Based on + * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] + * we have + * asinh(x) := x if 1+x*x=1, + * := sign(x)*(log(x)+ln2)) for large |x|, else + * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else + * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) + */ + +double +_Py_asinh(double x) +{ + double w; + double absx = fabs(x); + + if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { + return x+x; + } + if (absx < two_pow_m28) { /* |x| < 2**-28 */ + return x; /* return x inexact except 0 */ + } + if (absx > two_pow_p28) { /* |x| > 2**28 */ + w = log(absx)+ln2; + } + else if (absx > 2.0) { /* 2 < |x| < 2**28 */ + w = log(2.0*absx + 1.0 / (sqrt(x*x + 1.0) + absx)); + } + else { /* 2**-28 <= |x| < 2= */ + double t = x*x; + w = log1p(absx + t / (1.0 + sqrt(1.0 + t))); + } + return copysign(w, x); + +} + +/* atanh(x) + * Method : + * 1.Reduced x to positive by atanh(-x) = -atanh(x) + * 2.For x>=0.5 + * 1 2x x + * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + * 2 1 - x 1 - x + * + * For x<0.5 + * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) + * + * Special cases: + * atanh(x) is NaN if |x| >= 1 with signal; + * atanh(NaN) is that NaN with no signal; + * + */ + +double +_Py_atanh(double x) +{ + double absx; + double t; + + if (Py_IS_NAN(x)) { + return x+x; + } + absx = fabs(x); + if (absx >= 1.) { /* |x| >= 1 */ + errno = EDOM; +#ifdef Py_NAN + return Py_NAN; +#else + return x/zero; +#endif + } + if (absx < two_pow_m28) { /* |x| < 2**-28 */ + return x; + } + if (absx < 0.5) { /* |x| < 0.5 */ + t = absx+absx; + t = 0.5 * log1p(t + t*absx / (1.0 - absx)); + } + else { /* 0.5 <= |x| <= 1.0 */ + t = 0.5 * log1p((absx + absx) / (1.0 - absx)); + } + return copysign(t, x); +} /* Mathematically, expm1(x) = exp(x) - 1. The expm1 function is designed to avoid the significant loss of precision that arises from direct @@ -29,3 +182,47 @@ else return exp(x) - 1.0; } + +/* log1p(x) = log(1+x). The log1p function is designed to avoid the + significant loss of precision that arises from direct evaluation when x is + small. */ + +double +_Py_log1p(double x) +{ + /* For x small, we use the following approach. Let y be the nearest float + to 1+x, then + + 1+x = y * (1 - (y-1-x)/y) + + so log(1+x) = log(y) + log(1-(y-1-x)/y). Since (y-1-x)/y is tiny, the + second term is well approximated by (y-1-x)/y. If abs(x) >= + DBL_EPSILON/2 or the rounding-mode is some form of round-to-nearest + then y-1-x will be exactly representable, and is computed exactly by + (y-1)-x. + + If abs(x) < DBL_EPSILON/2 and the rounding mode is not known to be + round-to-nearest then this method is slightly dangerous: 1+x could be + rounded up to 1+DBL_EPSILON instead of down to 1, and in that case + y-1-x will not be exactly representable any more and the result can be + off by many ulps. But this is easily fixed: for a floating-point + number |x| < DBL_EPSILON/2., the closest floating-point number to + log(1+x) is exactly x. + */ + + double y; + if (fabs(x) < DBL_EPSILON/2.) { + return x; + } else if (-0.5 <= x && x <= 1.) { + /* WARNING: it's possible than an overeager compiler + will incorrectly optimize the following two lines + to the equivalent of "return log(1.+x)". If this + happens, then results from log1p will be inaccurate + for small x. */ + y = 1.+x; + return log(y)-((y-1.)-x)/y; + } else { + /* NaNs and infinities should end up here */ + return log(1.+x); + } +} Modified: python/branches/py3k/Modules/_math.h ============================================================================== --- python/branches/py3k/Modules/_math.h (original) +++ python/branches/py3k/Modules/_math.h Mon Dec 21 16:27:41 2009 @@ -1,4 +1,32 @@ +double _Py_acosh(double x); +double _Py_asinh(double x); +double _Py_atanh(double x); double _Py_expm1(double x); +double _Py_log1p(double x); + +#ifdef HAVE_ACOSH +#define m_acosh acosh +#else +/* if the system doesn't have acosh, use the substitute + function defined in Modules/_math.c. */ +#define m_acosh _Py_acosh +#endif + +#ifdef HAVE_ASINH +#define m_asinh asinh +#else +/* if the system doesn't have asinh, use the substitute + function defined in Modules/_math.c. */ +#define m_asinh _Py_asinh +#endif + +#ifdef HAVE_ATANH +#define m_atanh atanh +#else +/* if the system doesn't have atanh, use the substitute + function defined in Modules/_math.c. */ +#define m_atanh _Py_atanh +#endif #ifdef HAVE_EXPM1 #define m_expm1 expm1 @@ -7,3 +35,11 @@ function defined in Modules/_math.c. */ #define m_expm1 _Py_expm1 #endif + +#ifdef HAVE_LOG1P +#define m_log1p log1p +#else +/* if the system doesn't have log1p, use the substitute + function defined in Modules/_math.c. */ +#define m_log1p _Py_log1p +#endif Modified: python/branches/py3k/Modules/cmathmodule.c ============================================================================== --- python/branches/py3k/Modules/cmathmodule.c (original) +++ python/branches/py3k/Modules/cmathmodule.c Mon Dec 21 16:27:41 2009 @@ -3,6 +3,7 @@ /* much code borrowed from mathmodule.c */ #include "Python.h" +#include "_math.h" /* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from float.h. We assume that FLT_RADIX is either 2 or 16. */ #include @@ -149,7 +150,7 @@ s2.imag = z.imag; s2 = c_sqrt(s2); r.real = 2.*atan2(s1.real, s2.real); - r.imag = asinh(s2.real*s1.imag - s2.imag*s1.real); + r.imag = m_asinh(s2.real*s1.imag - s2.imag*s1.real); } errno = 0; return r; @@ -181,7 +182,7 @@ s2.real = z.real + 1.; s2.imag = z.imag; s2 = c_sqrt(s2); - r.real = asinh(s1.real*s2.real + s1.imag*s2.imag); + r.real = m_asinh(s1.real*s2.real + s1.imag*s2.imag); r.imag = 2.*atan2(s1.imag, s2.real); } errno = 0; @@ -238,7 +239,7 @@ s2.real = 1.-z.imag; s2.imag = z.real; s2 = c_sqrt(s2); - r.real = asinh(s1.real*s2.imag-s2.real*s1.imag); + r.real = m_asinh(s1.real*s2.imag-s2.real*s1.imag); r.imag = atan2(z.imag, s1.real*s2.real-s1.imag*s2.imag); } errno = 0; @@ -342,7 +343,7 @@ errno = 0; } } else { - r.real = log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.; + r.real = m_log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.; r.imag = -atan2(-2.*z.imag, (1-z.real)*(1+z.real) - ay*ay)/2.; errno = 0; } @@ -552,7 +553,7 @@ if (0.71 <= h && h <= 1.73) { am = ax > ay ? ax : ay; /* max(ax, ay) */ an = ax > ay ? ay : ax; /* min(ax, ay) */ - r.real = log1p((am-1)*(am+1)+an*an)/2.; + r.real = m_log1p((am-1)*(am+1)+an*an)/2.; } else { r.real = log(h); } Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Mon Dec 21 16:27:41 2009 @@ -816,18 +816,18 @@ FUNC1(acos, acos, 0, "acos(x)\n\nReturn the arc cosine (measured in radians) of x.") -FUNC1(acosh, acosh, 0, +FUNC1(acosh, m_acosh, 0, "acosh(x)\n\nReturn the hyperbolic arc cosine (measured in radians) of x.") FUNC1(asin, asin, 0, "asin(x)\n\nReturn the arc sine (measured in radians) of x.") -FUNC1(asinh, asinh, 0, +FUNC1(asinh, m_asinh, 0, "asinh(x)\n\nReturn the hyperbolic arc sine (measured in radians) of x.") FUNC1(atan, atan, 0, "atan(x)\n\nReturn the arc tangent (measured in radians) of x.") FUNC2(atan2, m_atan2, "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n" "Unlike atan(y/x), the signs of both x and y are considered.") -FUNC1(atanh, atanh, 0, +FUNC1(atanh, m_atanh, 0, "atanh(x)\n\nReturn the hyperbolic arc tangent (measured in radians) of x.") static PyObject * math_ceil(PyObject *self, PyObject *number) { @@ -895,7 +895,7 @@ "gamma(x)\n\nGamma function at x.") FUNC1A(lgamma, m_lgamma, "lgamma(x)\n\nNatural logarithm of absolute value of Gamma function at x.") -FUNC1(log1p, log1p, 1, +FUNC1(log1p, m_log1p, 1, "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n" "The result is computed in a way which is accurate for x near zero.") FUNC1(sin, sin, 0, Modified: python/branches/py3k/Python/pymath.c ============================================================================== --- python/branches/py3k/Python/pymath.c (original) +++ python/branches/py3k/Python/pymath.c Mon Dec 21 16:27:41 2009 @@ -77,202 +77,3 @@ return copysign(y, x); } #endif /* HAVE_ROUND */ - -#ifndef HAVE_LOG1P -#include - -double -log1p(double x) -{ - /* For x small, we use the following approach. Let y be the nearest - float to 1+x, then - - 1+x = y * (1 - (y-1-x)/y) - - so log(1+x) = log(y) + log(1-(y-1-x)/y). Since (y-1-x)/y is tiny, - the second term is well approximated by (y-1-x)/y. If abs(x) >= - DBL_EPSILON/2 or the rounding-mode is some form of round-to-nearest - then y-1-x will be exactly representable, and is computed exactly - by (y-1)-x. - - If abs(x) < DBL_EPSILON/2 and the rounding mode is not known to be - round-to-nearest then this method is slightly dangerous: 1+x could - be rounded up to 1+DBL_EPSILON instead of down to 1, and in that - case y-1-x will not be exactly representable any more and the - result can be off by many ulps. But this is easily fixed: for a - floating-point number |x| < DBL_EPSILON/2., the closest - floating-point number to log(1+x) is exactly x. - */ - - double y; - if (fabs(x) < DBL_EPSILON/2.) { - return x; - } else if (-0.5 <= x && x <= 1.) { - /* WARNING: it's possible than an overeager compiler - will incorrectly optimize the following two lines - to the equivalent of "return log(1.+x)". If this - happens, then results from log1p will be inaccurate - for small x. */ - y = 1.+x; - return log(y)-((y-1.)-x)/y; - } else { - /* NaNs and infinities should end up here */ - return log(1.+x); - } -} -#endif /* HAVE_LOG1P */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -static const double ln2 = 6.93147180559945286227E-01; -static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */ -static const double two_pow_p28 = 268435456.0; /* 2**28 */ -static const double zero = 0.0; - -/* asinh(x) - * Method : - * Based on - * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] - * we have - * asinh(x) := x if 1+x*x=1, - * := sign(x)*(log(x)+ln2)) for large |x|, else - * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else - * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) - */ - -#ifndef HAVE_ASINH -double -asinh(double x) -{ - double w; - double absx = fabs(x); - - if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) { - return x+x; - } - if (absx < two_pow_m28) { /* |x| < 2**-28 */ - return x; /* return x inexact except 0 */ - } - if (absx > two_pow_p28) { /* |x| > 2**28 */ - w = log(absx)+ln2; - } - else if (absx > 2.0) { /* 2 < |x| < 2**28 */ - w = log(2.0*absx + 1.0 / (sqrt(x*x + 1.0) + absx)); - } - else { /* 2**-28 <= |x| < 2= */ - double t = x*x; - w = log1p(absx + t / (1.0 + sqrt(1.0 + t))); - } - return copysign(w, x); - -} -#endif /* HAVE_ASINH */ - -/* acosh(x) - * Method : - * Based on - * acosh(x) = log [ x + sqrt(x*x-1) ] - * we have - * acosh(x) := log(x)+ln2, if x is large; else - * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else - * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. - * - * Special cases: - * acosh(x) is NaN with signal if x<1. - * acosh(NaN) is NaN without signal. - */ - -#ifndef HAVE_ACOSH -double -acosh(double x) -{ - if (Py_IS_NAN(x)) { - return x+x; - } - if (x < 1.) { /* x < 1; return a signaling NaN */ - errno = EDOM; -#ifdef Py_NAN - return Py_NAN; -#else - return (x-x)/(x-x); -#endif - } - else if (x >= two_pow_p28) { /* x > 2**28 */ - if (Py_IS_INFINITY(x)) { - return x+x; - } else { - return log(x)+ln2; /* acosh(huge)=log(2x) */ - } - } - else if (x == 1.) { - return 0.0; /* acosh(1) = 0 */ - } - else if (x > 2.) { /* 2 < x < 2**28 */ - double t = x*x; - return log(2.0*x - 1.0 / (x + sqrt(t - 1.0))); - } - else { /* 1 < x <= 2 */ - double t = x - 1.0; - return log1p(t + sqrt(2.0*t + t*t)); - } -} -#endif /* HAVE_ACOSH */ - -/* atanh(x) - * Method : - * 1.Reduced x to positive by atanh(-x) = -atanh(x) - * 2.For x>=0.5 - * 1 2x x - * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) - * 2 1 - x 1 - x - * - * For x<0.5 - * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) - * - * Special cases: - * atanh(x) is NaN if |x| >= 1 with signal; - * atanh(NaN) is that NaN with no signal; - * - */ - -#ifndef HAVE_ATANH -double -atanh(double x) -{ - double absx; - double t; - - if (Py_IS_NAN(x)) { - return x+x; - } - absx = fabs(x); - if (absx >= 1.) { /* |x| >= 1 */ - errno = EDOM; -#ifdef Py_NAN - return Py_NAN; -#else - return x/zero; -#endif - } - if (absx < two_pow_m28) { /* |x| < 2**-28 */ - return x; - } - if (absx < 0.5) { /* |x| < 0.5 */ - t = absx+absx; - t = 0.5 * log1p(t + t*absx / (1.0 - absx)); - } - else { /* 0.5 <= |x| <= 1.0 */ - t = 0.5 * log1p((absx + absx) / (1.0 - absx)); - } - return copysign(t, x); -} -#endif /* HAVE_ATANH */ Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Mon Dec 21 16:27:41 2009 @@ -394,9 +394,9 @@ # array objects exts.append( Extension('array', ['arraymodule.c']) ) # complex math library functions - exts.append( Extension('cmath', ['cmathmodule.c'], + exts.append( Extension('cmath', ['cmathmodule.c', '_math.c'], + depends=['_math.h'], libraries=math_libs) ) - # math library functions, e.g. sin() exts.append( Extension('math', ['mathmodule.c', '_math.c'], depends=['_math.h'], From python-checkins at python.org Mon Dec 21 16:28:44 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 15:28:44 -0000 Subject: [Python-checkins] r76981 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Mon Dec 21 16:28:44 2009 New Revision: 76981 Log: Blocked revisions 76980 via svnmerge ................ r76980 | mark.dickinson | 2009-12-21 15:27:41 +0000 (Mon, 21 Dec 2009) | 10 lines Merged revisions 76978 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76978 | mark.dickinson | 2009-12-21 15:22:00 +0000 (Mon, 21 Dec 2009) | 3 lines Issue #7518: Move substitute definitions of C99 math functions from pymath.c to Modules/_math.c. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Dec 21 16:40:34 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 15:40:34 -0000 Subject: [Python-checkins] r76982 - python/trunk/Modules/_math.c Message-ID: Author: mark.dickinson Date: Mon Dec 21 16:40:33 2009 New Revision: 76982 Log: Inverse hyperbolic trigonometric functions should call m_log1p, not log1p. Modified: python/trunk/Modules/_math.c Modified: python/trunk/Modules/_math.c ============================================================================== --- python/trunk/Modules/_math.c (original) +++ python/trunk/Modules/_math.c Mon Dec 21 16:40:33 2009 @@ -3,6 +3,7 @@ #include "Python.h" #include +#include "_math.h" /* The following copyright notice applies to the original implementations of acosh, asinh and atanh. */ @@ -67,7 +68,7 @@ } else { /* 1 < x <= 2 */ double t = x - 1.0; - return log1p(t + sqrt(2.0*t + t*t)); + return m_log1p(t + sqrt(2.0*t + t*t)); } } @@ -103,7 +104,7 @@ } else { /* 2**-28 <= |x| < 2= */ double t = x*x; - w = log1p(absx + t / (1.0 + sqrt(1.0 + t))); + w = m_log1p(absx + t / (1.0 + sqrt(1.0 + t))); } return copysign(w, x); @@ -149,10 +150,10 @@ } if (absx < 0.5) { /* |x| < 0.5 */ t = absx+absx; - t = 0.5 * log1p(t + t*absx / (1.0 - absx)); + t = 0.5 * m_log1p(t + t*absx / (1.0 - absx)); } else { /* 0.5 <= |x| <= 1.0 */ - t = 0.5 * log1p((absx + absx) / (1.0 - absx)); + t = 0.5 * m_log1p((absx + absx) / (1.0 - absx)); } return copysign(t, x); } From python-checkins at python.org Mon Dec 21 16:42:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 15:42:00 -0000 Subject: [Python-checkins] r76983 - in python/branches/py3k: Modules/_math.c Message-ID: Author: mark.dickinson Date: Mon Dec 21 16:42:00 2009 New Revision: 76983 Log: Merged revisions 76982 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76982 | mark.dickinson | 2009-12-21 15:40:33 +0000 (Mon, 21 Dec 2009) | 2 lines Inverse hyperbolic trigonometric functions should call m_log1p, not log1p. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_math.c Modified: python/branches/py3k/Modules/_math.c ============================================================================== --- python/branches/py3k/Modules/_math.c (original) +++ python/branches/py3k/Modules/_math.c Mon Dec 21 16:42:00 2009 @@ -3,6 +3,7 @@ #include "Python.h" #include +#include "_math.h" /* The following copyright notice applies to the original implementations of acosh, asinh and atanh. */ @@ -67,7 +68,7 @@ } else { /* 1 < x <= 2 */ double t = x - 1.0; - return log1p(t + sqrt(2.0*t + t*t)); + return m_log1p(t + sqrt(2.0*t + t*t)); } } @@ -103,7 +104,7 @@ } else { /* 2**-28 <= |x| < 2= */ double t = x*x; - w = log1p(absx + t / (1.0 + sqrt(1.0 + t))); + w = m_log1p(absx + t / (1.0 + sqrt(1.0 + t))); } return copysign(w, x); @@ -149,10 +150,10 @@ } if (absx < 0.5) { /* |x| < 0.5 */ t = absx+absx; - t = 0.5 * log1p(t + t*absx / (1.0 - absx)); + t = 0.5 * m_log1p(t + t*absx / (1.0 - absx)); } else { /* 0.5 <= |x| <= 1.0 */ - t = 0.5 * log1p((absx + absx) / (1.0 - absx)); + t = 0.5 * m_log1p((absx + absx) / (1.0 - absx)); } return copysign(t, x); } From python-checkins at python.org Mon Dec 21 17:29:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 16:29:21 -0000 Subject: [Python-checkins] r76984 - python/trunk/Lib/test/test_long_future.py Message-ID: Author: mark.dickinson Date: Mon Dec 21 17:29:21 2009 New Revision: 76984 Log: Issue #7553: test_long_future wasn't testing properly. Thanks Florent Xicluna for bug report and patch. Modified: python/trunk/Lib/test/test_long_future.py Modified: python/trunk/Lib/test/test_long_future.py ============================================================================== --- python/trunk/Lib/test/test_long_future.py (original) +++ python/trunk/Lib/test/test_long_future.py Mon Dec 21 17:29:21 2009 @@ -30,22 +30,20 @@ for overflow in ["float(huge)", "float(mhuge)", "huge / 1", "huge / 2L", "huge / -1", "huge / -2L", "mhuge / 100", "mhuge / 100L"]: - # XXX(cwinter) this test doesn't pass when converted to - # use assertRaises. - try: + # If the "eval" does not happen in this module, + # true division is not enabled + with self.assertRaises(OverflowError): eval(overflow, namespace) - self.fail("expected OverflowError from %r" % overflow) - except OverflowError: - pass for underflow in ["1 / huge", "2L / huge", "-1 / huge", "-2L / huge", "100 / mhuge", "100L / mhuge"]: result = eval(underflow, namespace) - self.assertEqual(result, 0.0, - "expected underflow to 0 from %r" % underflow) + self.assertEqual(result, 0.0, 'expected underflow to 0 ' + 'from {!r}'.format(underflow)) for zero in ["huge / 0", "huge / 0L", "mhuge / 0", "mhuge / 0L"]: - self.assertRaises(ZeroDivisionError, eval, zero, namespace) + with self.assertRaises(ZeroDivisionError): + eval(zero, namespace) def test_main(): From python-checkins at python.org Mon Dec 21 17:30:16 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 16:30:16 -0000 Subject: [Python-checkins] r76985 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Dec 21 17:30:16 2009 New Revision: 76985 Log: Blocked revisions 76984 via svnmerge ........ r76984 | mark.dickinson | 2009-12-21 16:29:21 +0000 (Mon, 21 Dec 2009) | 3 lines Issue #7553: test_long_future wasn't testing properly. Thanks Florent Xicluna for bug report and patch. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 21 17:30:52 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 16:30:52 -0000 Subject: [Python-checkins] r76986 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Mon Dec 21 17:30:51 2009 New Revision: 76986 Log: Blocked revisions 76984 via svnmerge ........ r76984 | mark.dickinson | 2009-12-21 16:29:21 +0000 (Mon, 21 Dec 2009) | 3 lines Issue #7553: test_long_future wasn't testing properly. Thanks Florent Xicluna for bug report and patch. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Dec 21 17:42:13 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 16:42:13 -0000 Subject: [Python-checkins] r76987 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Mon Dec 21 17:42:13 2009 New Revision: 76987 Log: Blocked revisions 76983 via svnmerge ................ r76983 | mark.dickinson | 2009-12-21 15:42:00 +0000 (Mon, 21 Dec 2009) | 9 lines Merged revisions 76982 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76982 | mark.dickinson | 2009-12-21 15:40:33 +0000 (Mon, 21 Dec 2009) | 2 lines Inverse hyperbolic trigonometric functions should call m_log1p, not log1p. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Dec 21 17:42:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 21 Dec 2009 16:42:47 -0000 Subject: [Python-checkins] r76988 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Dec 21 17:42:47 2009 New Revision: 76988 Log: Blocked revisions 76982 via svnmerge ........ r76982 | mark.dickinson | 2009-12-21 15:40:33 +0000 (Mon, 21 Dec 2009) | 2 lines Inverse hyperbolic trigonometric functions should call m_log1p, not log1p. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 21 20:25:56 2009 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 21 Dec 2009 19:25:56 -0000 Subject: [Python-checkins] r76989 - python/trunk/PCbuild/build_ssl.py Message-ID: Author: martin.v.loewis Date: Mon Dec 21 20:25:56 2009 New Revision: 76989 Log: Drop 2.4 compatibility. Modified: python/trunk/PCbuild/build_ssl.py Modified: python/trunk/PCbuild/build_ssl.py ============================================================================== --- python/trunk/PCbuild/build_ssl.py (original) +++ python/trunk/PCbuild/build_ssl.py Mon Dec 21 20:25:56 2009 @@ -102,11 +102,8 @@ """ if not os.path.isfile(m32): return - # 2.4 compatibility - fin = open(m32) - if 1: # with open(m32) as fin: - fout = open(makefile, 'w') - if 1: # with open(makefile, 'w') as fout: + with open(m32) as fin: + with open(makefile, 'w') as fout: for line in fin: line = line.replace("=tmp32", "=tmp64") line = line.replace("=out32", "=out64") From python-checkins at python.org Mon Dec 21 20:27:15 2009 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 21 Dec 2009 19:27:15 -0000 Subject: [Python-checkins] r76990 - in python/trunk: PCbuild/pyproject.vsprops PCbuild/readme.txt Tools/buildbot/external-common.bat Message-ID: Author: martin.v.loewis Date: Mon Dec 21 20:27:15 2009 New Revision: 76990 Log: Switch to OpenSSL 0.9.8l. Modified: python/trunk/PCbuild/pyproject.vsprops python/trunk/PCbuild/readme.txt python/trunk/Tools/buildbot/external-common.bat Modified: python/trunk/PCbuild/pyproject.vsprops ============================================================================== --- python/trunk/PCbuild/pyproject.vsprops (original) +++ python/trunk/PCbuild/pyproject.vsprops Mon Dec 21 20:27:15 2009 @@ -82,7 +82,7 @@ /> Author: martin.v.loewis Date: Mon Dec 21 20:29:59 2009 New Revision: 76991 Log: Add NEWS for OpenSSL changes. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Dec 21 20:29:59 2009 @@ -49,6 +49,10 @@ - Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata. +Build +----- + +- Switch to OpenSSL 0.9.8l on Windows. Tests ----- From python-checkins at python.org Mon Dec 21 20:41:16 2009 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 21 Dec 2009 19:41:16 -0000 Subject: [Python-checkins] r76992 - in python/branches/release26-maint: Misc/NEWS PCbuild/pyproject.vsprops PCbuild/readme.txt Tools/buildbot/external-common.bat Message-ID: Author: martin.v.loewis Date: Mon Dec 21 20:41:15 2009 New Revision: 76992 Log: Merged revisions 76990-76991 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76990 | martin.v.loewis | 2009-12-21 20:27:15 +0100 (Mo, 21 Dez 2009) | 1 line Switch to OpenSSL 0.9.8l. ........ r76991 | martin.v.loewis | 2009-12-21 20:29:59 +0100 (Mo, 21 Dez 2009) | 1 line Add NEWS for OpenSSL changes. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/PCbuild/pyproject.vsprops python/branches/release26-maint/PCbuild/readme.txt python/branches/release26-maint/Tools/buildbot/external-common.bat Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Dec 21 20:41:15 2009 @@ -114,6 +114,8 @@ Build ----- +- Switch to OpenSSL 0.9.8l on Windows. + - Issue #6603: Change READ_TIMESTAMP macro in ceval.c so that it compiles correctly under gcc on x86-64. This fixes a reported problem with the --with-tsc build on x86-64. Modified: python/branches/release26-maint/PCbuild/pyproject.vsprops ============================================================================== --- python/branches/release26-maint/PCbuild/pyproject.vsprops (original) +++ python/branches/release26-maint/PCbuild/pyproject.vsprops Mon Dec 21 20:41:15 2009 @@ -82,7 +82,7 @@ /> Author: tarek.ziade Date: Tue Dec 22 00:12:41 2009 New Revision: 76993 Log: Fixed #7556: editing the MSVC manifest file with a regexp was throwing an error Modified: python/branches/py3k/Lib/distutils/msvc9compiler.py python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/msvc9compiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/msvc9compiler.py (original) +++ python/branches/py3k/Lib/distutils/msvc9compiler.py Tue Dec 22 00:12:41 2009 @@ -645,28 +645,8 @@ mfid = 1 else: mfid = 2 - try: - # Remove references to the Visual C runtime, so they will - # fall through to the Visual C dependency of Python.exe. - # This way, when installed for a restricted user (e.g. - # runtimes are not in WinSxS folder, but in Python's own - # folder), the runtimes do not need to be in every folder - # with .pyd's. - manifest_f = open(temp_manifest, "rb") - manifest_buf = manifest_f.read() - manifest_f.close() - pattern = re.compile( - r"""|)""", - re.DOTALL) - manifest_buf = re.sub(pattern, "", manifest_buf) - pattern = "\s*" - manifest_buf = re.sub(pattern, "", manifest_buf) - manifest_f = open(temp_manifest, "wb") - manifest_f.write(manifest_buf) - manifest_f.close() - except IOError: - pass + # Remove references to the Visual C runtime + self._remove_visual_c_ref(temp_manifest) out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', @@ -676,6 +656,33 @@ else: log.debug("skipping %s (up-to-date)", output_filename) + def _remove_visual_c_ref(self, manifest_file): + try: + # Remove references to the Visual C runtime, so they will + # fall through to the Visual C dependency of Python.exe. + # This way, when installed for a restricted user (e.g. + # runtimes are not in WinSxS folder, but in Python's own + # folder), the runtimes do not need to be in every folder + # with .pyd's. + manifest_f = open(manifest_file) + try: + manifest_buf = manifest_f.read() + finally: + manifest_f.close() + pattern = re.compile( + r"""|)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "\s*" + manifest_buf = re.sub(pattern, "", manifest_buf) + manifest_f = open(manifest_file, 'w') + try: + manifest_f.write(manifest_buf) + finally: + manifest_f.close() + except IOError: + pass # -- Miscellaneous methods ----------------------------------------- # These are all used by the 'gen_lib_options() function, in 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 Tue Dec 22 00:12:41 2009 @@ -1,18 +1,73 @@ """Tests for distutils.msvc9compiler.""" import sys import unittest +import os from distutils.errors import DistutilsPlatformError +from distutils.tests import support -class msvc9compilerTestCase(unittest.TestCase): +_MANIFEST = """\ + + + + + + + + + + + + + + + + + + + + + + +""" + +_CLEANED_MANIFEST = """\ + + + + + + + + + + + + + + + + + + +""" + + at unittest.skip("These tests are only for win32") +class msvc9compilerTestCase(support.TempdirManager, + unittest.TestCase): def test_no_compiler(self): # makes sure query_vcvarsall throws # a DistutilsPlatformError if the compiler # is not found - if sys.platform != 'win32': - # this test is only for win32 - return from distutils.msvccompiler import get_build_version if get_build_version() < 8.0: # this test is only for MSVC8.0 or above @@ -31,9 +86,6 @@ msvc9compiler.find_vcvarsall = old_find_vcvarsall def test_reg_class(self): - if sys.platform != 'win32': - # this test is only for win32 - return from distutils.msvccompiler import get_build_version if get_build_version() < 8.0: # this test is only for MSVC8.0 or above @@ -56,6 +108,27 @@ keys = Reg.read_keys(HKCU, r'Control Panel') self.assertTrue('Desktop' in keys) + def test_remove_visual_c_ref(self): + from distutils.msvc9compiler import MSVCCompiler + tempdir = self.mkdtemp() + manifest = os.path.join(tempdir, 'manifest') + f = open(manifest, 'w') + f.write(_MANIFEST) + f.close() + + compiler = MSVCCompiler() + compiler._remove_visual_c_ref(manifest) + + # see what we got + f = open(manifest) + # removing trailing spaces + content = '\n'.join([line.rstrip() for line in f.readlines()]) + f.close() + + # makes sure the manifest was properly cleaned + self.assertEquals(content, _CLEANED_MANIFEST) + + def test_suite(): return unittest.makeSuite(msvc9compilerTestCase) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Dec 22 00:12:41 2009 @@ -157,6 +157,10 @@ Library ------- +- Issue #7556: Make sure Distutils' msvc9compile reads and writes the + MSVC XML Manifest file in text mode so string patterns can be used + in regular expressions. + - Issue #7552: Removed line feed in the base64 Authorization header in the Distutils upload command to avoid an error when PyPI reads it. This occurs on long passwords. Initial patch by JP St. Pierre. From python-checkins at python.org Tue Dec 22 00:16:10 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 23:16:10 -0000 Subject: [Python-checkins] r76994 - python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py Message-ID: Author: tarek.ziade Date: Tue Dec 22 00:16:09 2009 New Revision: 76994 Log: forgot to add the win32 test in the unittest skip call Modified: python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.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 Tue Dec 22 00:16:09 2009 @@ -60,7 +60,7 @@ """ - at unittest.skip("These tests are only for win32") + at unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") class msvc9compilerTestCase(support.TempdirManager, unittest.TestCase): From python-checkins at python.org Tue Dec 22 00:18:03 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 23:18:03 -0000 Subject: [Python-checkins] r76995 - in python/branches/release31-maint: Lib/distutils/msvc9compiler.py Lib/distutils/tests/test_msvc9compiler.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Tue Dec 22 00:18:02 2009 New Revision: 76995 Log: Merged revisions 76993-76994 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76993 | tarek.ziade | 2009-12-22 00:12:41 +0100 (Tue, 22 Dec 2009) | 1 line Fixed #7556: editing the MSVC manifest file with a regexp was throwing an error ........ r76994 | tarek.ziade | 2009-12-22 00:16:09 +0100 (Tue, 22 Dec 2009) | 1 line forgot to add the win32 test in the unittest skip call ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/distutils/msvc9compiler.py python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/distutils/msvc9compiler.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/msvc9compiler.py (original) +++ python/branches/release31-maint/Lib/distutils/msvc9compiler.py Tue Dec 22 00:18:02 2009 @@ -646,28 +646,8 @@ mfid = 1 else: mfid = 2 - try: - # Remove references to the Visual C runtime, so they will - # fall through to the Visual C dependency of Python.exe. - # This way, when installed for a restricted user (e.g. - # runtimes are not in WinSxS folder, but in Python's own - # folder), the runtimes do not need to be in every folder - # with .pyd's. - manifest_f = open(temp_manifest, "rb") - manifest_buf = manifest_f.read() - manifest_f.close() - pattern = re.compile( - r"""|)""", - re.DOTALL) - manifest_buf = re.sub(pattern, "", manifest_buf) - pattern = "\s*" - manifest_buf = re.sub(pattern, "", manifest_buf) - manifest_f = open(temp_manifest, "wb") - manifest_f.write(manifest_buf) - manifest_f.close() - except IOError: - pass + # Remove references to the Visual C runtime + self._remove_visual_c_ref(temp_manifest) out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', @@ -677,6 +657,33 @@ else: log.debug("skipping %s (up-to-date)", output_filename) + def _remove_visual_c_ref(self, manifest_file): + try: + # Remove references to the Visual C runtime, so they will + # fall through to the Visual C dependency of Python.exe. + # This way, when installed for a restricted user (e.g. + # runtimes are not in WinSxS folder, but in Python's own + # folder), the runtimes do not need to be in every folder + # with .pyd's. + manifest_f = open(manifest_file) + try: + manifest_buf = manifest_f.read() + finally: + manifest_f.close() + pattern = re.compile( + r"""|)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "\s*" + manifest_buf = re.sub(pattern, "", manifest_buf) + manifest_f = open(manifest_file, 'w') + try: + manifest_f.write(manifest_buf) + finally: + manifest_f.close() + except IOError: + pass # -- Miscellaneous methods ----------------------------------------- # These are all used by the 'gen_lib_options() function, in Modified: python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py Tue Dec 22 00:18:02 2009 @@ -1,18 +1,73 @@ """Tests for distutils.msvc9compiler.""" import sys import unittest +import os from distutils.errors import DistutilsPlatformError +from distutils.tests import support -class msvc9compilerTestCase(unittest.TestCase): +_MANIFEST = """\ + + + + + + + + + + + + + + + + + + + + + + +""" + +_CLEANED_MANIFEST = """\ + + + + + + + + + + + + + + + + + + +""" + + at unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") +class msvc9compilerTestCase(support.TempdirManager, + unittest.TestCase): def test_no_compiler(self): # makes sure query_vcvarsall throws # a DistutilsPlatformError if the compiler # is not found - if sys.platform != 'win32': - # this test is only for win32 - return from distutils.msvccompiler import get_build_version if get_build_version() < 8.0: # this test is only for MSVC8.0 or above @@ -31,9 +86,6 @@ msvc9compiler.find_vcvarsall = old_find_vcvarsall def test_reg_class(self): - if sys.platform != 'win32': - # this test is only for win32 - return from distutils.msvccompiler import get_build_version if get_build_version() < 8.0: # this test is only for MSVC8.0 or above @@ -56,6 +108,27 @@ keys = Reg.read_keys(HKCU, r'Control Panel') self.assertTrue('Desktop' in keys) + def test_remove_visual_c_ref(self): + from distutils.msvc9compiler import MSVCCompiler + tempdir = self.mkdtemp() + manifest = os.path.join(tempdir, 'manifest') + f = open(manifest, 'w') + f.write(_MANIFEST) + f.close() + + compiler = MSVCCompiler() + compiler._remove_visual_c_ref(manifest) + + # see what we got + f = open(manifest) + # removing trailing spaces + content = '\n'.join([line.rstrip() for line in f.readlines()]) + f.close() + + # makes sure the manifest was properly cleaned + self.assertEquals(content, _CLEANED_MANIFEST) + + def test_suite(): return unittest.makeSuite(msvc9compilerTestCase) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Tue Dec 22 00:18:02 2009 @@ -58,6 +58,10 @@ Library ------- +- Issue #7556: Make sure Distutils' msvc9compile reads and writes the + MSVC XML Manifest file in text mode so string patterns can be used + in regular expressions. + - Issue #7552: Removed line feed in the base64 Authorization header in the Distutils upload command to avoid an error when PyPI reads it. This occurs on long passwords. Initial patch by JP St. Pierre. From python-checkins at python.org Tue Dec 22 00:31:55 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 23:31:55 -0000 Subject: [Python-checkins] r76996 - in python/trunk/Lib/distutils: msvc9compiler.py tests/test_msvc9compiler.py Message-ID: Author: tarek.ziade Date: Tue Dec 22 00:31:55 2009 New Revision: 76996 Log: backported r76993 and r76994 so the trunk behaves the same way with MSVC Manifest files editing Modified: python/trunk/Lib/distutils/msvc9compiler.py python/trunk/Lib/distutils/tests/test_msvc9compiler.py Modified: python/trunk/Lib/distutils/msvc9compiler.py ============================================================================== --- python/trunk/Lib/distutils/msvc9compiler.py (original) +++ python/trunk/Lib/distutils/msvc9compiler.py Tue Dec 22 00:31:55 2009 @@ -646,28 +646,7 @@ mfid = 1 else: mfid = 2 - try: - # Remove references to the Visual C runtime, so they will - # fall through to the Visual C dependency of Python.exe. - # This way, when installed for a restricted user (e.g. - # runtimes are not in WinSxS folder, but in Python's own - # folder), the runtimes do not need to be in every folder - # with .pyd's. - manifest_f = open(temp_manifest, "rb") - manifest_buf = manifest_f.read() - manifest_f.close() - pattern = re.compile( - r"""|)""", - re.DOTALL) - manifest_buf = re.sub(pattern, "", manifest_buf) - pattern = "\s*" - manifest_buf = re.sub(pattern, "", manifest_buf) - manifest_f = open(temp_manifest, "wb") - manifest_f.write(manifest_buf) - manifest_f.close() - except IOError: - pass + self._remove_visual_c_ref(temp_manifest) out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', @@ -677,6 +656,33 @@ else: log.debug("skipping %s (up-to-date)", output_filename) + def _remove_visual_c_ref(self, manifest_file): + try: + # Remove references to the Visual C runtime, so they will + # fall through to the Visual C dependency of Python.exe. + # This way, when installed for a restricted user (e.g. + # runtimes are not in WinSxS folder, but in Python's own + # folder), the runtimes do not need to be in every folder + # with .pyd's. + manifest_f = open(manifest_file) + try: + manifest_buf = manifest_f.read() + finally: + manifest_f.close() + pattern = re.compile( + r"""|)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "\s*" + manifest_buf = re.sub(pattern, "", manifest_buf) + manifest_f = open(manifest_file, 'w') + try: + manifest_f.write(manifest_buf) + finally: + manifest_f.close() + except IOError: + pass # -- Miscellaneous methods ----------------------------------------- # These are all used by the 'gen_lib_options() function, in Modified: python/trunk/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/trunk/Lib/distutils/tests/test_msvc9compiler.py Tue Dec 22 00:31:55 2009 @@ -1,18 +1,73 @@ """Tests for distutils.msvc9compiler.""" import sys import unittest +import os from distutils.errors import DistutilsPlatformError +from distutils.tests import support -class msvc9compilerTestCase(unittest.TestCase): +_MANIFEST = """\ + + + + + + + + + + + + + + + + + + + + + + +""" + +_CLEANED_MANIFEST = """\ + + + + + + + + + + + + + + + + + + +""" + + at unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") +class msvc9compilerTestCase(support.TempdirManager, + unittest.TestCase): def test_no_compiler(self): # makes sure query_vcvarsall throws # a DistutilsPlatformError if the compiler # is not found - if sys.platform != 'win32': - # this test is only for win32 - return from distutils.msvccompiler import get_build_version if get_build_version() < 8.0: # this test is only for MSVC8.0 or above @@ -31,9 +86,6 @@ msvc9compiler.find_vcvarsall = old_find_vcvarsall def test_reg_class(self): - if sys.platform != 'win32': - # this test is only for win32 - return from distutils.msvccompiler import get_build_version if get_build_version() < 8.0: # this test is only for MSVC8.0 or above @@ -56,6 +108,27 @@ keys = Reg.read_keys(HKCU, r'Control Panel') self.assertTrue('Desktop' in keys) + def test_remove_visual_c_ref(self): + from distutils.msvc9compiler import MSVCCompiler + tempdir = self.mkdtemp() + manifest = os.path.join(tempdir, 'manifest') + f = open(manifest, 'w') + f.write(_MANIFEST) + f.close() + + compiler = MSVCCompiler() + compiler._remove_visual_c_ref(manifest) + + # see what we got + f = open(manifest) + # removing trailing spaces + content = '\n'.join([line.rstrip() for line in f.readlines()]) + f.close() + + # makes sure the manifest was properly cleaned + self.assertEquals(content, _CLEANED_MANIFEST) + + def test_suite(): return unittest.makeSuite(msvc9compilerTestCase) From python-checkins at python.org Tue Dec 22 00:36:13 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 23:36:13 -0000 Subject: [Python-checkins] r76997 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Tue Dec 22 00:36:12 2009 New Revision: 76997 Log: Blocked revisions 76996 via svnmerge ........ r76996 | tarek.ziade | 2009-12-22 00:31:55 +0100 (Tue, 22 Dec 2009) | 1 line backported r76993 and r76994 so the trunk behaves the same way with MSVC Manifest files editing ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Dec 22 00:37:45 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 23:37:45 -0000 Subject: [Python-checkins] r76998 - python/trunk/Misc/NEWS Message-ID: Author: tarek.ziade Date: Tue Dec 22 00:37:44 2009 New Revision: 76998 Log: added a note about #7556 in Misc/NEWS Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Dec 22 00:37:44 2009 @@ -24,6 +24,9 @@ Library ------- +- Issue #7556: Distutils' msvc9compiler now opens the MSVC Manifest + file in text mode. + - Issue #7552: Removed line feed in the base64 Authorization header in the Distutils upload command to avoid an error when PyPI reads it. This occurs on long passwords. Initial patch by JP St. Pierre. From python-checkins at python.org Tue Dec 22 00:39:47 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 23:39:47 -0000 Subject: [Python-checkins] r76999 - python/branches/py3k Message-ID: Author: tarek.ziade Date: Tue Dec 22 00:39:47 2009 New Revision: 76999 Log: Blocked revisions 76998 via svnmerge ........ r76998 | tarek.ziade | 2009-12-22 00:37:44 +0100 (Tue, 22 Dec 2009) | 1 line added a note about #7556 in Misc/NEWS ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Dec 22 00:40:32 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 21 Dec 2009 23:40:32 -0000 Subject: [Python-checkins] r77000 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Tue Dec 22 00:40:32 2009 New Revision: 77000 Log: Blocked revisions 76998 via svnmerge ........ r76998 | tarek.ziade | 2009-12-22 00:37:44 +0100 (Tue, 22 Dec 2009) | 1 line added a note about #7556 in Misc/NEWS ........ Modified: python/branches/release26-maint/ (props changed) From solipsis at pitrou.net Tue Dec 22 00:47:44 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 22 Dec 2009 00:47:44 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76983): sum=18 Message-ID: <20091221234744.0D3D617759@ns6635.ovh.net> py3k results for svn r76983 (hg cset 8f2ec1f3ea00) -------------------------------------------------- test_urllib2 leaked [6, 6, 6] references, sum=18 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogxPJevW', '-x', 'test_httpservers'] From martin at v.loewis.de Tue Dec 22 00:48:38 2009 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Tue, 22 Dec 2009 00:48:38 +0100 Subject: [Python-checkins] r76996 - in python/trunk/Lib/distutils: msvc9compiler.py tests/test_msvc9compiler.py In-Reply-To: References: Message-ID: <4B300956.9070102@v.loewis.de> > backported r76993 and r76994 so the trunk behaves the same way with MSVC Manifest files editing Please don't backport from 3k to 2.7. Instead, commit to 2.7, and then forward-port using svnmerge.py. Regards, Martin From ziade.tarek at gmail.com Tue Dec 22 01:37:43 2009 From: ziade.tarek at gmail.com (=?ISO-8859-1?Q?Tarek_Ziad=E9?=) Date: Tue, 22 Dec 2009 01:37:43 +0100 Subject: [Python-checkins] r76996 - in python/trunk/Lib/distutils: msvc9compiler.py tests/test_msvc9compiler.py In-Reply-To: <4B300956.9070102@v.loewis.de> References: <4B300956.9070102@v.loewis.de> Message-ID: <94bdd2610912211637x327032f5j78fede3cd0a1a5d@mail.gmail.com> On Tue, Dec 22, 2009 at 12:48 AM, "Martin v. L?wis" wrote: >> backported r76993 and r76994 so the trunk behaves the same way with MSVC Manifest files editing > > Please don't backport from 3k to 2.7. Instead, commit to 2.7, and then > forward-port using svnmerge.py. Yes, sorry, that's what I always do. In this particular case I didn't think at first I would apply it to trunk too, since the bug only happens in py3. But I eventually realized that it was better to backport the change in trunk too. Regards, Tarek From python-checkins at python.org Tue Dec 22 03:37:37 2009 From: python-checkins at python.org (brett.cannon) Date: Tue, 22 Dec 2009 02:37:37 -0000 Subject: [Python-checkins] r77001 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: brett.cannon Date: Tue Dec 22 03:37:37 2009 New Revision: 77001 Log: Make a word plural. 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 Tue Dec 22 03:37:37 2009 @@ -855,7 +855,7 @@ 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 +to users 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`. From python-checkins at python.org Tue Dec 22 09:54:53 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 22 Dec 2009 08:54:53 -0000 Subject: [Python-checkins] r77002 - in python/branches/py3k: PCbuild/build_ssl.py Message-ID: Author: martin.v.loewis Date: Tue Dec 22 09:54:52 2009 New Revision: 77002 Log: Merged revisions 76989 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76989 | martin.v.loewis | 2009-12-21 20:25:56 +0100 (Mo, 21 Dez 2009) | 1 line Drop 2.4 compatibility. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/PCbuild/build_ssl.py Modified: python/branches/py3k/PCbuild/build_ssl.py ============================================================================== --- python/branches/py3k/PCbuild/build_ssl.py (original) +++ python/branches/py3k/PCbuild/build_ssl.py Tue Dec 22 09:54:52 2009 @@ -102,11 +102,8 @@ """ if not os.path.isfile(m32): return - # 2.4 compatibility - fin = open(m32) - if 1: # with open(m32) as fin: - fout = open(makefile, 'w') - if 1: # with open(makefile, 'w') as fout: + with open(m32) as fin: + with open(makefile, 'w') as fout: for line in fin: line = line.replace("=tmp32", "=tmp64") line = line.replace("=out32", "=out64") From python-checkins at python.org Tue Dec 22 09:57:39 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 22 Dec 2009 08:57:39 -0000 Subject: [Python-checkins] r77003 - in python/branches/py3k: Misc/NEWS PCbuild/pyproject.vsprops PCbuild/readme.txt Tools/buildbot/external-common.bat Message-ID: Author: martin.v.loewis Date: Tue Dec 22 09:57:39 2009 New Revision: 77003 Log: Merged revisions 76990-76991 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76990 | martin.v.loewis | 2009-12-21 20:27:15 +0100 (Mo, 21 Dez 2009) | 1 line Switch to OpenSSL 0.9.8l. ........ r76991 | martin.v.loewis | 2009-12-21 20:29:59 +0100 (Mo, 21 Dez 2009) | 1 line Add NEWS for OpenSSL changes. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/PCbuild/pyproject.vsprops python/branches/py3k/PCbuild/readme.txt python/branches/py3k/Tools/buildbot/external-common.bat Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Dec 22 09:57:39 2009 @@ -490,6 +490,8 @@ Build ----- +- Switch to OpenSSL 0.9.8l on Windows. + - Issue #5792: Extend the short float repr support to x86 systems using icc or suncc. Modified: python/branches/py3k/PCbuild/pyproject.vsprops ============================================================================== --- python/branches/py3k/PCbuild/pyproject.vsprops (original) +++ python/branches/py3k/PCbuild/pyproject.vsprops Tue Dec 22 09:57:39 2009 @@ -58,7 +58,7 @@ /> Author: martin.v.loewis Date: Tue Dec 22 11:48:47 2009 New Revision: 77004 Log: Merged revisions 77003 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77003 | martin.v.loewis | 2009-12-22 09:57:39 +0100 (Di, 22 Dez 2009) | 13 lines Merged revisions 76990-76991 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76990 | martin.v.loewis | 2009-12-21 20:27:15 +0100 (Mo, 21 Dez 2009) | 1 line Switch to OpenSSL 0.9.8l. ........ r76991 | martin.v.loewis | 2009-12-21 20:29:59 +0100 (Mo, 21 Dez 2009) | 1 line Add NEWS for OpenSSL changes. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/PCbuild/pyproject.vsprops python/branches/release31-maint/PCbuild/readme.txt python/branches/release31-maint/Tools/buildbot/external-common.bat Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Tue Dec 22 11:48:47 2009 @@ -267,6 +267,8 @@ Build ----- +- Switch to OpenSSL 0.9.8l on Windows. + - Issue #6603: Change READ_TIMESTAMP macro in ceval.c so that it compiles correctly under gcc on x86-64. This fixes a reported problem with the --with-tsc build on x86-64. Modified: python/branches/release31-maint/PCbuild/pyproject.vsprops ============================================================================== --- python/branches/release31-maint/PCbuild/pyproject.vsprops (original) +++ python/branches/release31-maint/PCbuild/pyproject.vsprops Tue Dec 22 11:48:47 2009 @@ -58,7 +58,7 @@ /> py3k results for svn r77003 (hg cset 0f9c9cb8c6ed) -------------------------------------------------- test_urllib2 leaked [6, 6, 6] references, sum=18 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogkCB5Tc', '-x', 'test_httpservers'] From python-checkins at python.org Wed Dec 23 01:10:25 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 23 Dec 2009 00:10:25 -0000 Subject: [Python-checkins] r77005 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Wed Dec 23 01:10:25 2009 New Revision: 77005 Log: improving the PEP readability Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Wed Dec 23 01:10:25 2009 @@ -44,387 +44,462 @@ fields must be present. Metadata-Version - Version of the file format; "1.0", "1.1" and "1.2" are the - only legal values here. +:::::::::::::::: - Example:: +Version of the file format; "1.0", "1.1" and "1.2" are the +only legal values here. + +Example:: + + Metadata-Version: 1.2 - Metadata-Version: 1.2 Name - The name of the package. +:::: + +The name of the package. - Example:: +Example:: + + Name: BeagleVote - Name: BeagleVote Version - A string containing the package's version number. This - field must be in the format specified in `PEP 386`_. +::::::: + +A string containing the package's version number. This +field must be in the format specified in `PEP 386`_. - Example:: +Example:: + + Version: 1.0a2 - Version: 1.0a2 Platform (multiple use) - A comma-separated list of platform specifications, summarizing - the operating systems supported by the package which are not - listed in the "Operating System" Trove classifiers. See - "Classifier" below. +::::::::::::::::::::::: + +A comma-separated list of platform specifications, summarizing +the operating systems supported by the package which are not +listed in the "Operating System" Trove classifiers. See +"Classifier" below. - Example:: +Example:: + + Platform: ObscureUnix, RareDOS - Platform: ObscureUnix, RareDOS Supported-Platform (multiple use) - Binary distributions containing a PKG-INFO file will use the - Supported-Platform field in their metadata to specify the OS and - CPU for which the binary package was compiled. The semantics of - the Supported-Platform field are not specified in this PEP. +::::::::::::::::::::::::::::::::: + +Binary distributions containing a PKG-INFO file will use the +Supported-Platform field in their metadata to specify the OS and +CPU for which the binary package was compiled. The semantics of +the Supported-Platform field are not specified in this PEP. - Example:: +Example:: + + Supported-Platform: RedHat 7.2 + Supported-Platform: i386-win32-2791 - Supported-Platform: RedHat 7.2 - Supported-Platform: i386-win32-2791 Summary - A one-line summary of what the package does. +::::::: + +A one-line summary of what the package does. + +Example:: - Example:: + Summary: A module for collecting votes from beagles. - Summary: A module for collecting votes from beagles. Description (optional) - A longer description of the package that can run to several - paragraphs. Software that deals with metadata should not assume - any maximum size for this field, though people shouldn't include - their instruction manual as the description. - - The contents of this field can be written using reStructuredText - markup [1]_. For programs that work with the metadata, supporting - markup is optional; programs can also display the contents of the - field as-is. This means that authors should be conservative in - the markup they use. - - Example:: - - Description: This module collects votes from beagles - in order to determine their electoral wishes. - Do *not* try to use this module with basset hounds; - it makes them grumpy. +:::::::::::::::::::::: + +A longer description of the package that can run to several +paragraphs. Software that deals with metadata should not assume +any maximum size for this field, though people shouldn't include +their instruction manual as the description. + +The contents of this field can be written using reStructuredText +markup [1]_. For programs that work with the metadata, supporting +markup is optional; programs can also display the contents of the +field as-is. This means that authors should be conservative in +the markup they use. + +Example:: + + Description: This module collects votes from beagles + in order to determine their electoral wishes. + Do *not* try to use this module with basset hounds; + it makes them grumpy. + Keywords (optional) - A list of additional keywords to be used to assist searching - for the package in a larger catalog. +::::::::::::::::::: - Example:: +A list of additional keywords to be used to assist searching +for the package in a larger catalog. + +Example:: + + Keywords: dog puppy voting election - Keywords: dog puppy voting election Home-page (optional) - A string containing the URL for the package's home page. +:::::::::::::::::::: + +A string containing the URL for the package's home page. + +Example:: - Example:: + Home-page: http://www.example.com/~cschultz/bvote/ - Home-page: http://www.example.com/~cschultz/bvote/ Download-URL - A string containing the URL from which this version of the package - can be downloaded. (This means that the URL can't be something like - ".../package-latest.tgz", but instead must be ".../package-0.45.tgz".) +:::::::::::: + +A string containing the URL from which this version of the package +can be downloaded. (This means that the URL can't be something like +".../package-latest.tgz", but instead must be ".../package-0.45.tgz".) + Author (optional) - A string containing the author's name at a minimum; additional - contact information may be provided. +::::::::::::::::: + +A string containing the author's name at a minimum; additional +contact information may be provided. - Example:: +Example:: + + Author: C. Schultz, Universal Features Syndicate, + Los Angeles, CA - Author: C. Schultz, Universal Features Syndicate, - Los Angeles, CA Author-email - A string containing the author's e-mail address. It can contain - a name and e-mail address in the legal forms for a RFC-822 - ``From:`` header. It's not optional because cataloging systems - can use the e-mail portion of this field as a unique key - representing the author. A catalog might provide authors the - ability to store their GPG key, personal home page, and other - additional metadata *about the author*, and optionally the - ability to associate several e-mail addresses with the same - person. Author-related metadata fields are not covered by this - PEP. +:::::::::::: + +A string containing the author's e-mail address. It can contain +a name and e-mail address in the legal forms for a RFC-822 +``From:`` header. It's not optional because cataloging systems +can use the e-mail portion of this field as a unique key +representing the author. A catalog might provide authors the +ability to store their GPG key, personal home page, and other +additional metadata *about the author*, and optionally the +ability to associate several e-mail addresses with the same +person. Author-related metadata fields are not covered by this +PEP. - Example:: +Example:: + + Author-email: "C. Schultz" - Author-email: "C. Schultz" Maintainer (optional) - A string containing the maintainer's name at a minimum; additional - contact information may be provided. +::::::::::::::::::::: + +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``. +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:: +Example:: + + Maintainer: C. Schultz, Universal Features Syndicate, + Los Angeles, CA - 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. +::::::::::::::::::::::::::: + +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-email``. +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``. - Example:: +Example:: + + Maintainer-email: "C. Schultz" - Maintainer-email: "C. Schultz" License (optional) - Text indicating the license covering the package where the license - is not a selection from the "License" Trove classifiers. See - "Classifier" below. This field may also be used to specify a - particular version of a licencse which is named via the ``Classifier`` - field, or to indicate a variation or exception to such a license. - - Examples:: - - License: This software may only be obtained by sending the - author a postcard, and then the user promises not - to redistribute it. +:::::::::::::::::: + +Text indicating the license covering the package where the license +is not a selection from the "License" Trove classifiers. See +"Classifier" below. This field may also be used to specify a +particular version of a licencse which is named via the ``Classifier`` +field, or to indicate a variation or exception to such a license. + +Examples:: + + License: This software may only be obtained by sending the + author a postcard, and then the user promises not + to redistribute it. + + License: GPL version 3, excluding DRM provisions - License: GPL version 3, excluding DRM provisions Classifier (multiple use) - Each entry is a string giving a single classification value - for the package. Classifiers are described in PEP 301 [2]. +::::::::::::::::::::::::: + +Each entry is a string giving a single classification value +for the package. Classifiers are described in PEP 301 [2]. + +Examples:: + + Classifier: Development Status :: 4 - Beta + Classifier: Environment :: Console (Text Based) - Examples:: - Classifier: Development Status :: 4 - Beta - Classifier: Environment :: Console (Text Based) +Requires (multiple use) (deprecated) +:::::::::::::::::::::::::::::::::::: -Requires (multiple use) - Each entry contains a string describing some other module or - package required by this package. +**This field is now deprecated in favor of "Requires-Dist"** - The format of a requirement string is identical to that of a - module or package name usable with the ``import`` statement, - optionally followed by a version declaration within parentheses. +Each entry contains a string describing some other module or +package required by this package. - 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 - distutils.version.StrictVersion class: two or three - dot-separated numeric components, with an optional "pre-release" - tag on the end consisting of the letter 'a' or 'b' followed by a - number. Example version numbers are "1.0", "2.3a2", "1.3.99", +The format of a requirement string is identical to that of a +module or package name usable with the ``import`` statement, +optionally followed by a version declaration within parentheses. - Any number of conditional operators can be specified, e.g. - the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. +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 +distutils.version.StrictVersion class: two or three +dot-separated numeric components, with an optional "pre-release" +tag on the end consisting of the letter 'a' or 'b' followed by a +number. Example version numbers are "1.0", "2.3a2", "1.3.99", - All of the following are possible requirement strings: "rfc822", - "zlib (>=1.1.4)", "zope". +Any number of conditional operators can be specified, e.g. +the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. - There's no canonical list of what strings should be used; the - Python community is left to choose its own standards. +All of the following are possible requirement strings: "rfc822", +"zlib (>=1.1.4)", "zope". - Examples:: +There's no canonical list of what strings should be used; the +Python community is left to choose its own standards. - Requires: re - Requires: sys - Requires: zlib - Requires: xml.parsers.expat (>1.0) - Requires: psycopg +Examples:: - Note: this field is now deprecated in favor of ``Requires-Dist``. + Requires: re + Requires: sys + Requires: zlib + Requires: xml.parsers.expat (>1.0) + Requires: psycopg -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 - strings should match the ones used in Requirements fields. A - version declaration may be supplied (without a comparison - operator); the package's version number will be implied if none - is specified. - Examples:: +Provides (multiple use) (deprecated) +:::::::::::::::::::::::::::::::::::: - Provides: xml - Provides: xml.utils - Provides: xml.utils.iso8601 - Provides: xml.dom - Provides: xmltools (1.3) +**This field is now deprecated in favor of "Provides-Dist"** - Note: this field is now deprecated in favor of ``Provides-Dist``. +Each entry contains a string describing a package or module that +will be provided by this package once it is installed. These +strings should match the ones used in Requirements fields. A +version declaration may be supplied (without a comparison +operator); the package's version number will be implied if none +is specified. -Obsoletes (multiple use) - Each entry contains a string describing a package or module - that this package renders obsolete, meaning that the two packages - should not be installed at the same time. Version declarations - can be supplied. +Examples:: - The most common use of this field will be in case a package name - changes, e.g. Gorgon 2.3 gets subsumed into Torqued Python 1.0. - When you install Torqued Python, the Gorgon package should be - removed. + Provides: xml + Provides: xml.utils + Provides: xml.utils.iso8601 + Provides: xml.dom + Provides: xmltools (1.3) - Example:: - Obsoletes: Gorgon +Obsoletes (multiple use) (deprecated) +::::::::::::::::::::::::::::::::::::: + +**This field is now deprecated in favor of "Obsoletes-Dist"** + +Each entry contains a string describing a package or module +that 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 package name +changes, e.g. Gorgon 2.3 gets subsumed into Torqued Python 1.0. +When you install Torqued Python, the Gorgon package should be +removed. + +Example:: + + 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. +:::::::::::::::::::::::::::: + +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. + +The distutils project names should correspond to names as found +on the `Python Package Index`_. + +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 specified in `PEP 386`_. +If no operator is provided with a version, the "==" operator +is used by default. + +Any number of conditional operators can be specified, e.g. +the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. + +Examples:: + + Requires-Dist: pkginfo + Requires-Dist: PasteDeploy + Requires-Dist: zope.interface (>3.5.0) - 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. - - The distutils project names should correspond to names as found - on the `Python Package Index`_. - - 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 specified in `PEP 386`_. - If no operator is provided with a version, the "==" operator - is used by default. - - Any number of conditional operators can be specified, e.g. - the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. - - Examples:: - - 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. For instance, source - distributions of the ``ZODB`` project have historically included - the ``transaction`` project, which is now available as a separate - distribution. Installing such a source distribution satisfies - requirements for both ``ZODB`` and ``transaction``. - - 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. E.g., multiple projects might supply - RDBMS bindings for use by a given ORM: each project might declare - that it provides ``ORM-bindings``, allowing other projects to depend - only on having at most one of them installed. - - A version declaration may be supplied (without a comparison - operator); the distribution's version number will be implied if none - is specified. Version numbers must be in the format specified in - `PEP 386`_. - - Examples:: - - Provides-Dist: OtherPackage - Provides-Dist: AnotherPackage (3.4) - Provides-Dist: virtual_package +:::::::::::::::::::::::::::: + +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. For instance, source +distributions of the ``ZODB`` project have historically included +the ``transaction`` project, which is now available as a separate +distribution. Installing such a source distribution satisfies +requirements for both ``ZODB`` and ``transaction``. + +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. E.g., multiple projects might supply +RDBMS bindings for use by a given ORM: each project might declare +that it provides ``ORM-bindings``, allowing other projects to depend +only on having at most one of them installed. + +A version declaration may be supplied (without a comparison +operator); the distribution's version number will be implied if none +is specified. Version numbers must be in the format specified in +`PEP 386`_. + +Examples:: + + Provides-Dist: OtherPackage + Provides-Dist: AnotherPackage (3.4) + 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. Version numbers must be in the - format specified in `PEP 386`_. - - 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. +::::::::::::::::::::::::::::: - Examples:: +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. Version numbers must be in the +format specified in `PEP 386`_. + +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. + +Examples:: + + Obsoletes-Dist: Gorgon + Obsoletes-Dist: OtherPackage (<3.0) - Obsoletes-Dist: Gorgon - Obsoletes-Dist: OtherPackage (<3.0) 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 - series of conditional operators and version numbers, separated - by commas. Conditional operators must be one of "<", ">", "<=", - ">=", "==", and "!=". If no operator is provided with a version, - the "==" operator is used by default. - - Version numbers must be in the format specified in `PEP 386`_. - - Any number of conditional operators can be specified, e.g. - the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. - - Examples:: - - Requires-Python: >2.1 - Requires-Python: >=2.3.4 - Requires-Python: 2.5, 2.6 +::::::::::::::: + +This field specifies the Python version(s) that the package is +guaranteed to be compatible with. The format of the field is a +series of conditional operators and version numbers, separated +by commas. Conditional operators must be one of "<", ">", "<=", +">=", "==", and "!=". If no operator is provided with a version, +the "==" operator is used by default. + +Version numbers must be in the format specified in `PEP 386`_. + +Any number of conditional operators can be specified, e.g. +the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. + +Examples:: + + Requires-Python: >2.1 + Requires-Python: >=2.3.4 + Requires-Python: 2.5, 2.6 + Requires-External (multiple use) - Each entry contains a string describing some dependency in the - system that the package is to be used. This field is intended to - serve as a hint to downstream package maintainers, and has no - semantics which are meaningful to the ``distutils`` package. - - The format of a requirement string is a name of an external - dependency, 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 "!=". If no - operator is provided with a version, the "==" operator is used by default. - - Because they refer to non-Python software releases, version numbers - for this field are **not** required to conform to the format - specified in `PEP 386`_: they should correspond to the - version scheme used by the external dependency. - - Any number of conditional operators can be specified, e.g. - the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. +:::::::::::::::::::::::::::::::: + +Each entry contains a string describing some dependency in the +system that the package is to be used. This field is intended to +serve as a hint to downstream package maintainers, and has no +semantics which are meaningful to the ``distutils`` package. + +The format of a requirement string is a name of an external +dependency, 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 "!=". If no +operator is provided with a version, the "==" operator is used by default. - Notice that there's is no particular rule on the strings to be used. +Because they refer to non-Python software releases, version numbers +for this field are **not** required to conform to the format +specified in `PEP 386`_: they should correspond to the +version scheme used by the external dependency. - Examples:: +Any number of conditional operators can be specified, e.g. +the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. - Requires-External: C - Requires-External: libpng (>=1.5) +Notice that there's is no particular rule on the strings to be used. + +Examples:: + + Requires-External: C + Requires-External: libpng (>=1.5) Copyright - Indicates the party or parties, and the year of copyright - covering the package. +::::::::: + +Indicates the party or parties, and the year of copyright +covering the package. + +Examples:: - Examples:: + Copyright: Guido van Rossum, 1991 + Copyright: Python Software Foundation, 2005 + Copyright: Public Domain - Copyright: Guido van Rossum, 1991 - Copyright: Python Software Foundation, 2005 - Copyright: Public Domain +Project-URL (multiple-use) +:::::::::::::::::::::::::: -Project-URL (multiple-use) : - A string containing a browsable URL for the project and a label for it, - separated by a comma. +A string containing a browsable URL for the project and a label for it, +separated by a comma. - Example:: +Example:: - Bug Tracker, http://bitbucket.org/tarek/distribute/issues/ + Bug Tracker, http://bitbucket.org/tarek/distribute/issues/ - The label is a free text limited to 32 signs. +The label is a free text limited to 32 signs. Version Specifiers From python-checkins at python.org Wed Dec 23 01:13:57 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 23 Dec 2009 00:13:57 -0000 Subject: [Python-checkins] r77006 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Wed Dec 23 01:13:56 2009 New Revision: 77006 Log: added Project-URL in the Abstract Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Wed Dec 23 01:13:56 2009 @@ -28,8 +28,9 @@ designed to make third-party packaging of Python Software easier. 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". This new version also adds `environment markers`. +"Metadata-Version" field, and adds new fields, "Maintainer", +"Maintainer-email" and "Project-URL". This new version also adds +`environment markers`. Fields ====== From python-checkins at python.org Wed Dec 23 10:31:12 2009 From: python-checkins at python.org (gregory.p.smith) Date: Wed, 23 Dec 2009 09:31:12 -0000 Subject: [Python-checkins] r77007 - in python/trunk: Lib/test/test_posix.py Modules/posixmodule.c Message-ID: Author: gregory.p.smith Date: Wed Dec 23 10:31:11 2009 New Revision: 77007 Log: Fix possible integer overflow in lchown and fchown functions. For issue1747858. Modified: python/trunk/Lib/test/test_posix.py python/trunk/Modules/posixmodule.c Modified: python/trunk/Lib/test/test_posix.py ============================================================================== --- python/trunk/Lib/test/test_posix.py (original) +++ python/trunk/Lib/test/test_posix.py Wed Dec 23 10:31:11 2009 @@ -207,32 +207,55 @@ if hasattr(posix, 'stat'): self.assertTrue(posix.stat(test_support.TESTFN)) - if hasattr(posix, 'chown'): - def test_chown(self): - # raise an OSError if the file does not exist - os.unlink(test_support.TESTFN) - self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1) - - # re-create the file - open(test_support.TESTFN, 'w').close() - if os.getuid() == 0: - try: - # Many linux distros have a nfsnobody user as MAX_UID-2 - # that makes a good test case for signedness issues. - # http://bugs.python.org/issue1747858 - # This part of the test only runs when run as root. - # Only scary people run their tests as root. - ent = pwd.getpwnam('nfsnobody') - posix.chown(test_support.TESTFN, ent.pw_uid, ent.pw_gid) - except KeyError: - pass - else: - # non-root cannot chown to root, raises OSError - self.assertRaises(OSError, posix.chown, - test_support.TESTFN, 0, 0) - - # test a successful chown call - posix.chown(test_support.TESTFN, os.getuid(), os.getgid()) + def _test_all_chown_common(self, chown_func, first_param): + """Common code for chown, fchown and lchown tests.""" + if os.getuid() == 0: + try: + # Many linux distros have a nfsnobody user as MAX_UID-2 + # that makes a good test case for signedness issues. + # http://bugs.python.org/issue1747858 + # This part of the test only runs when run as root. + # Only scary people run their tests as root. + ent = pwd.getpwnam('nfsnobody') + chown_func(first_param, ent.pw_uid, ent.pw_gid) + except KeyError: + pass + else: + # non-root cannot chown to root, raises OSError + self.assertRaises(OSError, chown_func, + first_param, 0, 0) + + # test a successful chown call + chown_func(first_param, os.getuid(), os.getgid()) + + @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()") + def test_chown(self): + # raise an OSError if the file does not exist + os.unlink(test_support.TESTFN) + self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1) + + # re-create the file + open(test_support.TESTFN, 'w').close() + self._test_all_chown_common(posix.chown, test_support.TESTFN) + + @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()") + def test_fchown(self): + os.unlink(test_support.TESTFN) + + # re-create the file + test_file = open(test_support.TESTFN, 'w') + try: + fd = test_file.fileno() + self._test_all_chown_common(posix.fchown, fd) + finally: + test_file.close() + + @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()") + def test_lchown(self): + os.unlink(test_support.TESTFN) + # create a symlink + os.symlink('/tmp/dummy-symlink-target', test_support.TESTFN) + self._test_all_chown_common(posix.lchown, test_support.TESTFN) def test_chdir(self): if hasattr(posix, 'chdir'): Modified: python/trunk/Modules/posixmodule.c ============================================================================== --- python/trunk/Modules/posixmodule.c (original) +++ python/trunk/Modules/posixmodule.c Wed Dec 23 10:31:11 2009 @@ -1910,9 +1910,10 @@ static PyObject * posix_fchown(PyObject *self, PyObject *args) { - int fd, uid, gid; + int fd; + long uid, gid; int res; - if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS res = fchown(fd, (uid_t) uid, (gid_t) gid); @@ -1933,9 +1934,9 @@ posix_lchown(PyObject *self, PyObject *args) { char *path = NULL; - int uid, gid; + long uid, gid; int res; - if (!PyArg_ParseTuple(args, "etii:lchown", + if (!PyArg_ParseTuple(args, "etll:lchown", Py_FileSystemDefaultEncoding, &path, &uid, &gid)) return NULL; From python-checkins at python.org Wed Dec 23 10:46:54 2009 From: python-checkins at python.org (gregory.p.smith) Date: Wed, 23 Dec 2009 09:46:54 -0000 Subject: [Python-checkins] r77008 - in python/branches/release26-maint: Lib/test/test_posix.py Misc/NEWS Modules/posixmodule.c Message-ID: Author: gregory.p.smith Date: Wed Dec 23 10:46:53 2009 New Revision: 77008 Log: Merged revisions 77007 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77007 | gregory.p.smith | 2009-12-23 01:31:11 -0800 (Wed, 23 Dec 2009) | 3 lines Fix possible integer overflow in lchown and fchown functions. For issue1747858. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_posix.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/posixmodule.c Modified: python/branches/release26-maint/Lib/test/test_posix.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_posix.py (original) +++ python/branches/release26-maint/Lib/test/test_posix.py Wed Dec 23 10:46:53 2009 @@ -143,32 +143,61 @@ if hasattr(posix, 'stat'): self.assert_(posix.stat(test_support.TESTFN)) + def _test_all_chown_common(self, chown_func, first_param): + """Common code for chown, fchown and lchown tests.""" + if os.getuid() == 0: + try: + # Many linux distros have a nfsnobody user as MAX_UID-2 + # that makes a good test case for signedness issues. + # http://bugs.python.org/issue1747858 + # This part of the test only runs when run as root. + # Only scary people run their tests as root. + ent = pwd.getpwnam('nfsnobody') + chown_func(first_param, ent.pw_uid, ent.pw_gid) + except KeyError: + pass + else: + # non-root cannot chown to root, raises OSError + self.assertRaises(OSError, chown_func, + first_param, 0, 0) + + # test a successful chown call + chown_func(first_param, os.getuid(), os.getgid()) + + def _test_chown(self): + # raise an OSError if the file does not exist + os.unlink(test_support.TESTFN) + self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1) + + # re-create the file + open(test_support.TESTFN, 'w').close() + self._test_all_chown_common(posix.chown, test_support.TESTFN) + if hasattr(posix, 'chown'): - def test_chown(self): - # raise an OSError if the file does not exist - os.unlink(test_support.TESTFN) - self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1) - - # re-create the file - open(test_support.TESTFN, 'w').close() - if os.getuid() == 0: - try: - # Many linux distros have a nfsnobody user as MAX_UID-2 - # that makes a good test case for signedness issues. - # http://bugs.python.org/issue1747858 - # This part of the test only runs when run as root. - # Only scary people run their tests as root. - ent = pwd.getpwnam('nfsnobody') - posix.chown(test_support.TESTFN, ent.pw_uid, ent.pw_gid) - except KeyError: - pass - else: - # non-root cannot chown to root, raises OSError - self.assertRaises(OSError, posix.chown, - test_support.TESTFN, 0, 0) + test_chown = _test_chown + + def _test_fchown(self): + os.unlink(test_support.TESTFN) + + # re-create the file + test_file = open(test_support.TESTFN, 'w') + try: + fd = test_file.fileno() + self._test_all_chown_common(posix.fchown, fd) + finally: + test_file.close() + + if hasattr(posix, 'fchown'): + test_fchown = _test_fchown + + def _test_lchown(self): + os.unlink(test_support.TESTFN) + # create a symlink + os.symlink('/tmp/dummy-symlink-target', test_support.TESTFN) + self._test_all_chown_common(posix.lchown, test_support.TESTFN) - # test a successful chown call - posix.chown(test_support.TESTFN, os.getuid(), os.getgid()) + if hasattr(posix, 'lchown'): + test_lchown = _test_lchown def test_chdir(self): if hasattr(posix, 'chdir'): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Dec 23 10:46:53 2009 @@ -32,6 +32,10 @@ - Issue #7084: Fix a (very unlikely) crash when printing a list from one thread, and mutating it from another one. Patch by Scott Dial. +- Issue #1747858: Fix lchown & fchown to work with large uid's and gid's on + 64-bit 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 Wed Dec 23 10:46:53 2009 @@ -1923,9 +1923,10 @@ static PyObject * posix_fchown(PyObject *self, PyObject *args) { - int fd, uid, gid; + int fd; + long uid, gid; int res; - if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS res = fchown(fd, (uid_t) uid, (gid_t) gid); @@ -1946,9 +1947,9 @@ posix_lchown(PyObject *self, PyObject *args) { char *path = NULL; - int uid, gid; + long uid, gid; int res; - if (!PyArg_ParseTuple(args, "etii:lchown", + if (!PyArg_ParseTuple(args, "etll:lchown", Py_FileSystemDefaultEncoding, &path, &uid, &gid)) return NULL; From python-checkins at python.org Wed Dec 23 11:30:45 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 23 Dec 2009 10:30:45 -0000 Subject: [Python-checkins] r77009 - python/branches/py3k/Modules/_io/_iomodule.c Message-ID: Author: georg.brandl Date: Wed Dec 23 11:30:45 2009 New Revision: 77009 Log: #7417: add signature to open() docstring. 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 Wed Dec 23 11:30:45 2009 @@ -176,6 +176,9 @@ * The main open() function */ PyDoc_STRVAR(open_doc, +"open(file, mode='r', buffering=None, encoding=None,\n" +" errors=None, newline=None, closefd=True) -> file object\n" +"\n" "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" From python-checkins at python.org Wed Dec 23 16:47:09 2009 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 23 Dec 2009 15:47:09 -0000 Subject: [Python-checkins] r77010 - tracker/instances/python-dev/schema.py Message-ID: Author: martin.v.loewis Date: Wed Dec 23 16:47:09 2009 New Revision: 77010 Log: Give Coordinator retire permission on all classes. Modified: tracker/instances/python-dev/schema.py Modified: tracker/instances/python-dev/schema.py ============================================================================== --- tracker/instances/python-dev/schema.py (original) +++ tracker/instances/python-dev/schema.py Wed Dec 23 16:47:09 2009 @@ -277,6 +277,7 @@ db.security.addPermissionToRole('Coordinator', 'View', cl) db.security.addPermissionToRole('Coordinator', 'Edit', cl) db.security.addPermissionToRole('Coordinator', 'Create', cl) + db.security.addPermissionToRole('Coordinator', 'Retire', cl) db.security.addPermissionToRole('Coordinator', 'SB: May Classify') From python-checkins at python.org Wed Dec 23 17:11:55 2009 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 23 Dec 2009 16:11:55 -0000 Subject: [Python-checkins] r77011 - tracker/instances/python-dev/schema.py Message-ID: Author: martin.v.loewis Date: Wed Dec 23 17:11:54 2009 New Revision: 77011 Log: Fix Retire permission. Modified: tracker/instances/python-dev/schema.py Modified: tracker/instances/python-dev/schema.py ============================================================================== --- tracker/instances/python-dev/schema.py (original) +++ tracker/instances/python-dev/schema.py Wed Dec 23 17:11:54 2009 @@ -277,7 +277,9 @@ db.security.addPermissionToRole('Coordinator', 'View', cl) db.security.addPermissionToRole('Coordinator', 'Edit', cl) db.security.addPermissionToRole('Coordinator', 'Create', cl) - db.security.addPermissionToRole('Coordinator', 'Retire', cl) + p = db.security.addPermission(name='Retire', klass=cl, + description='Coordinator may retire '+cl) + db.security.addPermissionToRole('Coordinator', p) db.security.addPermissionToRole('Coordinator', 'SB: May Classify') From python-checkins at python.org Wed Dec 23 21:56:09 2009 From: python-checkins at python.org (ezio.melotti) Date: Wed, 23 Dec 2009 20:56:09 -0000 Subject: [Python-checkins] r77012 - python/branches/py3k/Misc/maintainers.rst Message-ID: Author: ezio.melotti Date: Wed Dec 23 21:56:09 2009 New Revision: 77012 Log: Rephrased the introduction, added missing commas and my name for Unicode Modified: python/branches/py3k/Misc/maintainers.rst Modified: python/branches/py3k/Misc/maintainers.rst ============================================================================== --- python/branches/py3k/Misc/maintainers.rst (original) +++ python/branches/py3k/Misc/maintainers.rst Wed Dec 23 21:56:09 2009 @@ -1,21 +1,19 @@ Maintainers Index ================= -This document cross references Python Modules (first table) and platforms -(second table) with the Tracker user names of people who are experts -and/or resources for that module or platform. This list is intended -to be used by issue submitters, issue triage people, and other issue -participants to find people to add to the nosy list or to contact -directly by email for help and decisions on feature requests and bug -fixes. People on this list may be asked to render final judgement on a -feature or bug. If no active maintainer is listed for a given module, -then questionable changes should go to python-dev, while any other issues -can and should be decided by any committer. - -The last part of this document is a third table, listing broader topic -areas in which various people have expertise. These people can also -be contacted for help, opinions, and decisions when issues involve -their areas. +This document has tables that list Python Modules, Tools, Platforms and +Interest Areas and names for each item that indicate a maintainer or an +expert in the field. This list is intended to be used by issue submitters, +issue triage people, and other issue participants to find people to add to +the nosy list or to contact directly by email for help and decisions on +feature requests and bug fixes. People on this list may be asked to render +final judgement on a feature or bug. If no active maintainer is listed for +a given module, then questionable changes should go to python-dev, while +any other issues can and should be decided by any committer. + +The Platform and Interest Area tables list broader fields in which various +people have expertise. These people can also be contacted for help, +opinions, and decisions when issues involve their areas. If a listed maintainer does not respond to requests for comment for an extended period (three weeks or more), they should be marked as inactive @@ -99,7 +97,7 @@ fnmatch formatter fpectl -fractions mark.dickinson rhettinger +fractions mark.dickinson, rhettinger ftplib functools gc pitrou @@ -132,7 +130,7 @@ mailbox andrew.kuchling mailcap marshal -math mark.dickinson rhettinger +math mark.dickinson, rhettinger mimetypes mmap modulefinder theller, jvr @@ -289,7 +287,7 @@ testing michael.foord, pitrou threads tracker -unicode lemburg +unicode lemburg, ezio.melotti version control windows ================== =========== From solipsis at pitrou.net Thu Dec 24 00:47:17 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 24 Dec 2009 00:47:17 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r77012): sum=18 Message-ID: <20091223234717.8E1DA17759@ns6635.ovh.net> py3k results for svn r77012 (hg cset 1c7491ae5b22) -------------------------------------------------- test_urllib2 leaked [6, 6, 6] references, sum=18 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogwOEQeb', '-x', 'test_httpservers'] From python-checkins at python.org Thu Dec 24 01:51:34 2009 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 24 Dec 2009 00:51:34 -0000 Subject: [Python-checkins] r77013 - python/branches/release26-maint/Lib/httplib.py Message-ID: Author: senthil.kumaran Date: Thu Dec 24 01:51:34 2009 New Revision: 77013 Log: Issue: 7291. 2.6 backport missed the headers argument. Fixed it. Modified: python/branches/release26-maint/Lib/httplib.py Modified: python/branches/release26-maint/Lib/httplib.py ============================================================================== --- python/branches/release26-maint/Lib/httplib.py (original) +++ python/branches/release26-maint/Lib/httplib.py Thu Dec 24 01:51:34 2009 @@ -658,7 +658,7 @@ if strict is not None: self.strict = strict - def _set_tunnel(self, host, port=None): + def _set_tunnel(self, host, port=None, headers=None): """ Sets up the host and the port for the HTTP CONNECT Tunnelling. The headers argument should be a mapping of extra HTTP headers From python-checkins at python.org Thu Dec 24 02:09:53 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 24 Dec 2009 01:09:53 -0000 Subject: [Python-checkins] r77014 - python/trunk/Lib/test/test_urllib2.py Message-ID: Author: benjamin.peterson Date: Thu Dec 24 02:09:53 2009 New Revision: 77014 Log: fix alleged refleak Modified: python/trunk/Lib/test/test_urllib2.py Modified: python/trunk/Lib/test/test_urllib2.py ============================================================================== --- python/trunk/Lib/test/test_urllib2.py (original) +++ python/trunk/Lib/test/test_urllib2.py Thu Dec 24 02:09:53 2009 @@ -292,10 +292,11 @@ self._tunnel_headers = headers else: self._tunnel_headers.clear() - def request(self, method, url, body=None, headers={}): + def request(self, method, url, body=None, headers=None): self.method = method self.selector = url - self.req_headers += headers.items() + if headers is not None: + self.req_headers += headers.items() self.req_headers.sort() if body: self.data = body @@ -415,7 +416,11 @@ class MockHTTPSHandler(urllib2.AbstractHTTPHandler): # Useful for testing the Proxy-Authorization request by verifying the # properties of httpcon - httpconn = MockHTTPClass() + + def __init__(self): + urllib2.AbstractHTTPHandler.__init__(self) + self.httpconn = MockHTTPClass() + def https_open(self, req): return self.do_open(self.httpconn, req) From python-checkins at python.org Thu Dec 24 02:13:50 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 24 Dec 2009 01:13:50 -0000 Subject: [Python-checkins] r77015 - in python/branches/release26-maint: Lib/test/test_urllib2.py Message-ID: Author: benjamin.peterson Date: Thu Dec 24 02:13:50 2009 New Revision: 77015 Log: Merged revisions 77014 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77014 | benjamin.peterson | 2009-12-23 19:09:53 -0600 (Wed, 23 Dec 2009) | 1 line fix alleged refleak ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_urllib2.py Modified: python/branches/release26-maint/Lib/test/test_urllib2.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_urllib2.py (original) +++ python/branches/release26-maint/Lib/test/test_urllib2.py Thu Dec 24 02:13:50 2009 @@ -292,10 +292,11 @@ self._tunnel_headers = headers else: self._tunnel_headers.clear() - def request(self, method, url, body=None, headers={}): + def request(self, method, url, body=None, headers=None): self.method = method self.selector = url - self.req_headers += headers.items() + if headers is not None: + self.req_headers += headers.items() self.req_headers.sort() if body: self.data = body @@ -415,7 +416,11 @@ class MockHTTPSHandler(urllib2.AbstractHTTPHandler): # Useful for testing the Proxy-Authorization request by verifying the # properties of httpcon - httpconn = MockHTTPClass() + + def __init__(self): + urllib2.AbstractHTTPHandler.__init__(self) + self.httpconn = MockHTTPClass() + def https_open(self, req): return self.do_open(self.httpconn, req) From python-checkins at python.org Thu Dec 24 02:14:05 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 24 Dec 2009 01:14:05 -0000 Subject: [Python-checkins] r77016 - in python/branches/py3k: Lib/test/test_urllib2.py Message-ID: Author: benjamin.peterson Date: Thu Dec 24 02:14:05 2009 New Revision: 77016 Log: Merged revisions 77014 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77014 | benjamin.peterson | 2009-12-23 19:09:53 -0600 (Wed, 23 Dec 2009) | 1 line fix alleged refleak ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_urllib2.py Modified: python/branches/py3k/Lib/test/test_urllib2.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllib2.py (original) +++ python/branches/py3k/Lib/test/test_urllib2.py Thu Dec 24 02:14:05 2009 @@ -301,10 +301,11 @@ else: self._tunnel_headers.clear() - def request(self, method, url, body=None, headers={}): + def request(self, method, url, body=None, headers=None): self.method = method self.selector = url - self.req_headers += headers.items() + if headers is not None: + self.req_headers += headers.items() self.req_headers.sort() if body: self.data = body @@ -424,7 +425,11 @@ class MockHTTPSHandler(urllib.request.AbstractHTTPHandler): # Useful for testing the Proxy-Authorization request by verifying the # properties of httpcon - httpconn = MockHTTPClass() + + def __init__(self): + urllib.request.AbstractHTTPHandler.__init__(self) + self.httpconn = MockHTTPClass() + def https_open(self, req): return self.do_open(self.httpconn, req) From python-checkins at python.org Thu Dec 24 02:18:13 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 24 Dec 2009 01:18:13 -0000 Subject: [Python-checkins] r77017 - in python/branches/release31-maint: Lib/test/test_urllib2.py Message-ID: Author: benjamin.peterson Date: Thu Dec 24 02:18:13 2009 New Revision: 77017 Log: Merged revisions 77016 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77016 | benjamin.peterson | 2009-12-23 19:14:05 -0600 (Wed, 23 Dec 2009) | 9 lines Merged revisions 77014 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77014 | benjamin.peterson | 2009-12-23 19:09:53 -0600 (Wed, 23 Dec 2009) | 1 line fix alleged refleak ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_urllib2.py Modified: python/branches/release31-maint/Lib/test/test_urllib2.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_urllib2.py (original) +++ python/branches/release31-maint/Lib/test/test_urllib2.py Thu Dec 24 02:18:13 2009 @@ -301,10 +301,11 @@ else: self._tunnel_headers.clear() - def request(self, method, url, body=None, headers={}): + def request(self, method, url, body=None, headers=None): self.method = method self.selector = url - self.req_headers += headers.items() + if headers is not None: + self.req_headers += headers.items() self.req_headers.sort() if body: self.data = body @@ -424,7 +425,11 @@ class MockHTTPSHandler(urllib.request.AbstractHTTPHandler): # Useful for testing the Proxy-Authorization request by verifying the # properties of httpcon - httpconn = MockHTTPClass() + + def __init__(self): + urllib.request.AbstractHTTPHandler.__init__(self) + self.httpconn = MockHTTPClass() + def https_open(self, req): return self.do_open(self.httpconn, req) From python-checkins at python.org Thu Dec 24 03:18:18 2009 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 24 Dec 2009 02:18:18 -0000 Subject: [Python-checkins] r77018 - python/trunk/Doc/library/urllib2.rst Message-ID: Author: senthil.kumaran Date: Thu Dec 24 03:18:14 2009 New Revision: 77018 Log: Fix for Issue7570: Error in urllib2 example. Modified: python/trunk/Doc/library/urllib2.rst Modified: python/trunk/Doc/library/urllib2.rst ============================================================================== --- python/trunk/Doc/library/urllib2.rst (original) +++ python/trunk/Doc/library/urllib2.rst Thu Dec 24 03:18:14 2009 @@ -945,10 +945,10 @@ :class:`ProxyBasicAuthHandler`. :: proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'}) - proxy_auth_handler = urllib2.HTTPBasicAuthHandler() + proxy_auth_handler = urllib2.ProxyBasicAuthHandler() proxy_auth_handler.add_password('realm', 'host', 'username', 'password') - opener = build_opener(proxy_handler, proxy_auth_handler) + opener = urllib2.build_opener(proxy_handler, proxy_auth_handler) # This time, rather than install the OpenerDirector, we use it directly: opener.open('http://www.example.com/login.html') From python-checkins at python.org Thu Dec 24 03:21:03 2009 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 24 Dec 2009 02:21:03 -0000 Subject: [Python-checkins] r77019 - in python/branches/release26-maint: Doc/library/urllib2.rst Message-ID: Author: senthil.kumaran Date: Thu Dec 24 03:21:03 2009 New Revision: 77019 Log: Merged revisions 77018 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77018 | senthil.kumaran | 2009-12-24 07:48:14 +0530 (Thu, 24 Dec 2009) | 3 lines Fix for Issue7570: Error in urllib2 example. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/urllib2.rst Modified: python/branches/release26-maint/Doc/library/urllib2.rst ============================================================================== --- python/branches/release26-maint/Doc/library/urllib2.rst (original) +++ python/branches/release26-maint/Doc/library/urllib2.rst Thu Dec 24 03:21:03 2009 @@ -945,10 +945,10 @@ :class:`ProxyBasicAuthHandler`. :: proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'}) - proxy_auth_handler = urllib2.HTTPBasicAuthHandler() + proxy_auth_handler = urllib2.ProxyBasicAuthHandler() proxy_auth_handler.add_password('realm', 'host', 'username', 'password') - opener = build_opener(proxy_handler, proxy_auth_handler) + opener = urllib2.build_opener(proxy_handler, proxy_auth_handler) # This time, rather than install the OpenerDirector, we use it directly: opener.open('http://www.example.com/login.html') From python-checkins at python.org Thu Dec 24 03:24:37 2009 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 24 Dec 2009 02:24:37 -0000 Subject: [Python-checkins] r77020 - in python/branches/py3k: Doc/library/urllib.request.rst Message-ID: Author: senthil.kumaran Date: Thu Dec 24 03:24:37 2009 New Revision: 77020 Log: Merged revisions 77018 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77018 | senthil.kumaran | 2009-12-24 07:48:14 +0530 (Thu, 24 Dec 2009) | 3 lines Fix for Issue7570: Error in urllib2 example. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/urllib.request.rst 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 Thu Dec 24 03:24:37 2009 @@ -1116,10 +1116,10 @@ :class:`ProxyBasicAuthHandler`. :: proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'}) - proxy_auth_handler = urllib.request.HTTPBasicAuthHandler() + proxy_auth_handler = urllib.request.ProxyBasicAuthHandler() proxy_auth_handler.add_password('realm', 'host', 'username', 'password') - opener = build_opener(proxy_handler, proxy_auth_handler) + opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler) # This time, rather than install the OpenerDirector, we use it directly: opener.open('http://www.example.com/login.html') From python-checkins at python.org Thu Dec 24 03:27:00 2009 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 24 Dec 2009 02:27:00 -0000 Subject: [Python-checkins] r77021 - in python/branches/release31-maint: Doc/library/urllib.request.rst Message-ID: Author: senthil.kumaran Date: Thu Dec 24 03:27:00 2009 New Revision: 77021 Log: Merged revisions 77020 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77020 | senthil.kumaran | 2009-12-24 07:54:37 +0530 (Thu, 24 Dec 2009) | 9 lines Merged revisions 77018 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77018 | senthil.kumaran | 2009-12-24 07:48:14 +0530 (Thu, 24 Dec 2009) | 3 lines Fix for Issue7570: Error in urllib2 example. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/urllib.request.rst Modified: python/branches/release31-maint/Doc/library/urllib.request.rst ============================================================================== --- python/branches/release31-maint/Doc/library/urllib.request.rst (original) +++ python/branches/release31-maint/Doc/library/urllib.request.rst Thu Dec 24 03:27:00 2009 @@ -1116,10 +1116,10 @@ :class:`ProxyBasicAuthHandler`. :: proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'}) - proxy_auth_handler = urllib.request.HTTPBasicAuthHandler() + proxy_auth_handler = urllib.request.ProxyBasicAuthHandler() proxy_auth_handler.add_password('realm', 'host', 'username', 'password') - opener = build_opener(proxy_handler, proxy_auth_handler) + opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler) # This time, rather than install the OpenerDirector, we use it directly: opener.open('http://www.example.com/login.html') From python-checkins at python.org Thu Dec 24 03:54:53 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 24 Dec 2009 02:54:53 -0000 Subject: [Python-checkins] r77022 - python/trunk/Doc/library/webbrowser.rst Message-ID: Author: ezio.melotti Date: Thu Dec 24 03:54:53 2009 New Revision: 77022 Log: Added markup and default arg, fixed example 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 Thu Dec 24 03:54:53 2009 @@ -18,10 +18,10 @@ the user exits the browser. If the environment variable :envvar:`BROWSER` exists, it is interpreted to -override the platform default list of browsers, as a os.pathsep-separated list -of browsers to try in order. When the value of a list part contains the string -``%s``, then it is interpreted as a literal browser command line to be used -with the argument URL substituted for ``%s``; if the part does not contain +override the platform default list of browsers, as a :data:`os.pathsep`-separated +list of browsers to try in order. When the value of a list part contains the +string ``%s``, then it is interpreted as a literal browser command line to be +used with the argument URL substituted for ``%s``; if the part does not contain ``%s``, it is simply interpreted as the name of the browser to launch. [1]_ For non-Unix platforms, or when a remote browser is available on Unix, the @@ -162,10 +162,10 @@ Here are some simple examples:: - url = 'http://www.python.org' + url = 'http://www.python.org/' # Open URL in a new tab, if a browser window is already open. - webbrowser.open_new_tab(url + '/doc') + webbrowser.open_new_tab(url + 'doc/') # Open URL in new window, raising the window if possible. webbrowser.open_new(url) @@ -180,7 +180,7 @@ module-level convenience functions: -.. method:: controller.open(url[, new[, autoraise=True]]) +.. method:: controller.open(url[, new=0[, autoraise=True]]) Display *url* using the browser handled by this controller. If *new* is 1, a new browser window is opened if possible. If *new* is 2, a new browser page ("tab") From python-checkins at python.org Thu Dec 24 04:06:05 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 24 Dec 2009 03:06:05 -0000 Subject: [Python-checkins] r77023 - in python/branches/release26-maint: Doc/library/webbrowser.rst Message-ID: Author: ezio.melotti Date: Thu Dec 24 04:06:04 2009 New Revision: 77023 Log: Merged revisions 77022 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77022 | ezio.melotti | 2009-12-24 04:54:53 +0200 (Thu, 24 Dec 2009) | 1 line Added markup and default arg, fixed example ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/webbrowser.rst 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 Thu Dec 24 04:06:04 2009 @@ -18,10 +18,10 @@ the user exits the browser. If the environment variable :envvar:`BROWSER` exists, it is interpreted to -override the platform default list of browsers, as a os.pathsep-separated list -of browsers to try in order. When the value of a list part contains the string -``%s``, then it is interpreted as a literal browser command line to be used -with the argument URL substituted for ``%s``; if the part does not contain +override the platform default list of browsers, as a :data:`os.pathsep`-separated +list of browsers to try in order. When the value of a list part contains the +string ``%s``, then it is interpreted as a literal browser command line to be +used with the argument URL substituted for ``%s``; if the part does not contain ``%s``, it is simply interpreted as the name of the browser to launch. [1]_ For non-Unix platforms, or when a remote browser is available on Unix, the @@ -162,10 +162,10 @@ Here are some simple examples:: - url = 'http://www.python.org' + url = 'http://www.python.org/' # Open URL in a new tab, if a browser window is already open. - webbrowser.open_new_tab(url + '/doc') + webbrowser.open_new_tab(url + 'doc/') # Open URL in new window, raising the window if possible. webbrowser.open_new(url) @@ -180,7 +180,7 @@ module-level convenience functions: -.. method:: controller.open(url[, new[, autoraise=True]]) +.. method:: controller.open(url[, new=0[, autoraise=True]]) Display *url* using the browser handled by this controller. If *new* is 1, a new browser window is opened if possible. If *new* is 2, a new browser page ("tab") From python-checkins at python.org Thu Dec 24 04:23:23 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 24 Dec 2009 03:23:23 -0000 Subject: [Python-checkins] r77024 - in python/branches/py3k: Doc/library/webbrowser.rst Message-ID: Author: ezio.melotti Date: Thu Dec 24 04:23:23 2009 New Revision: 77024 Log: Merged revisions 77022 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77022 | ezio.melotti | 2009-12-24 04:54:53 +0200 (Thu, 24 Dec 2009) | 1 line Added markup and default arg, fixed example ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/webbrowser.rst Modified: python/branches/py3k/Doc/library/webbrowser.rst ============================================================================== --- python/branches/py3k/Doc/library/webbrowser.rst (original) +++ python/branches/py3k/Doc/library/webbrowser.rst Thu Dec 24 04:23:23 2009 @@ -17,10 +17,10 @@ the user exits the browser. If the environment variable :envvar:`BROWSER` exists, it is interpreted to -override the platform default list of browsers, as a os.pathsep-separated list -of browsers to try in order. When the value of a list part contains the string -``%s``, then it is interpreted as a literal browser command line to be used -with the argument URL substituted for ``%s``; if the part does not contain +override the platform default list of browsers, as a :data:`os.pathsep`-separated +list of browsers to try in order. When the value of a list part contains the +string ``%s``, then it is interpreted as a literal browser command line to be +used with the argument URL substituted for ``%s``; if the part does not contain ``%s``, it is simply interpreted as the name of the browser to launch. [1]_ For non-Unix platforms, or when a remote browser is available on Unix, the @@ -156,10 +156,10 @@ Here are some simple examples:: - url = 'http://www.python.org' + url = 'http://www.python.org/' # Open URL in a new tab, if a browser window is already open. - webbrowser.open_new_tab(url + '/doc') + webbrowser.open_new_tab(url + 'doc/') # Open URL in new window, raising the window if possible. webbrowser.open_new(url) From python-checkins at python.org Thu Dec 24 04:26:13 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 24 Dec 2009 03:26:13 -0000 Subject: [Python-checkins] r77025 - in python/branches/release31-maint: Doc/library/webbrowser.rst Message-ID: Author: ezio.melotti Date: Thu Dec 24 04:26:13 2009 New Revision: 77025 Log: Merged revisions 77024 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77024 | ezio.melotti | 2009-12-24 05:23:23 +0200 (Thu, 24 Dec 2009) | 9 lines Merged revisions 77022 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77022 | ezio.melotti | 2009-12-24 04:54:53 +0200 (Thu, 24 Dec 2009) | 1 line Added markup and default arg, fixed example ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/webbrowser.rst Modified: python/branches/release31-maint/Doc/library/webbrowser.rst ============================================================================== --- python/branches/release31-maint/Doc/library/webbrowser.rst (original) +++ python/branches/release31-maint/Doc/library/webbrowser.rst Thu Dec 24 04:26:13 2009 @@ -17,10 +17,10 @@ the user exits the browser. If the environment variable :envvar:`BROWSER` exists, it is interpreted to -override the platform default list of browsers, as a os.pathsep-separated list -of browsers to try in order. When the value of a list part contains the string -``%s``, then it is interpreted as a literal browser command line to be used -with the argument URL substituted for ``%s``; if the part does not contain +override the platform default list of browsers, as a :data:`os.pathsep`-separated +list of browsers to try in order. When the value of a list part contains the +string ``%s``, then it is interpreted as a literal browser command line to be +used with the argument URL substituted for ``%s``; if the part does not contain ``%s``, it is simply interpreted as the name of the browser to launch. [1]_ For non-Unix platforms, or when a remote browser is available on Unix, the @@ -156,10 +156,10 @@ Here are some simple examples:: - url = 'http://www.python.org' + url = 'http://www.python.org/' # Open URL in a new tab, if a browser window is already open. - webbrowser.open_new_tab(url + '/doc') + webbrowser.open_new_tab(url + 'doc/') # Open URL in new window, raising the window if possible. webbrowser.open_new(url) From python-checkins at python.org Thu Dec 24 14:06:39 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 13:06:39 -0000 Subject: [Python-checkins] r77026 - python/trunk/Lib/distutils/util.py Message-ID: Author: ronald.oussoren Date: Thu Dec 24 14:06:39 2009 New Revision: 77026 Log: On OSX the output of "uname -m" always reflects the 32-bit architecture for the machine ("i386" or "ppc"), even if the executable is 64-bit. This patchs ensures that the distutils platform architecture represents the architecture for the executable when running a 64-bit only executable on OSX. Modified: python/trunk/Lib/distutils/util.py Modified: python/trunk/Lib/distutils/util.py ============================================================================== --- python/trunk/Lib/distutils/util.py (original) +++ python/trunk/Lib/distutils/util.py Thu Dec 24 14:06:39 2009 @@ -165,11 +165,21 @@ raise ValueError( "Don't know machine value for archs=%r"%(archs,)) + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxint >= 2**32: + machine = 'x86_64' elif machine in ('PowerPC', 'Power_Macintosh'): # Pick a sane name for the PPC architecture. machine = 'ppc' + # See 'i386' case + if sys.maxint >= 2**32: + machine = 'ppc64' + return "%s-%s-%s" % (osname, release, machine) From python-checkins at python.org Thu Dec 24 14:07:53 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 13:07:53 -0000 Subject: [Python-checkins] r77027 - in python/branches/release26-maint: Lib/distutils/util.py Message-ID: Author: ronald.oussoren Date: Thu Dec 24 14:07:53 2009 New Revision: 77027 Log: Merged revisions 77026 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77026 | ronald.oussoren | 2009-12-24 14:06:39 +0100 (Thu, 24 Dec 2009) | 8 lines On OSX the output of "uname -m" always reflects the 32-bit architecture for the machine ("i386" or "ppc"), even if the executable is 64-bit. This patchs ensures that the distutils platform architecture represents the architecture for the executable when running a 64-bit only executable on OSX. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/util.py Modified: python/branches/release26-maint/Lib/distutils/util.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/util.py (original) +++ python/branches/release26-maint/Lib/distutils/util.py Thu Dec 24 14:07:53 2009 @@ -162,11 +162,21 @@ raise ValueError( "Don't know machine value for archs=%r"%(archs,)) + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxint >= 2**32: + machine = 'x86_64' elif machine in ('PowerPC', 'Power_Macintosh'): # Pick a sane name for the PPC architecture. machine = 'ppc' + # See 'i386' case + if sys.maxint >= 2**32: + machine = 'ppc64' + return "%s-%s-%s" % (osname, release, machine) # get_platform () From python-checkins at python.org Thu Dec 24 14:14:22 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 13:14:22 -0000 Subject: [Python-checkins] r77028 - in python/branches/py3k: Lib/distutils/util.py Message-ID: Author: ronald.oussoren Date: Thu Dec 24 14:14:21 2009 New Revision: 77028 Log: Merged revisions 77026 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77026 | ronald.oussoren | 2009-12-24 14:06:39 +0100 (Thu, 24 Dec 2009) | 8 lines On OSX the output of "uname -m" always reflects the 32-bit architecture for the machine ("i386" or "ppc"), even if the executable is 64-bit. This patchs ensures that the distutils platform architecture represents the architecture for the executable when running a 64-bit only executable on OSX. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/util.py Modified: python/branches/py3k/Lib/distutils/util.py ============================================================================== --- python/branches/py3k/Lib/distutils/util.py (original) +++ python/branches/py3k/Lib/distutils/util.py Thu Dec 24 14:14:21 2009 @@ -165,11 +165,21 @@ raise ValueError( "Don't know machine value for archs=%r"%(archs,)) + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxsize >= 2**32: + machine = 'x86_64' elif machine in ('PowerPC', 'Power_Macintosh'): # Pick a sane name for the PPC architecture. machine = 'ppc' + # See 'i386' case + if sys.maxsize >= 2**32: + machine = 'ppc64' + return "%s-%s-%s" % (osname, release, machine) From ziade.tarek at gmail.com Thu Dec 24 14:14:48 2009 From: ziade.tarek at gmail.com (=?ISO-8859-1?Q?Tarek_Ziad=E9?=) Date: Thu, 24 Dec 2009 14:14:48 +0100 Subject: [Python-checkins] r77026 - python/trunk/Lib/distutils/util.py In-Reply-To: <4b336762.1567f10a.35fb.27eeSMTPIN_ADDED@mx.google.com> References: <4b336762.1567f10a.35fb.27eeSMTPIN_ADDED@mx.google.com> Message-ID: <94bdd2610912240514w6659aff2u47d87065015ef00b@mail.gmail.com> Can you add a test for this change in test_util if possible? I am trying to keep the test coverage high for all new changes. Thanks ! On Thu, Dec 24, 2009 at 2:06 PM, ronald.oussoren wrote: > Author: ronald.oussoren > Date: Thu Dec 24 14:06:39 2009 > New Revision: 77026 > > Log: > On OSX the output of "uname -m" always reflects the 32-bit architecture > for the machine ("i386" or "ppc"), even if the executable is > 64-bit. > > This patchs ensures that the distutils platform architecture > represents the architecture for the executable when running a > 64-bit only executable on OSX. > > > Modified: > ? python/trunk/Lib/distutils/util.py > > Modified: python/trunk/Lib/distutils/util.py > ============================================================================== > --- python/trunk/Lib/distutils/util.py ?(original) > +++ python/trunk/Lib/distutils/util.py ?Thu Dec 24 14:06:39 2009 > @@ -165,11 +165,21 @@ > ? ? ? ? ? ? ? ? ? ? raise ValueError( > ? ? ? ? ? ? ? ? ? ? ? ?"Don't know machine value for archs=%r"%(archs,)) > > + ? ? ? ? ? ?elif machine == 'i386': > + ? ? ? ? ? ? ? ?# On OSX the machine type returned by uname is always the > + ? ? ? ? ? ? ? ?# 32-bit variant, even if the executable architecture is > + ? ? ? ? ? ? ? ?# the 64-bit variant > + ? ? ? ? ? ? ? ?if sys.maxint >= 2**32: > + ? ? ? ? ? ? ? ? ? ?machine = 'x86_64' > > ? ? ? ? ? ? elif machine in ('PowerPC', 'Power_Macintosh'): > ? ? ? ? ? ? ? ? # Pick a sane name for the PPC architecture. > ? ? ? ? ? ? ? ? machine = 'ppc' > > + ? ? ? ? ? ? ? ?# See 'i386' case > + ? ? ? ? ? ? ? ?if sys.maxint >= 2**32: > + ? ? ? ? ? ? ? ? ? ?machine = 'ppc64' > + > ? ? return "%s-%s-%s" % (osname, release, machine) > > > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > -- Tarek Ziad? | http://ziade.org From python-checkins at python.org Thu Dec 24 14:16:53 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 13:16:53 -0000 Subject: [Python-checkins] r77029 - in python/branches/release31-maint: Lib/distutils/util.py Message-ID: Author: ronald.oussoren Date: Thu Dec 24 14:16:53 2009 New Revision: 77029 Log: Merged revisions 77028 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77028 | ronald.oussoren | 2009-12-24 14:14:21 +0100 (Thu, 24 Dec 2009) | 15 lines Merged revisions 77026 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77026 | ronald.oussoren | 2009-12-24 14:06:39 +0100 (Thu, 24 Dec 2009) | 8 lines On OSX the output of "uname -m" always reflects the 32-bit architecture for the machine ("i386" or "ppc"), even if the executable is 64-bit. This patchs ensures that the distutils platform architecture represents the architecture for the executable when running a 64-bit only executable on OSX. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/distutils/util.py Modified: python/branches/release31-maint/Lib/distutils/util.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/util.py (original) +++ python/branches/release31-maint/Lib/distutils/util.py Thu Dec 24 14:16:53 2009 @@ -162,11 +162,21 @@ raise ValueError( "Don't know machine value for archs=%r"%(archs,)) + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxsize >= 2**32: + machine = 'x86_64' elif machine in ('PowerPC', 'Power_Macintosh'): # Pick a sane name for the PPC architecture. machine = 'ppc' + # See 'i386' case + if sys.maxsize >= 2**32: + machine = 'ppc64' + return "%s-%s-%s" % (osname, release, machine) # get_platform () From python-checkins at python.org Thu Dec 24 14:30:42 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 13:30:42 -0000 Subject: [Python-checkins] r77030 - python/trunk/Mac/BuildScript/build-installer.py Message-ID: Author: ronald.oussoren Date: Thu Dec 24 14:30:42 2009 New Revision: 77030 Log: An update to the script that's used to build the binary installer: don't install files in /usr/local by default. Users can still choose to install files into /usr/local, but by default we'll only install files in /Library/Framework/Python.framework and /Applications/Python X.Y/ Modified: python/trunk/Mac/BuildScript/build-installer.py Modified: python/trunk/Mac/BuildScript/build-installer.py ============================================================================== --- python/trunk/Mac/BuildScript/build-installer.py (original) +++ python/trunk/Mac/BuildScript/build-installer.py Thu Dec 24 14:30:42 2009 @@ -249,6 +249,7 @@ wrappers for lots of Mac OS X API's. """, postflight="scripts/postflight.framework", + selected='selected', ), dict( name="PythonApplications", @@ -262,6 +263,7 @@ It also installs a number of examples and demos. """, required=False, + selected='selected', ), dict( name="PythonUnixTools", @@ -273,6 +275,7 @@ is not necessary to use Python. """, required=False, + selected='unselected', ), dict( name="PythonDocumentation", @@ -287,6 +290,7 @@ """, postflight="scripts/postflight.documentation", required=False, + selected='selected', ), dict( name="PythonProfileChanges", @@ -304,6 +308,7 @@ topdir="/Library/Frameworks/Python.framework", source="/empty-dir", required=False, + selected='selected', ), ] @@ -321,6 +326,7 @@ topdir="/Library/Frameworks/Python.framework", source="/empty-dir", required=False, + selected='selected', ) ) return result @@ -923,7 +929,7 @@ IFPkgFlagPackageList=[ dict( IFPkgFlagPackageLocation='%s-%s.pkg'%(item['name'], getVersion()), - IFPkgFlagPackageSelection='selected' + IFPkgFlagPackageSelection=item.get('selected', 'selected'), ) for item in pkg_recipes() ], From python-checkins at python.org Thu Dec 24 14:30:59 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 13:30:59 -0000 Subject: [Python-checkins] r77031 - in python/trunk: Lib/idlelib/macosxSupport.py Mac/IDLE/Info.plist.in Mac/IDLE/Makefile.in Mac/IDLE/idlemain.py Mac/Makefile.in Mac/README Mac/Tools/pythonw.c Makefile.pre.in Misc/NEWS configure configure.in Message-ID: Author: ronald.oussoren Date: Thu Dec 24 14:30:58 2009 New Revision: 77031 Log: Issue #6834: replace the implementation for the 'python' and 'pythonw' executables on OSX. The previous implementation used execv(2) to run the real interpreter, which means that you cannot use the arch(1) tool to select the architecture you want to use for a universal build because that only affects the python/pythonw wrapper and not the actual interpreter. The new version uses posix_spawnv with a number of OSX-specific options that ensure that the real interpreter is started using the same CPU architecture as the wrapper, and that means that 'arch -ppc python' now actually works. I've also changed the way that the wrapper looks for the framework: it is now linked to the framework rather than hardcoding the framework path. This should make it easier to provide pythonw support in tools like virtualenv. Modified: python/trunk/Lib/idlelib/macosxSupport.py python/trunk/Mac/IDLE/Info.plist.in python/trunk/Mac/IDLE/Makefile.in python/trunk/Mac/IDLE/idlemain.py python/trunk/Mac/Makefile.in python/trunk/Mac/README python/trunk/Mac/Tools/pythonw.c python/trunk/Makefile.pre.in python/trunk/Misc/NEWS python/trunk/configure python/trunk/configure.in Modified: python/trunk/Lib/idlelib/macosxSupport.py ============================================================================== --- python/trunk/Lib/idlelib/macosxSupport.py (original) +++ python/trunk/Lib/idlelib/macosxSupport.py Thu Dec 24 14:30:58 2009 @@ -5,13 +5,19 @@ import sys import Tkinter + +_appbundle = None + def runningAsOSXApp(): """ Returns True if Python is running from within an app on OSX. If so, assume that Python was built with Aqua Tcl/Tk rather than X11 Tcl/Tk. """ - return (sys.platform == 'darwin' and '.app' in sys.executable) + global _appbundle + if _appbundle is None: + _appbundle = (sys.platform == 'darwin' and '.app' in sys.executable) + return _appbundle def addOpenEventSupport(root, flist): """ Modified: python/trunk/Mac/IDLE/Info.plist.in ============================================================================== --- python/trunk/Mac/IDLE/Info.plist.in (original) +++ python/trunk/Mac/IDLE/Info.plist.in Thu Dec 24 14:30:58 2009 @@ -51,5 +51,14 @@ %VERSION% CFBundleVersion %VERSION% + Modified: python/trunk/Mac/IDLE/Makefile.in ============================================================================== --- python/trunk/Mac/IDLE/Makefile.in (original) +++ python/trunk/Mac/IDLE/Makefile.in Thu Dec 24 14:30:58 2009 @@ -10,6 +10,8 @@ UNIVERSALSDK=@UNIVERSALSDK@ builddir= ../.. PYTHONFRAMEWORK=@PYTHONFRAMEWORK@ +LIPO_32BIT_FLAGS=@LIPO_32BIT_FLAGS@ + RUNSHARED= @RUNSHARED@ BUILDEXE= @BUILDEXEEXT@ @@ -51,9 +53,12 @@ --iconfile=$(srcdir)/../Icons/IDLE.icns \ --resource=$(srcdir)/../Icons/PythonSource.icns \ --resource=$(srcdir)/../Icons/PythonCompiled.icns \ - --python=$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)`test -f "$(DESTDIR)$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)-32" && echo "-32"` \ + --python=$(prefix)/Resources/Python.app/Contents/MacOS/Python \ build - +ifneq ($(LIPO_32BIT_FLAGS),) + rm "IDLE.app/Contents/MacOS/Python" + lipo $(LIPO_32BIT_FLAGS) -output "IDLE.app/Contents/MacOS/Python" "$(BUILDPYTHON)" +endif Info.plist: $(srcdir)/Info.plist.in sed 's/%VERSION%/'"`$(RUNSHARED) $(BUILDPYTHON) -c 'import platform; print platform.python_version()'`"'/g' < $(srcdir)/Info.plist.in > Info.plist Modified: python/trunk/Mac/IDLE/idlemain.py ============================================================================== --- python/trunk/Mac/IDLE/idlemain.py (original) +++ python/trunk/Mac/IDLE/idlemain.py Thu Dec 24 14:30:58 2009 @@ -48,7 +48,7 @@ # the interpreter in the framework, by following the symlink # exported in PYTHONEXECUTABLE. pyex = os.environ['PYTHONEXECUTABLE'] -sys.executable = os.path.join(os.path.dirname(pyex), os.readlink(pyex)) +sys.executable = os.path.join(sys.prefix, 'bin', 'python%d.%d'%(sys.version_info[:2])) # Remove any sys.path entries for the Resources dir in the IDLE.app bundle. p = pyex.partition('.app') @@ -68,6 +68,8 @@ break # Now it is safe to import idlelib. +from idlelib import macosxSupport +macosxSupport._appbundle = True from idlelib.PyShell import main if __name__ == '__main__': main() Modified: python/trunk/Mac/Makefile.in ============================================================================== --- python/trunk/Mac/Makefile.in (original) +++ python/trunk/Mac/Makefile.in Thu Dec 24 14:30:58 2009 @@ -15,6 +15,7 @@ FRAMEWORKUNIXTOOLSPREFIX=@FRAMEWORKUNIXTOOLSPREFIX@ PYTHONFRAMEWORK=@PYTHONFRAMEWORK@ PYTHONFRAMEWORKIDENTIFIER=@PYTHONFRAMEWORKIDENTIFIER@ +LIPO_32BIT_FLAGS=@LIPO_32BIT_FLAGS@ # These are normally glimpsed from the previous set @@ -42,10 +43,8 @@ CACHERSRC=$(srcdir)/scripts/cachersrc.py compileall=$(srcdir)/../Lib/compileall.py -installapps: install_Python install_BuildApplet install_PythonLauncher \ - install_IDLE checkapplepython install_pythonw install_versionedtools - -installapps4way: install_Python4way install_BuildApplet install_PythonLauncher install_IDLE install_pythonw4way install_versionedtools +installapps: install_Python install_pythonw install_BuildApplet install_PythonLauncher \ + install_IDLE checkapplepython install_versionedtools install_pythonw: pythonw @@ -53,33 +52,13 @@ $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/python$(VERSION)" ln -sf python$(VERSION) "$(DESTDIR)$(prefix)/bin/python" ln -sf pythonw$(VERSION) "$(DESTDIR)$(prefix)/bin/pythonw" - - -# Install 3 variants of python/pythonw: -# - 32-bit (i386 and ppc) -# - 64-bit (x86_64 and ppc64) -# - all (all four architectures) -# - Make 'python' and 'pythonw' aliases for the 32-bit variant -install_pythonw4way: pythonw-32 pythonw-64 pythonw - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-64 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-64" - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-64 "$(DESTDIR)$(prefix)/bin/python$(VERSION)-64" - ln -sf python$(VERSION)-64 "$(DESTDIR)$(prefix)/bin/python-64" - ln -sf pythonw$(VERSION)-64 "$(DESTDIR)$(prefix)/bin/pythonw-64" - - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-32 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-32" - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-32 "$(DESTDIR)$(prefix)/bin/python$(VERSION)-32" +ifneq ($(LIPO_32BIT_FLAGS),) + lipo $(LIPO_32BIT_FLAGS) -output $(DESTDIR)$(prefix)/bin/python$(VERSION)-32 pythonw + lipo $(LIPO_32BIT_FLAGS) -output $(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-32 pythonw ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python-32" ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw-32" +endif - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-all" - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/python$(VERSION)-all" - ln -sf python$(VERSION)-all "$(DESTDIR)$(prefix)/bin/python-all" - ln -sf pythonw$(VERSION)-all "$(DESTDIR)$(prefix)/bin/pythonw-all" - - ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)" - ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python$(VERSION)" - ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw" - ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python" # # Install unix tools in /usr/local/bin. These are just aliases for the @@ -97,10 +76,6 @@ done -# TODO: install symlinks for -32, -64 and -all as well -installunixtools4way: installunixtools - - # # Like installunixtools, but only install links to the versioned binaries. # @@ -114,9 +89,6 @@ ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\ done -# TODO: -32, -64 and -all variants -altinstallunixtools4way: altinstallunixtools - # By default most tools are installed without a version in their basename, to # make it easier to install (and use) several python versions side-by-side move # the tools to a version-specific name and add the non-versioned name as an @@ -141,16 +113,7 @@ pythonw: $(srcdir)/Tools/pythonw.c Makefile - $(CC) $(LDFLAGS) -o $@ $(srcdir)/Tools/pythonw.c \ - -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"' - -pythonw-32: $(srcdir)/Tools/pythonw.c Makefile - $(CC) $(LDFLAGS) -o $@ -arch i386 -arch ppc $(srcdir)/Tools/pythonw.c \ - -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-32"' - -pythonw-64: $(srcdir)/Tools/pythonw.c Makefile - $(CC) $(LDFLAGS) -o $@ -arch x86_64 -arch ppc64 $(srcdir)/Tools/pythonw.c \ - -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-64"' + $(CC) $(LDFLAGS) -o $@ $(srcdir)/Tools/pythonw.c -I.. -I$(srcdir)/../Include ../$(PYTHONFRAMEWORK).framework/Versions/$(VERSION)/$(PYTHONFRAMEWORK) install_PythonLauncher: cd PythonLauncher && make install DESTDIR=$(DESTDIR) @@ -206,11 +169,6 @@ > "$(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)" - lipo -extract x86_64 -extract ppc64 -output "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-64" "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" - - install_IDLE: cd IDLE && make install @@ -218,9 +176,13 @@ install_BuildApplet: $(RUNSHARED) @ARCH_RUN_32BIT@ $(BUILDPYTHON) $(srcdir)/scripts/BuildApplet.py \ --destroot "$(DESTDIR)" \ - --python=$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)`test -f "$(DESTDIR)$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)-32" && echo "-32"` \ + --python=$(prefix)/Resources/Python.app/Contents/MacOS/Python \ --output "$(DESTDIR)$(PYTHONAPPSDIR)/Build Applet.app" \ $(srcdir)/scripts/BuildApplet.py +ifneq ($(LIPO_32BIT_FLAGS),) + rm "$(DESTDIR)$(PYTHONAPPSDIR)/Build Applet.app/Contents/MacOS/Python" + lipo $(LIPO_32BIT_FLAGS) -output "$(DESTDIR)$(PYTHONAPPSDIR)/Build Applet.app/Contents/MacOS/Python" $(BUILDPYTHON) +endif MACLIBDEST=$(LIBDEST)/plat-mac MACTOOLSDEST=$(prefix)/Mac/Tools Modified: python/trunk/Mac/README ============================================================================== --- python/trunk/Mac/README (original) +++ python/trunk/Mac/README Thu Dec 24 14:30:58 2009 @@ -25,7 +25,7 @@ Create a universal binary build of of Python. This can be used with both regular and framework builds. - The optional argument specifies with OSX SDK should be used to perform the + The optional argument specifies which OSX SDK should be used to perform the build. This defaults to ``/Developer/SDKs/MacOSX.10.4u.sdk``, specify ``/`` when building on a 10.5 system, especially when building 64-bit code. @@ -88,10 +88,29 @@ * ``intel``: ``i386``, ``x86_64`` -To build a universal binary that includes a 64-bit architecture you must build -on a system running OSX 10.5 or later. The ``all`` flavour can only be build on +To build a universal binary that includes a 64-bit architecture, you must build +on a system running OSX 10.5 or later. The ``all`` flavour can only be built on OSX 10.5. +The makefile for a framework build will install ``python32`` and ``pythonw32`` +binaries when the universal architecures includes at least one 32-bit architecture +(that is, for all flavours but ``64-bit``). + +Running a specific archicture +............................. + +You can run code using a specific architecture using the ``arch`` command:: + + $ arch -i386 python + +Or to explicitly run in 32-bit mode, regardless of the machine hardware:: + + $ arch -i386 -ppc python + +NOTE: When you're using a framework install of Python this requires at least +Python 2.7 or 3.2, in earlier versions the python (and pythonw) commands are +wrapper tools that execute the real interpreter without ensuring that the +real interpreter runs with the same architecture. Building and using a framework-based Python on Mac OS X. ======================================================== Modified: python/trunk/Mac/Tools/pythonw.c ============================================================================== --- python/trunk/Mac/Tools/pythonw.c (original) +++ python/trunk/Mac/Tools/pythonw.c Thu Dec 24 14:30:58 2009 @@ -3,15 +3,145 @@ * application bundle inside the Python framework. This is needed to run * GUI code: some GUI API's don't work unless the program is inside an * application bundle. + * + * This program uses posix_spawn rather than plain execv because we need + * slightly more control over how the "real" interpreter is executed. */ #include +#include +#include +#include +#include #include +#include +#include +#include -static char Python[] = PYTHONWEXECUTABLE; -int main(int argc, char **argv) { - argv[0] = Python; - execv(Python, argv); - err(1, "execv: %s", Python); +extern char** environ; + +/* + * Locate the python framework by looking for the + * library that contains Py_Initialize. + * + * In a regular framework the structure is: + * + * Python.framework/Versions/2.7 + * /Python + * /Resources/Python.app/Contents/MacOS/Python + * + * In a virtualenv style structure the expected + * structure is: + * + * ROOT + * /bin/pythonw + * /.Python <- the dylib + * /.Resources/Python.app/Contents/MacOS/Python + * + * NOTE: virtualenv's are not an officially supported + * feature, support for that structure is provided as + * a convenience. + */ +static char* get_python_path(void) +{ + size_t len; + Dl_info info; + char* end; + char* g_path; + + if (dladdr(Py_Initialize, &info) == 0) { + return NULL; + } + + len = strlen(info.dli_fname); + + g_path = malloc(len+60); + if (g_path == NULL) { + return NULL; + } + + strcpy(g_path, info.dli_fname); + end = g_path + len - 1; + while (end != g_path && *end != '/') { + end --; + } + end++; + if (end[1] == '.') { + end++; + } + strcpy(end, "Resources/Python.app/Contents/MacOS/Python"); + + return g_path; +} + +static void +setup_spawnattr(posix_spawnattr_t* spawnattr) +{ + size_t ocount; + size_t count; + cpu_type_t cpu_types[1]; + short flags = 0; +#ifdef __LP64__ + int ch; +#endif + + if ((errno = posix_spawnattr_init(spawnattr)) != 0) { + err(2, "posix_spawnattr_int"); + /* NOTREACHTED */ + } + + count = 1; + + /* Run the real python executable using the same architure as this + * executable, this allows users to controle the architecture using + * "arch -ppc python" + */ + +#if defined(__ppc64__) + cpu_types[0] = CPU_TYPE_POWERPC64; + +#elif defined(__x86_64__) + cpu_types[0] = CPU_TYPE_X86_64; + +#elif defined(__ppc__) + cpu_types[0] = CPU_TYPE_POWERPC; +#elif defined(__i386__) + cpu_types[0] = CPU_TYPE_X86; +#else +# error "Unknown CPU" +#endif + + if (posix_spawnattr_setbinpref_np(spawnattr, count, + cpu_types, &ocount) == -1) { + err(1, "posix_spawnattr_setbinpref"); + /* NOTREACHTED */ + } + if (count != ocount) { + fprintf(stderr, "posix_spawnattr_setbinpref failed to copy\n"); + exit(1); + /* NOTREACHTED */ + } + + + /* + * Set flag that causes posix_spawn to behave like execv + */ + flags |= POSIX_SPAWN_SETEXEC; + if ((errno = posix_spawnattr_setflags(spawnattr, flags)) != 0) { + err(1, "posix_spawnattr_setflags"); + /* NOTREACHTED */ + } +} + +int +main(int argc, char **argv) { + posix_spawnattr_t spawnattr = NULL; + char* exec_path = get_python_path(); + + + setup_spawnattr(&spawnattr); + posix_spawn(NULL, exec_path, NULL, + &spawnattr, argv, environ); + err(1, "posix_spawn: %s", argv[0]); /* NOTREACHED */ } Modified: python/trunk/Makefile.pre.in ============================================================================== --- python/trunk/Makefile.pre.in (original) +++ python/trunk/Makefile.pre.in Thu Dec 24 14:30:58 2009 @@ -1079,22 +1079,13 @@ frameworkinstallapps: cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)" -frameworkinstallapps4way: - cd Mac && $(MAKE) installapps4way DESTDIR="$(DESTDIR)" - # This install the unix python and pythonw tools in /usr/local/bin frameworkinstallunixtools: cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)" -frameworkinstallunixtools4way: - cd Mac && $(MAKE) installunixtools4way DESTDIR="$(DESTDIR)" - frameworkaltinstallunixtools: cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)" -frameworkaltinstallunixtools4way: - cd Mac && $(MAKE) altinstallunixtools4way DESTDIR="$(DESTDIR)" - # This installs the Demos and Tools into the applications directory. # It is not part of a normal frameworkinstall frameworkinstallextras: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Dec 24 14:30:58 2009 @@ -12,6 +12,13 @@ Core and Builtins ----------------- +- Issue #6834: replace the implementation for the 'python' and 'pythonw' + executables on OSX. + + These executables now work properly with the arch(1) command: + ``arch -ppc python`` will start a universal binary version of python + in PPC mode (unlike previous releases). + - Issue #1680159: unicode coercion during an 'in' operation no longer masks the underlying error when the coercion fails for the left hand operand. Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Thu Dec 24 14:30:58 2009 @@ -658,6 +658,7 @@ CONFIG_ARGS UNIVERSALSDK ARCH_RUN_32BIT +LIPO_32BIT_FLAGS PYTHONFRAMEWORK PYTHONFRAMEWORKIDENTIFIER PYTHONFRAMEWORKDIR @@ -1915,6 +1916,7 @@ UNIVERSAL_ARCHS="32-bit" + { echo "$as_me:$LINENO: checking for --with-universal-archs" >&5 echo $ECHO_N "checking for --with-universal-archs... $ECHO_C" >&6; } @@ -1994,14 +1996,8 @@ PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR FRAMEWORKINSTALLFIRST="frameworkinstallstructure" FRAMEWORKALTINSTALLFIRST="frameworkinstallstructure bininstall maninstall" - if test "$UNIVERSAL_ARCHS" = "all" - then - FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkinstallunixtools4way" - FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkaltinstallunixtools4way" - else - FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" - FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" - fi + FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" + FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" if test "x${prefix}" = "xNONE" ; then FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" @@ -2041,11 +2037,6 @@ fi enable_framework= - if test "$UNIVERSAL_ARCHS" = "all" - then - FRAMEWORKINSTALLLAST=update4wayuniversal - FRAMEWORKALTINSTALLLAST=update4wayuniversal - fi fi @@ -3866,7 +3857,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f conftest* +rm -f -r conftest* @@ -4697,22 +4688,27 @@ if test "$UNIVERSAL_ARCHS" = "32-bit" ; then UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386" ARCH_RUN_32BIT="" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" elif test "$UNIVERSAL_ARCHS" = "64-bit" ; then UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="" ARCH_RUN_32BIT="true" elif test "$UNIVERSAL_ARCHS" = "all" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" ARCH_RUN_32BIT="arch -i386 -ppc" elif test "$UNIVERSAL_ARCHS" = "intel" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch x86_64" + LIPO_32BIT_FLAGS="-extract i386" ARCH_RUN_32BIT="arch -i386" elif test "$UNIVERSAL_ARCHS" = "3-way" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch x86_64" - ARCH_RUN_32BIT="arch -i386 -ppc" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" + ARCH_RUN_32BIT="arch -i386 -ppc7400" else { { echo "$as_me:$LINENO: error: proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" >&5 @@ -5414,7 +5410,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -5435,7 +5431,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -6533,7 +6529,7 @@ fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -7063,7 +7059,7 @@ else ac_cv_type_uid_t=no fi -rm -f conftest* +rm -f -r conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -15723,7 +15719,7 @@ else unistd_defines_pthreads=no fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -17337,7 +17333,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f conftest* +rm -f -r conftest* ;; kame) @@ -17360,7 +17356,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-glibc) @@ -17381,7 +17377,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-inet6) @@ -17419,7 +17415,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; v6d) @@ -17442,7 +17438,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f conftest* +rm -f -r conftest* ;; zeta) @@ -17464,7 +17460,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; esac @@ -26007,7 +26003,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -26026,7 +26022,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -26296,7 +26292,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -28235,6 +28231,7 @@ CONFIG_ARGS!$CONFIG_ARGS$ac_delim UNIVERSALSDK!$UNIVERSALSDK$ac_delim ARCH_RUN_32BIT!$ARCH_RUN_32BIT$ac_delim +LIPO_32BIT_FLAGS!$LIPO_32BIT_FLAGS$ac_delim PYTHONFRAMEWORK!$PYTHONFRAMEWORK$ac_delim PYTHONFRAMEWORKIDENTIFIER!$PYTHONFRAMEWORKIDENTIFIER$ac_delim PYTHONFRAMEWORKDIR!$PYTHONFRAMEWORKDIR$ac_delim @@ -28289,7 +28286,6 @@ SO!$SO$ac_delim LDSHARED!$LDSHARED$ac_delim BLDSHARED!$BLDSHARED$ac_delim -CCSHARED!$CCSHARED$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -28331,6 +28327,7 @@ ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +CCSHARED!$CCSHARED$ac_delim LINKFORSHARED!$LINKFORSHARED$ac_delim CFLAGSFORSHARED!$CFLAGSFORSHARED$ac_delim SHLIBS!$SHLIBS$ac_delim @@ -28357,7 +28354,7 @@ LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 24; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 25; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Thu Dec 24 14:30:58 2009 @@ -112,6 +112,7 @@ AC_SUBST(ARCH_RUN_32BIT) UNIVERSAL_ARCHS="32-bit" +AC_SUBST(LIPO_32BIT_FLAGS) AC_MSG_CHECKING(for --with-universal-archs) AC_ARG_WITH(universal-archs, AC_HELP_STRING(--with-universal-archs=ARCH, select architectures for universal build ("32-bit", "64-bit", "3-way", "intel" or "all")), @@ -177,14 +178,8 @@ PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR FRAMEWORKINSTALLFIRST="frameworkinstallstructure" FRAMEWORKALTINSTALLFIRST="frameworkinstallstructure bininstall maninstall" - if test "$UNIVERSAL_ARCHS" = "all" - then - FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkinstallunixtools4way" - FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkaltinstallunixtools4way" - else - FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" - FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" - fi + FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" + FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" if test "x${prefix}" = "xNONE" ; then FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" @@ -217,11 +212,6 @@ fi enable_framework= - if test "$UNIVERSAL_ARCHS" = "all" - then - FRAMEWORKINSTALLLAST=update4wayuniversal - FRAMEWORKALTINSTALLLAST=update4wayuniversal - fi ]) AC_SUBST(PYTHONFRAMEWORK) AC_SUBST(PYTHONFRAMEWORKIDENTIFIER) @@ -952,22 +942,27 @@ if test "$UNIVERSAL_ARCHS" = "32-bit" ; then UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386" ARCH_RUN_32BIT="" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" elif test "$UNIVERSAL_ARCHS" = "64-bit" ; then UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="" ARCH_RUN_32BIT="true" elif test "$UNIVERSAL_ARCHS" = "all" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" ARCH_RUN_32BIT="arch -i386 -ppc" elif test "$UNIVERSAL_ARCHS" = "intel" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch x86_64" + LIPO_32BIT_FLAGS="-extract i386" ARCH_RUN_32BIT="arch -i386" elif test "$UNIVERSAL_ARCHS" = "3-way" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch x86_64" - ARCH_RUN_32BIT="arch -i386 -ppc" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" + ARCH_RUN_32BIT="arch -i386 -ppc7400" else AC_MSG_ERROR([proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way]) From python-checkins at python.org Thu Dec 24 15:03:20 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 14:03:20 -0000 Subject: [Python-checkins] r77032 - in python/branches/py3k: Lib/idlelib/macosxSupport.py Mac/Makefile.in Mac/README Mac/Tools/pythonw.c Makefile.pre.in Misc/NEWS configure configure.in Message-ID: Author: ronald.oussoren Date: Thu Dec 24 15:03:19 2009 New Revision: 77032 Log: Merged revisions 77031 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77031 | ronald.oussoren | 2009-12-24 14:30:58 +0100 (Thu, 24 Dec 2009) | 15 lines Issue #6834: replace the implementation for the 'python' and 'pythonw' executables on OSX. The previous implementation used execv(2) to run the real interpreter, which means that you cannot use the arch(1) tool to select the architecture you want to use for a universal build because that only affects the python/pythonw wrapper and not the actual interpreter. The new version uses posix_spawnv with a number of OSX-specific options that ensure that the real interpreter is started using the same CPU architecture as the wrapper, and that means that 'arch -ppc python' now actually works. I've also changed the way that the wrapper looks for the framework: it is now linked to the framework rather than hardcoding the framework path. This should make it easier to provide pythonw support in tools like virtualenv. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/idlelib/macosxSupport.py python/branches/py3k/Mac/Makefile.in python/branches/py3k/Mac/README python/branches/py3k/Mac/Tools/pythonw.c python/branches/py3k/Makefile.pre.in python/branches/py3k/Misc/NEWS python/branches/py3k/configure python/branches/py3k/configure.in Modified: python/branches/py3k/Lib/idlelib/macosxSupport.py ============================================================================== --- python/branches/py3k/Lib/idlelib/macosxSupport.py (original) +++ python/branches/py3k/Lib/idlelib/macosxSupport.py Thu Dec 24 15:03:19 2009 @@ -5,13 +5,19 @@ import sys import tkinter + +_appbundle = None + def runningAsOSXApp(): """ Returns True if Python is running from within an app on OSX. If so, assume that Python was built with Aqua Tcl/Tk rather than X11 Tcl/Tk. """ - return (sys.platform == 'darwin' and '.app' in sys.executable) + global _appbundle + if _appbundle is None: + _appbundle = (sys.platform == 'darwin' and '.app' in sys.executable) + return _appbundle def addOpenEventSupport(root, flist): """ Modified: python/branches/py3k/Mac/Makefile.in ============================================================================== --- python/branches/py3k/Mac/Makefile.in (original) +++ python/branches/py3k/Mac/Makefile.in Thu Dec 24 15:03:19 2009 @@ -15,6 +15,7 @@ FRAMEWORKUNIXTOOLSPREFIX=@FRAMEWORKUNIXTOOLSPREFIX@ PYTHONFRAMEWORK=@PYTHONFRAMEWORK@ PYTHONFRAMEWORKIDENTIFIER=@PYTHONFRAMEWORKIDENTIFIER@ +LIPO_32BIT_FLAGS=@LIPO_32BIT_FLAGS@ # These are normally glimpsed from the previous set @@ -41,11 +42,8 @@ APPSUBDIRS=MacOS Resources compileall=$(srcdir)/../Lib/compileall.py -installapps: install_Python install_PythonLauncher install_IDLE \ - checkapplepython install_pythonw install_versionedtools - -installapps4way: install_Python4way install_PythonLauncher \ - install_IDLE4way install_pythonw4way install_versionedtools +installapps: install_Python install_pythonw install_PythonLauncher install_IDLE \ + checkapplepython install_versionedtools install_pythonw: pythonw @@ -53,33 +51,12 @@ $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/python$(VERSION)" ln -sf python$(VERSION) "$(DESTDIR)$(prefix)/bin/python3" ln -sf pythonw$(VERSION) "$(DESTDIR)$(prefix)/bin/pythonw3" - - -# Install 3 variants of python/pythonw: -# - 32-bit (i386 and ppc) -# - 64-bit (x86_64 and ppc64) -# - all (all four architectures) -# - Make 'python' and 'pythonw' aliases for the 32-bit variant -install_pythonw4way: pythonw-32 pythonw-64 pythonw - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-64 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-64" - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-64 "$(DESTDIR)$(prefix)/bin/python$(VERSION)-64" - ln -sf python$(VERSION)-64 "$(DESTDIR)$(prefix)/bin/python3-64" - ln -sf pythonw$(VERSION)-64 "$(DESTDIR)$(prefix)/bin/pythonw3-64" - - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-32 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-32" - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw-32 "$(DESTDIR)$(prefix)/bin/python$(VERSION)-32" - ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python3-32" - ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw3-32" - - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-all" - $(INSTALL_PROGRAM) $(STRIPFLAG) pythonw "$(DESTDIR)$(prefix)/bin/python$(VERSION)-all" - ln -sf python$(VERSION)-all "$(DESTDIR)$(prefix)/bin/python3-all" - ln -sf pythonw$(VERSION)-all "$(DESTDIR)$(prefix)/bin/pythonw3-all" - +ifneq ($(LIPO_32BIT_FLAGS),) + lipo $(LIPO_32BIT_FLAGS) -output $(DESTDIR)$(prefix)/bin/python$(VERSION)-32 pythonw + lipo $(LIPO_32BIT_FLAGS) -output $(DESTDIR)$(prefix)/bin/pythonw$(VERSION)-32 pythonw ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw$(VERSION)" ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python$(VERSION)" - ln -sf pythonw$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/pythonw3" - ln -sf python$(VERSION)-32 "$(DESTDIR)$(prefix)/bin/python3" +endif # # Install unix tools in /usr/local/bin. These are just aliases for the @@ -98,10 +75,6 @@ done -# TODO: install symlinks for -32, -64 and -all as well -installunixtools4way: installunixtools - - # # Like installunixtools, but only install links to the versioned binaries. # @@ -115,9 +88,6 @@ ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\ done -# TODO: -32, -64 and -all variants -altinstallunixtools4way: altinstallunixtools - # By default most tools are installed without a version in their basename, to # make it easier to install (and use) several python versions side-by-side move # the tools to a version-specific name and add the non-versioned name as an @@ -140,16 +110,7 @@ pythonw: $(srcdir)/Tools/pythonw.c Makefile - $(CC) $(LDFLAGS) -o $@ $(srcdir)/Tools/pythonw.c \ - -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"' - -pythonw-32: $(srcdir)/Tools/pythonw.c Makefile - $(CC) $(LDFLAGS) -o $@ -arch i386 -arch ppc $(srcdir)/Tools/pythonw.c \ - -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-32"' - -pythonw-64: $(srcdir)/Tools/pythonw.c Makefile - $(CC) $(LDFLAGS) -o $@ -arch x86_64 -arch ppc64 $(srcdir)/Tools/pythonw.c \ - -DPYTHONWEXECUTABLE='"$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-64"' + $(CC) $(LDFLAGS) -o $@ $(srcdir)/Tools/pythonw.c -I.. -I$(srcdir)/../Include ../$(PYTHONFRAMEWORK).framework/Versions/$(VERSION)/$(PYTHONFRAMEWORK) install_PythonLauncher: cd PythonLauncher && make install DESTDIR=$(DESTDIR) @@ -205,11 +166,6 @@ > "$(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)" - lipo -extract x86_64 -extract ppc64 -output "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-64" "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" - - install_IDLE: test -d "$(DESTDIR)$(PYTHONAPPSDIR)" || mkdir -p "$(DESTDIR)$(PYTHONAPPSDIR)" @@ -237,11 +193,6 @@ fi touch "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" -install_IDLE4way: install_IDLE - ln -sf "$(INSTALLED_PYTHONAPP)-32" "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app/Contents/MacOS/Python" - sed -e "s!%prefix%!$(prefix)!g" -e 's!%exe%!$(PYTHONFRAMEWORK)-32!g' < "$(srcdir)/IDLE/IDLE.app/Contents/MacOS/IDLE" > "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app/Contents/MacOS/IDLE" - touch "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" - $(INSTALLED_PYTHONAPP): install_Python installextras: $(srcdir)/Extras.ReadMe.txt $(srcdir)/Extras.install.py Modified: python/branches/py3k/Mac/README ============================================================================== --- python/branches/py3k/Mac/README (original) +++ python/branches/py3k/Mac/README Thu Dec 24 15:03:19 2009 @@ -5,6 +5,35 @@ This document provides a quick overview of some Mac OS X specific features in the Python distribution. +* ``--enable-framework`` + + If this argument is specified the build will create a Python.framework rather + than a traditional Unix install. See the section + _`Building and using a framework-based Python on Mac OS X` for more + information on frameworks. + +* ``--with-framework-name=NAME`` + + Specify the name for the python framework, defaults to ``Python``. This option + is only valid when ``--enable-framework`` is specified. + +* ``--enable-universalsdk[=PATH]`` + + Create a universal binary build of of Python. This can be used with both + regular and framework builds. + + The optional argument specifies which OSX SDK should be used to perform the + build. This defaults to ``/Developer/SDKs/MacOSX.10.4u.sdk``, specify + ``/`` when building on a 10.5 system, especially when building 64-bit code. + + See the section _`Building and using a universal binary of Python on Mac OS X` + for more information. + +* ``--with-univeral-archs=VALUE`` + + Specify the kind of universal binary that should be created. This option is + only valid when ``--enable-universalsdk`` is specified. + Building and using a universal binary of Python on Mac OS X =========================================================== @@ -31,6 +60,47 @@ with Xcode 2.1 (or later). You also have to install the 10.4u SDK when installing Xcode. +2.1 Flavours of universal binaries +.................................. + +It is possible to build a number of flavours of the universal binary build, +the default is a 32-bit only binary (i386 and ppc). The flavour can be +specified using the option ``--with-universal-archs=VALUE``. The following +values are available: + + * ``32-bit``: ``ppc``, ``i386`` + + * ``64-bit``: ``ppc64``, ``x86_64`` + + * ``all``: ``ppc``, ``ppc64``, ``i386``, ``x86_64`` + + * ``3-way``: ``ppc``, ``i386`` and ``x86_64`` + + * ``intel``: ``i386``, ``x86_64`` + +To build a universal binary that includes a 64-bit architecture, you must build +on a system running OSX 10.5 or later. The ``all`` flavour can only be built on +OSX 10.5. + +The makefile for a framework build will install ``python32`` and ``pythonw32`` +binaries when the universal architecures includes at least one 32-bit architecture +(that is, for all flavours but ``64-bit``). + +Running a specific archicture +............................. + +You can run code using a specific architecture using the ``arch`` command:: + + $ arch -i386 python + +Or to explicitly run in 32-bit mode, regardless of the machine hardware:: + + $ arch -i386 -ppc python + +NOTE: When you're using a framework install of Python this requires at least +Python 2.7 or 3.2, in earlier versions the python (and pythonw) commands are +wrapper tools that execute the real interpreter without ensuring that the +real interpreter runs with the same architecture. Building and using a framework-based Python on Mac OS X. ======================================================== Modified: python/branches/py3k/Mac/Tools/pythonw.c ============================================================================== --- python/branches/py3k/Mac/Tools/pythonw.c (original) +++ python/branches/py3k/Mac/Tools/pythonw.c Thu Dec 24 15:03:19 2009 @@ -3,15 +3,145 @@ * application bundle inside the Python framework. This is needed to run * GUI code: some GUI API's don't work unless the program is inside an * application bundle. + * + * This program uses posix_spawn rather than plain execv because we need + * slightly more control over how the "real" interpreter is executed. */ #include +#include +#include +#include +#include #include +#include +#include +#include -static char Python[] = PYTHONWEXECUTABLE; -int main(int argc, char **argv) { - argv[0] = Python; - execv(Python, argv); - err(1, "execv: %s", Python); +extern char** environ; + +/* + * Locate the python framework by looking for the + * library that contains Py_Initialize. + * + * In a regular framework the structure is: + * + * Python.framework/Versions/2.7 + * /Python + * /Resources/Python.app/Contents/MacOS/Python + * + * In a virtualenv style structure the expected + * structure is: + * + * ROOT + * /bin/pythonw + * /.Python <- the dylib + * /.Resources/Python.app/Contents/MacOS/Python + * + * NOTE: virtualenv's are not an officially supported + * feature, support for that structure is provided as + * a convenience. + */ +static char* get_python_path(void) +{ + size_t len; + Dl_info info; + char* end; + char* g_path; + + if (dladdr(Py_Initialize, &info) == 0) { + return NULL; + } + + len = strlen(info.dli_fname); + + g_path = malloc(len+60); + if (g_path == NULL) { + return NULL; + } + + strcpy(g_path, info.dli_fname); + end = g_path + len - 1; + while (end != g_path && *end != '/') { + end --; + } + end++; + if (end[1] == '.') { + end++; + } + strcpy(end, "Resources/Python.app/Contents/MacOS/Python"); + + return g_path; +} + +static void +setup_spawnattr(posix_spawnattr_t* spawnattr) +{ + size_t ocount; + size_t count; + cpu_type_t cpu_types[1]; + short flags = 0; +#ifdef __LP64__ + int ch; +#endif + + if ((errno = posix_spawnattr_init(spawnattr)) != 0) { + err(2, "posix_spawnattr_int"); + /* NOTREACHTED */ + } + + count = 1; + + /* Run the real python executable using the same architure as this + * executable, this allows users to controle the architecture using + * "arch -ppc python" + */ + +#if defined(__ppc64__) + cpu_types[0] = CPU_TYPE_POWERPC64; + +#elif defined(__x86_64__) + cpu_types[0] = CPU_TYPE_X86_64; + +#elif defined(__ppc__) + cpu_types[0] = CPU_TYPE_POWERPC; +#elif defined(__i386__) + cpu_types[0] = CPU_TYPE_X86; +#else +# error "Unknown CPU" +#endif + + if (posix_spawnattr_setbinpref_np(spawnattr, count, + cpu_types, &ocount) == -1) { + err(1, "posix_spawnattr_setbinpref"); + /* NOTREACHTED */ + } + if (count != ocount) { + fprintf(stderr, "posix_spawnattr_setbinpref failed to copy\n"); + exit(1); + /* NOTREACHTED */ + } + + + /* + * Set flag that causes posix_spawn to behave like execv + */ + flags |= POSIX_SPAWN_SETEXEC; + if ((errno = posix_spawnattr_setflags(spawnattr, flags)) != 0) { + err(1, "posix_spawnattr_setflags"); + /* NOTREACHTED */ + } +} + +int +main(int argc, char **argv) { + posix_spawnattr_t spawnattr = NULL; + char* exec_path = get_python_path(); + + + setup_spawnattr(&spawnattr); + posix_spawn(NULL, exec_path, NULL, + &spawnattr, argv, environ); + err(1, "posix_spawn: %s", argv[0]); /* NOTREACHED */ } Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Thu Dec 24 15:03:19 2009 @@ -1073,22 +1073,13 @@ frameworkinstallapps: cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)" -frameworkinstallapps4way: - cd Mac && $(MAKE) installapps4way DESTDIR="$(DESTDIR)" - # This install the unix python and pythonw tools in /usr/local/bin frameworkinstallunixtools: cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)" -frameworkinstallunixtools4way: - cd Mac && $(MAKE) installunixtools4way DESTDIR="$(DESTDIR)" - frameworkaltinstallunixtools: cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)" -frameworkaltinstallunixtools4way: - cd Mac && $(MAKE) altinstallunixtools4way DESTDIR="$(DESTDIR)" - # This installs the Demos and Tools into the applications directory. # It is not part of a normal frameworkinstall frameworkinstallextras: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 24 15:03:19 2009 @@ -12,6 +12,13 @@ Core and Builtins ----------------- +- Issue #6834: replace the implementation for the 'python' and 'pythonw' + executables on OSX. + + These executables now work properly with the arch(1) command: + ``arch -ppc python`` will start a universal binary version of python + in PPC mode (unlike previous releases). + - Issue #7466: segmentation fault when the garbage collector is called in the middle of populating a tuple. Patch by Florent Xicluna. Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Thu Dec 24 15:03:19 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76779 . +# From configure.in Revision: 76815 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -658,6 +658,7 @@ CONFIG_ARGS UNIVERSALSDK ARCH_RUN_32BIT +LIPO_32BIT_FLAGS PYTHONFRAMEWORK PYTHONFRAMEWORKIDENTIFIER PYTHONFRAMEWORKDIR @@ -1911,6 +1912,7 @@ UNIVERSAL_ARCHS="32-bit" + { echo "$as_me:$LINENO: checking for --with-universal-archs" >&5 echo $ECHO_N "checking for --with-universal-archs... $ECHO_C" >&6; } @@ -1976,14 +1978,8 @@ PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR FRAMEWORKINSTALLFIRST="frameworkinstallstructure" FRAMEWORKALTINSTALLFIRST="frameworkinstallstructure " - if test "$UNIVERSAL_ARCHS" = "all" - then - FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkinstallunixtools4way" - FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkaltinstallunixtools4way" - else - FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" - FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" - fi + FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" + FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" if test "x${prefix}" = "xNONE" ; then FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" @@ -2021,11 +2017,6 @@ fi enable_framework= - if test "$UNIVERSAL_ARCHS" = "all" - then - FRAMEWORKINSTALLLAST=update4wayuniversal - FRAMEWORKALTINSTALLLAST=update4wayuniversal - fi fi @@ -3801,7 +3792,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f conftest* +rm -f -r conftest* @@ -4622,22 +4613,27 @@ if test "$UNIVERSAL_ARCHS" = "32-bit" ; then UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386" ARCH_RUN_32BIT="" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" elif test "$UNIVERSAL_ARCHS" = "64-bit" ; then UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="" ARCH_RUN_32BIT="true" elif test "$UNIVERSAL_ARCHS" = "all" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" ARCH_RUN_32BIT="arch -i386 -ppc" elif test "$UNIVERSAL_ARCHS" = "intel" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch x86_64" + LIPO_32BIT_FLAGS="-extract i386" ARCH_RUN_32BIT="arch -i386" elif test "$UNIVERSAL_ARCHS" = "3-way" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch x86_64" - ARCH_RUN_32BIT="arch -i386 -ppc" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" + ARCH_RUN_32BIT="arch -i386 -ppc7400" else { { echo "$as_me:$LINENO: error: proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" >&5 @@ -5339,7 +5335,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -5360,7 +5356,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -6458,7 +6454,7 @@ fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -6988,7 +6984,7 @@ else ac_cv_type_uid_t=no fi -rm -f conftest* +rm -f -r conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -15530,7 +15526,7 @@ else unistd_defines_pthreads=no fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -16828,7 +16824,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f conftest* +rm -f -r conftest* ;; kame) @@ -16851,7 +16847,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-glibc) @@ -16872,7 +16868,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-inet6) @@ -16910,7 +16906,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; v6d) @@ -16933,7 +16929,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f conftest* +rm -f -r conftest* ;; zeta) @@ -16955,7 +16951,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; esac @@ -25296,7 +25292,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -25315,7 +25311,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -25585,7 +25581,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -27618,6 +27614,7 @@ CONFIG_ARGS!$CONFIG_ARGS$ac_delim UNIVERSALSDK!$UNIVERSALSDK$ac_delim ARCH_RUN_32BIT!$ARCH_RUN_32BIT$ac_delim +LIPO_32BIT_FLAGS!$LIPO_32BIT_FLAGS$ac_delim PYTHONFRAMEWORK!$PYTHONFRAMEWORK$ac_delim PYTHONFRAMEWORKIDENTIFIER!$PYTHONFRAMEWORKIDENTIFIER$ac_delim PYTHONFRAMEWORKDIR!$PYTHONFRAMEWORKDIR$ac_delim @@ -27672,7 +27669,6 @@ BLDSHARED!$BLDSHARED$ac_delim CCSHARED!$CCSHARED$ac_delim LINKFORSHARED!$LINKFORSHARED$ac_delim -CFLAGSFORSHARED!$CFLAGSFORSHARED$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -27714,6 +27710,7 @@ ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +CFLAGSFORSHARED!$CFLAGSFORSHARED$ac_delim SHLIBS!$SHLIBS$ac_delim USE_SIGNAL_MODULE!$USE_SIGNAL_MODULE$ac_delim SIGNAL_OBJS!$SIGNAL_OBJS$ac_delim @@ -27737,7 +27734,7 @@ LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 21; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 22; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Thu Dec 24 15:03:19 2009 @@ -112,6 +112,7 @@ AC_SUBST(ARCH_RUN_32BIT) UNIVERSAL_ARCHS="32-bit" +AC_SUBST(LIPO_32BIT_FLAGS) AC_MSG_CHECKING(for --with-universal-archs) AC_ARG_WITH(universal-archs, AC_HELP_STRING(--with-universal-archs=ARCH, select architectures for universal build ("32-bit", "64-bit", "3-way", "intel" or "all")), @@ -167,14 +168,8 @@ PYTHONFRAMEWORKINSTALLDIR=$PYTHONFRAMEWORKPREFIX/$PYTHONFRAMEWORKDIR FRAMEWORKINSTALLFIRST="frameworkinstallstructure" FRAMEWORKALTINSTALLFIRST="frameworkinstallstructure " - if test "$UNIVERSAL_ARCHS" = "all" - then - FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkinstallunixtools4way" - FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps4way frameworkaltinstallunixtools4way" - else - FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" - FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" - fi + FRAMEWORKINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools" + FRAMEWORKALTINSTALLLAST="frameworkinstallmaclib frameworkinstallapps frameworkaltinstallunixtools" if test "x${prefix}" = "xNONE" ; then FRAMEWORKUNIXTOOLSPREFIX="${ac_default_prefix}" @@ -206,11 +201,6 @@ fi enable_framework= - if test "$UNIVERSAL_ARCHS" = "all" - then - FRAMEWORKINSTALLLAST=update4wayuniversal - FRAMEWORKALTINSTALLLAST=update4wayuniversal - fi ]) AC_SUBST(PYTHONFRAMEWORK) AC_SUBST(PYTHONFRAMEWORKIDENTIFIER) @@ -890,22 +880,27 @@ if test "$UNIVERSAL_ARCHS" = "32-bit" ; then UNIVERSAL_ARCH_FLAGS="-arch ppc -arch i386" ARCH_RUN_32BIT="" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" elif test "$UNIVERSAL_ARCHS" = "64-bit" ; then UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="" ARCH_RUN_32BIT="true" elif test "$UNIVERSAL_ARCHS" = "all" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" ARCH_RUN_32BIT="arch -i386 -ppc" elif test "$UNIVERSAL_ARCHS" = "intel" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch x86_64" + LIPO_32BIT_FLAGS="-extract i386" ARCH_RUN_32BIT="arch -i386" elif test "$UNIVERSAL_ARCHS" = "3-way" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch x86_64" - ARCH_RUN_32BIT="arch -i386 -ppc" + LIPO_32BIT_FLAGS="-extract ppc7400 -extract i386" + ARCH_RUN_32BIT="arch -i386 -ppc7400" else AC_MSG_ERROR([proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way]) From python-checkins at python.org Thu Dec 24 15:17:20 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 14:17:20 -0000 Subject: [Python-checkins] r77033 - in python/trunk: Makefile.pre.in Misc/NEWS Message-ID: Author: ronald.oussoren Date: Thu Dec 24 15:17:19 2009 New Revision: 77033 Log: Fix for issue #7541: python-config --ldflags doesn't pick up libpython2.5.a Modified: python/trunk/Makefile.pre.in python/trunk/Misc/NEWS Modified: python/trunk/Makefile.pre.in ============================================================================== --- python/trunk/Makefile.pre.in (original) +++ python/trunk/Makefile.pre.in Thu Dec 24 15:17:19 2009 @@ -1072,6 +1072,7 @@ # install (which includes python-config) happy. frameworkinstallmaclib: ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a" + ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).dylib" ln -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib" cd Mac && $(MAKE) installmacsubtree DESTDIR="$(DESTDIR)" Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Dec 24 15:17:19 2009 @@ -64,6 +64,9 @@ - Switch to OpenSSL 0.9.8l on Windows. +- Issue #7541: when using ``python-config`` with a framework install the compiler might + use the wrong library. + Tests ----- From python-checkins at python.org Thu Dec 24 15:19:38 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 14:19:38 -0000 Subject: [Python-checkins] r77034 - in python/branches/release26-maint: Makefile.pre.in Misc/NEWS Message-ID: Author: ronald.oussoren Date: Thu Dec 24 15:19:38 2009 New Revision: 77034 Log: Merged revisions 77033 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77033 | ronald.oussoren | 2009-12-24 15:17:19 +0100 (Thu, 24 Dec 2009) | 2 lines Fix for issue #7541: python-config --ldflags doesn't pick up libpython2.5.a ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Makefile.pre.in python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Makefile.pre.in ============================================================================== --- python/branches/release26-maint/Makefile.pre.in (original) +++ python/branches/release26-maint/Makefile.pre.in Thu Dec 24 15:19:38 2009 @@ -1051,6 +1051,7 @@ # install (which includes python-config) happy. frameworkinstallmaclib: ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a" + ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).dylib" cd Mac && $(MAKE) installmacsubtree DESTDIR="$(DESTDIR)" # This installs the IDE, the Launcher and other apps into /Applications Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Dec 24 15:19:38 2009 @@ -128,6 +128,10 @@ binary distribution on OSX 10.6 even when the user does not have the 10.4u SDK installed. +- Issue #7541: when using ``python-config`` with a framework install the compiler might + use the wrong library. + + Tests ----- From python-checkins at python.org Thu Dec 24 15:21:56 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 14:21:56 -0000 Subject: [Python-checkins] r77035 - in python/branches/py3k: Makefile.pre.in Misc/NEWS Message-ID: Author: ronald.oussoren Date: Thu Dec 24 15:21:55 2009 New Revision: 77035 Log: Merged revisions 77033 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77033 | ronald.oussoren | 2009-12-24 15:17:19 +0100 (Thu, 24 Dec 2009) | 2 lines Fix for issue #7541: python-config --ldflags doesn't pick up libpython2.5.a ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Makefile.pre.in python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Thu Dec 24 15:21:55 2009 @@ -1067,6 +1067,7 @@ # install (which includes python-config) happy. frameworkinstallmaclib: ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a" + ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).dylib" ln -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib" # This installs the IDE, the Launcher and other apps into /Applications Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 24 15:21:55 2009 @@ -516,6 +516,9 @@ - Issue 5390: Add uninstall icon independent of whether file extensions are installed. +- Issue #7541: when using ``python-config`` with a framework install the compiler might + use the wrong library. + Documentation ------------ From python-checkins at python.org Thu Dec 24 15:24:06 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 14:24:06 -0000 Subject: [Python-checkins] r77036 - in python/branches/release31-maint: Makefile.pre.in Misc/NEWS Message-ID: Author: ronald.oussoren Date: Thu Dec 24 15:24:05 2009 New Revision: 77036 Log: Merged revisions 77035 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77035 | ronald.oussoren | 2009-12-24 15:21:55 +0100 (Thu, 24 Dec 2009) | 9 lines Merged revisions 77033 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77033 | ronald.oussoren | 2009-12-24 15:17:19 +0100 (Thu, 24 Dec 2009) | 2 lines Fix for issue #7541: python-config --ldflags doesn't pick up libpython2.5.a ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Makefile.pre.in python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Makefile.pre.in ============================================================================== --- python/branches/release31-maint/Makefile.pre.in (original) +++ python/branches/release31-maint/Makefile.pre.in Thu Dec 24 15:24:05 2009 @@ -1068,6 +1068,7 @@ # install (which includes python-config) happy. frameworkinstallmaclib: ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a" + ln -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).dylib" ln -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib" # This installs the IDE, the Launcher and other apps into /Applications Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Dec 24 15:24:05 2009 @@ -278,6 +278,9 @@ - Issue #6801 : symmetric_difference_update also accepts |. Thanks to Carl Chenet. +- Issue #7541: when using ``python-config`` with a framework install the compiler might + use the wrong library. + Documentation ------------- From python-checkins at python.org Thu Dec 24 15:50:36 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 24 Dec 2009 14:50:36 -0000 Subject: [Python-checkins] r77037 - in python/trunk: Lib/distutils/tests/test_util.py Misc/NEWS Message-ID: Author: ronald.oussoren Date: Thu Dec 24 15:50:35 2009 New Revision: 77037 Log: Unittests and news items for the patch in r77026. 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 Thu Dec 24 15:50:35 2009 @@ -119,6 +119,26 @@ sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) ' '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]') sys.platform = 'darwin' + + self._set_uname(('Darwin', 'macziade', '8.11.1', + ('Darwin Kernel Version 8.11.1: ' + 'Wed Oct 10 18:23:28 PDT 2007; ' + 'root:xnu-792.25.20~1/RELEASE_I386'), 'PowerPC')) + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3' + + get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' + '-fwrapv -O3 -Wall -Wstrict-prototypes') + + maxint = sys.maxint + try: + sys.maxint = 2147483647 + self.assertEquals(get_platform(), 'macosx-10.3-ppc') + sys.maxint = 9223372036854775807 + self.assertEquals(get_platform(), 'macosx-10.3-ppc64') + finally: + sys.maxint = maxint + + self._set_uname(('Darwin', 'macziade', '8.11.1', ('Darwin Kernel Version 8.11.1: ' 'Wed Oct 10 18:23:28 PDT 2007; ' @@ -128,7 +148,15 @@ get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' '-fwrapv -O3 -Wall -Wstrict-prototypes') - self.assertEquals(get_platform(), 'macosx-10.3-i386') + maxint = sys.maxint + try: + sys.maxint = 2147483647 + self.assertEquals(get_platform(), 'macosx-10.3-i386') + sys.maxint = 9223372036854775807 + self.assertEquals(get_platform(), 'macosx-10.3-x86_64') + finally: + sys.maxint = maxint + # macbook with fat binaries (fat, universal or fat64) os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.4' @@ -173,6 +201,7 @@ self.assertEquals(get_platform(), 'macosx-10.4-%s'%(arch,)) + # 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 Thu Dec 24 15:50:35 2009 @@ -31,6 +31,9 @@ Library ------- +- Distutils now correctly identifies the build architecture as "x86_64" + when building on OSX 10.6 without "-arch" flags. + - Issue #7556: Distutils' msvc9compiler now opens the MSVC Manifest file in text mode. From python-checkins at python.org Thu Dec 24 16:19:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 24 Dec 2009 15:19:40 -0000 Subject: [Python-checkins] r77038 - python/trunk/Lib/multiprocessing/process.py Message-ID: Author: benjamin.peterson Date: Thu Dec 24 16:19:40 2009 New Revision: 77038 Log: allow Process name to be unicode #7571 Modified: python/trunk/Lib/multiprocessing/process.py Modified: python/trunk/Lib/multiprocessing/process.py ============================================================================== --- python/trunk/Lib/multiprocessing/process.py (original) +++ python/trunk/Lib/multiprocessing/process.py Thu Dec 24 16:19:40 2009 @@ -138,7 +138,7 @@ @name.setter def name(self, name): - assert isinstance(name, str), 'name must be a string' + assert isinstance(name, basestring), 'name must be a string' self._name = name @property From python-checkins at python.org Thu Dec 24 16:21:26 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 24 Dec 2009 15:21:26 -0000 Subject: [Python-checkins] r77039 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Thu Dec 24 16:21:26 2009 New Revision: 77039 Log: Blocked revisions 77038 via svnmerge ........ r77038 | benjamin.peterson | 2009-12-24 09:19:40 -0600 (Thu, 24 Dec 2009) | 1 line allow Process name to be unicode #7571 ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Dec 24 16:21:48 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 24 Dec 2009 15:21:48 -0000 Subject: [Python-checkins] r77040 - in python/branches/release26-maint: Lib/multiprocessing/process.py Message-ID: Author: benjamin.peterson Date: Thu Dec 24 16:21:47 2009 New Revision: 77040 Log: Merged revisions 77038 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77038 | benjamin.peterson | 2009-12-24 09:19:40 -0600 (Thu, 24 Dec 2009) | 1 line allow Process name to be unicode #7571 ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/multiprocessing/process.py Modified: python/branches/release26-maint/Lib/multiprocessing/process.py ============================================================================== --- python/branches/release26-maint/Lib/multiprocessing/process.py (original) +++ python/branches/release26-maint/Lib/multiprocessing/process.py Thu Dec 24 16:21:47 2009 @@ -138,7 +138,7 @@ @name.setter def name(self, name): - assert isinstance(name, str), 'name must be a string' + assert isinstance(name, basestring), 'name must be a string' self._name = name @property From python-checkins at python.org Thu Dec 24 17:06:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 24 Dec 2009 16:06:59 -0000 Subject: [Python-checkins] r77041 - python/trunk/Lib/imaplib.py Message-ID: Author: mark.dickinson Date: Thu Dec 24 17:06:58 2009 New Revision: 77041 Log: Issue #7568: typo in docstring. Thanks Mike Putnam. Modified: python/trunk/Lib/imaplib.py Modified: python/trunk/Lib/imaplib.py ============================================================================== --- python/trunk/Lib/imaplib.py (original) +++ python/trunk/Lib/imaplib.py Thu Dec 24 17:06:58 2009 @@ -726,7 +726,7 @@ def thread(self, threading_algorithm, charset, *search_criteria): """IMAPrev1 extension THREAD command. - (type, [data]) = .thread(threading_alogrithm, charset, search_criteria, ...) + (type, [data]) = .thread(threading_algorithm, charset, search_criteria, ...) """ name = 'THREAD' typ, dat = self._simple_command(name, threading_algorithm, charset, *search_criteria) From python-checkins at python.org Thu Dec 24 17:09:31 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 24 Dec 2009 16:09:31 -0000 Subject: [Python-checkins] r77042 - in python/branches/release26-maint: Lib/imaplib.py Message-ID: Author: mark.dickinson Date: Thu Dec 24 17:09:31 2009 New Revision: 77042 Log: Merged revisions 77041 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77041 | mark.dickinson | 2009-12-24 16:06:58 +0000 (Thu, 24 Dec 2009) | 1 line Issue #7568: typo in docstring. Thanks Mike Putnam. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/imaplib.py Modified: python/branches/release26-maint/Lib/imaplib.py ============================================================================== --- python/branches/release26-maint/Lib/imaplib.py (original) +++ python/branches/release26-maint/Lib/imaplib.py Thu Dec 24 17:09:31 2009 @@ -726,7 +726,7 @@ def thread(self, threading_algorithm, charset, *search_criteria): """IMAPrev1 extension THREAD command. - (type, [data]) = .thread(threading_alogrithm, charset, search_criteria, ...) + (type, [data]) = .thread(threading_algorithm, charset, search_criteria, ...) """ name = 'THREAD' typ, dat = self._simple_command(name, threading_algorithm, charset, *search_criteria) From python-checkins at python.org Thu Dec 24 17:12:50 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 24 Dec 2009 16:12:50 -0000 Subject: [Python-checkins] r77043 - in python/branches/py3k: Lib/imaplib.py Message-ID: Author: mark.dickinson Date: Thu Dec 24 17:12:49 2009 New Revision: 77043 Log: Merged revisions 77041 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77041 | mark.dickinson | 2009-12-24 16:06:58 +0000 (Thu, 24 Dec 2009) | 1 line Issue #7568: typo in docstring. Thanks Mike Putnam. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/imaplib.py Modified: python/branches/py3k/Lib/imaplib.py ============================================================================== --- python/branches/py3k/Lib/imaplib.py (original) +++ python/branches/py3k/Lib/imaplib.py Thu Dec 24 17:12:49 2009 @@ -740,7 +740,7 @@ def thread(self, threading_algorithm, charset, *search_criteria): """IMAPrev1 extension THREAD command. - (type, [data]) = .thread(threading_alogrithm, charset, search_criteria, ...) + (type, [data]) = .thread(threading_algorithm, charset, search_criteria, ...) """ name = 'THREAD' typ, dat = self._simple_command(name, threading_algorithm, charset, *search_criteria) From python-checkins at python.org Thu Dec 24 17:15:31 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 24 Dec 2009 16:15:31 -0000 Subject: [Python-checkins] r77044 - in python/branches/release31-maint: Lib/imaplib.py Message-ID: Author: mark.dickinson Date: Thu Dec 24 17:15:31 2009 New Revision: 77044 Log: Merged revisions 77043 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77043 | mark.dickinson | 2009-12-24 16:12:49 +0000 (Thu, 24 Dec 2009) | 9 lines Merged revisions 77041 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77041 | mark.dickinson | 2009-12-24 16:06:58 +0000 (Thu, 24 Dec 2009) | 1 line Issue #7568: typo in docstring. Thanks Mike Putnam. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/imaplib.py Modified: python/branches/release31-maint/Lib/imaplib.py ============================================================================== --- python/branches/release31-maint/Lib/imaplib.py (original) +++ python/branches/release31-maint/Lib/imaplib.py Thu Dec 24 17:15:31 2009 @@ -740,7 +740,7 @@ def thread(self, threading_algorithm, charset, *search_criteria): """IMAPrev1 extension THREAD command. - (type, [data]) = .thread(threading_alogrithm, charset, search_criteria, ...) + (type, [data]) = .thread(threading_algorithm, charset, search_criteria, ...) """ name = 'THREAD' typ, dat = self._simple_command(name, threading_algorithm, charset, *search_criteria) From python-checkins at python.org Thu Dec 24 23:25:17 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 24 Dec 2009 22:25:17 -0000 Subject: [Python-checkins] r77045 - in python/trunk: Lib/test/test_exceptions.py Misc/NEWS Objects/exceptions.c Message-ID: Author: ezio.melotti Date: Thu Dec 24 23:25:17 2009 New Revision: 77045 Log: #6108: unicode(exception) and str(exception) should return the same message Modified: python/trunk/Lib/test/test_exceptions.py python/trunk/Misc/NEWS python/trunk/Objects/exceptions.c Modified: python/trunk/Lib/test/test_exceptions.py ============================================================================== --- python/trunk/Lib/test/test_exceptions.py (original) +++ python/trunk/Lib/test/test_exceptions.py Thu Dec 24 23:25:17 2009 @@ -430,8 +430,116 @@ self.assertTrue("maximum recursion depth exceeded" in str(v), v) + +# Helper class used by TestSameStrAndUnicodeMsg +class ExcWithOverriddenStr(Exception): + """Subclass of Exception that accepts a keyword 'msg' arg that is + returned by __str__. 'msg' won't be included in self.args""" + def __init__(self, *args, **kwargs): + self.msg = kwargs.pop('msg') # msg should always be present + super(ExcWithOverriddenStr, self).__init__(*args, **kwargs) + def __str__(self): + return self.msg + + +class TestSameStrAndUnicodeMsg(unittest.TestCase): + """unicode(err) should return the same message of str(err). See #6108""" + + def check_same_msg(self, exc, msg): + """Helper function that checks if str(exc) == unicode(exc) == msg""" + self.assertEqual(str(exc), msg) + self.assertEqual(str(exc), unicode(exc)) + + def test_builtin_exceptions(self): + """Check same msg for built-in exceptions""" + # These exceptions implement a __str__ method that uses the args + # to create a better error message. unicode(e) should return the same + # message. + exceptions = [ + SyntaxError('invalid syntax', ('', 1, 3, '2+*3')), + IOError(2, 'No such file or directory'), + KeyError('both should have the same quotes'), + UnicodeDecodeError('ascii', '\xc3\xa0', 0, 1, + 'ordinal not in range(128)'), + UnicodeEncodeError('ascii', u'\u1234', 0, 1, + 'ordinal not in range(128)') + ] + for exception in exceptions: + self.assertEqual(str(exception), unicode(exception)) + + def test_0_args(self): + """Check same msg for Exception with 0 args""" + # str() and unicode() on an Exception with no args should return an + # empty string + self.check_same_msg(Exception(), '') + + def test_0_args_with_overridden___str__(self): + """Check same msg for exceptions with 0 args and overridden __str__""" + # str() and unicode() on an exception with overridden __str__ that + # returns an ascii-only string should return the same string + for msg in ('foo', u'foo'): + self.check_same_msg(ExcWithOverriddenStr(msg=msg), msg) + + # if __str__ returns a non-ascii unicode string str() should fail + # but unicode() should return the unicode string + e = ExcWithOverriddenStr(msg=u'f\xf6\xf6') # no args + self.assertRaises(UnicodeEncodeError, str, e) + self.assertEqual(unicode(e), u'f\xf6\xf6') + + def test_1_arg(self): + """Check same msg for Exceptions with 1 arg""" + for arg in ('foo', u'foo'): + self.check_same_msg(Exception(arg), arg) + + # if __str__ is not overridden and self.args[0] is a non-ascii unicode + # string, str() should try to return str(self.args[0]) and fail. + # unicode() should return unicode(self.args[0]) and succeed. + e = Exception(u'f\xf6\xf6') + self.assertRaises(UnicodeEncodeError, str, e) + self.assertEqual(unicode(e), u'f\xf6\xf6') + + def test_1_arg_with_overridden___str__(self): + """Check same msg for exceptions with overridden __str__ and 1 arg""" + # when __str__ is overridden and __unicode__ is not implemented + # unicode(e) returns the same as unicode(e.__str__()). + for msg in ('foo', u'foo'): + self.check_same_msg(ExcWithOverriddenStr('arg', msg=msg), msg) + + # if __str__ returns a non-ascii unicode string, str() should fail + # but unicode() should succeed. + e = ExcWithOverriddenStr('arg', msg=u'f\xf6\xf6') # 1 arg + self.assertRaises(UnicodeEncodeError, str, e) + self.assertEqual(unicode(e), u'f\xf6\xf6') + + def test_many_args(self): + """Check same msg for Exceptions with many args""" + argslist = [ + (3, 'foo'), + (1, u'foo', 'bar'), + (4, u'f\xf6\xf6', u'bar', 'baz') + ] + # both str() and unicode() should return a repr() of the args + for args in argslist: + self.check_same_msg(Exception(*args), repr(args)) + + def test_many_args_with_overridden___str__(self): + """Check same msg for exceptions with overridden __str__ and many args""" + # if __str__ returns an ascii string / ascii unicode string + # both str() and unicode() should succeed + for msg in ('foo', u'foo'): + e = ExcWithOverriddenStr('arg1', u'arg2', u'f\xf6\xf6', msg=msg) + self.check_same_msg(e, msg) + + # if __str__ returns a non-ascii unicode string, str() should fail + # but unicode() should succeed + e = ExcWithOverriddenStr('arg1', u'f\xf6\xf6', u'arg3', # 3 args + msg=u'f\xf6\xf6') + self.assertRaises(UnicodeEncodeError, str, e) + self.assertEqual(unicode(e), u'f\xf6\xf6') + + def test_main(): - run_unittest(ExceptionTests) + run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg) if __name__ == '__main__': test_main() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Dec 24 23:25:17 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #6108: unicode(exception) and str(exception) should return the same + message when only __str__ (and not __unicode__) is overridden in the subclass. + - Issue #6834: replace the implementation for the 'python' and 'pythonw' executables on OSX. Modified: python/trunk/Objects/exceptions.c ============================================================================== --- python/trunk/Objects/exceptions.c (original) +++ python/trunk/Objects/exceptions.c Thu Dec 24 23:25:17 2009 @@ -122,6 +122,21 @@ { PyObject *out; + /* issue6108: if __str__ has been overridden in the subclass, unicode() + should return the message returned by __str__ as used to happen + before this method was implemented. */ + if (Py_TYPE(self)->tp_str != (reprfunc)BaseException_str) { + PyObject *str; + /* Unlike PyObject_Str, tp_str can return unicode (i.e. return the + equivalent of unicode(e.__str__()) instead of unicode(str(e))). */ + str = Py_TYPE(self)->tp_str((PyObject*)self); + if (str == NULL) + return NULL; + out = PyObject_Unicode(str); + Py_DECREF(str); + return out; + } + switch (PyTuple_GET_SIZE(self->args)) { case 0: out = PyUnicode_FromString(""); From python-checkins at python.org Thu Dec 24 23:32:25 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 24 Dec 2009 22:32:25 -0000 Subject: [Python-checkins] r77046 - in python/branches/release26-maint: Lib/test/test_exceptions.py Misc/NEWS Objects/exceptions.c Message-ID: Author: ezio.melotti Date: Thu Dec 24 23:32:25 2009 New Revision: 77046 Log: Merged revisions 77045 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77045 | ezio.melotti | 2009-12-25 00:25:17 +0200 (Fri, 25 Dec 2009) | 1 line #6108: unicode(exception) and str(exception) should return the same message ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_exceptions.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/exceptions.c Modified: python/branches/release26-maint/Lib/test/test_exceptions.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_exceptions.py (original) +++ python/branches/release26-maint/Lib/test/test_exceptions.py Thu Dec 24 23:32:25 2009 @@ -429,8 +429,116 @@ self.assert_("maximum recursion depth exceeded" in str(v), v) + +# Helper class used by TestSameStrAndUnicodeMsg +class ExcWithOverriddenStr(Exception): + """Subclass of Exception that accepts a keyword 'msg' arg that is + returned by __str__. 'msg' won't be included in self.args""" + def __init__(self, *args, **kwargs): + self.msg = kwargs.pop('msg') # msg should always be present + super(ExcWithOverriddenStr, self).__init__(*args, **kwargs) + def __str__(self): + return self.msg + + +class TestSameStrAndUnicodeMsg(unittest.TestCase): + """unicode(err) should return the same message of str(err). See #6108""" + + def check_same_msg(self, exc, msg): + """Helper function that checks if str(exc) == unicode(exc) == msg""" + self.assertEqual(str(exc), msg) + self.assertEqual(str(exc), unicode(exc)) + + def test_builtin_exceptions(self): + """Check same msg for built-in exceptions""" + # These exceptions implement a __str__ method that uses the args + # to create a better error message. unicode(e) should return the same + # message. + exceptions = [ + SyntaxError('invalid syntax', ('', 1, 3, '2+*3')), + IOError(2, 'No such file or directory'), + KeyError('both should have the same quotes'), + UnicodeDecodeError('ascii', '\xc3\xa0', 0, 1, + 'ordinal not in range(128)'), + UnicodeEncodeError('ascii', u'\u1234', 0, 1, + 'ordinal not in range(128)') + ] + for exception in exceptions: + self.assertEqual(str(exception), unicode(exception)) + + def test_0_args(self): + """Check same msg for Exception with 0 args""" + # str() and unicode() on an Exception with no args should return an + # empty string + self.check_same_msg(Exception(), '') + + def test_0_args_with_overridden___str__(self): + """Check same msg for exceptions with 0 args and overridden __str__""" + # str() and unicode() on an exception with overridden __str__ that + # returns an ascii-only string should return the same string + for msg in ('foo', u'foo'): + self.check_same_msg(ExcWithOverriddenStr(msg=msg), msg) + + # if __str__ returns a non-ascii unicode string str() should fail + # but unicode() should return the unicode string + e = ExcWithOverriddenStr(msg=u'f\xf6\xf6') # no args + self.assertRaises(UnicodeEncodeError, str, e) + self.assertEqual(unicode(e), u'f\xf6\xf6') + + def test_1_arg(self): + """Check same msg for Exceptions with 1 arg""" + for arg in ('foo', u'foo'): + self.check_same_msg(Exception(arg), arg) + + # if __str__ is not overridden and self.args[0] is a non-ascii unicode + # string, str() should try to return str(self.args[0]) and fail. + # unicode() should return unicode(self.args[0]) and succeed. + e = Exception(u'f\xf6\xf6') + self.assertRaises(UnicodeEncodeError, str, e) + self.assertEqual(unicode(e), u'f\xf6\xf6') + + def test_1_arg_with_overridden___str__(self): + """Check same msg for exceptions with overridden __str__ and 1 arg""" + # when __str__ is overridden and __unicode__ is not implemented + # unicode(e) returns the same as unicode(e.__str__()). + for msg in ('foo', u'foo'): + self.check_same_msg(ExcWithOverriddenStr('arg', msg=msg), msg) + + # if __str__ returns a non-ascii unicode string, str() should fail + # but unicode() should succeed. + e = ExcWithOverriddenStr('arg', msg=u'f\xf6\xf6') # 1 arg + self.assertRaises(UnicodeEncodeError, str, e) + self.assertEqual(unicode(e), u'f\xf6\xf6') + + def test_many_args(self): + """Check same msg for Exceptions with many args""" + argslist = [ + (3, 'foo'), + (1, u'foo', 'bar'), + (4, u'f\xf6\xf6', u'bar', 'baz') + ] + # both str() and unicode() should return a repr() of the args + for args in argslist: + self.check_same_msg(Exception(*args), repr(args)) + + def test_many_args_with_overridden___str__(self): + """Check same msg for exceptions with overridden __str__ and many args""" + # if __str__ returns an ascii string / ascii unicode string + # both str() and unicode() should succeed + for msg in ('foo', u'foo'): + e = ExcWithOverriddenStr('arg1', u'arg2', u'f\xf6\xf6', msg=msg) + self.check_same_msg(e, msg) + + # if __str__ returns a non-ascii unicode string, str() should fail + # but unicode() should succeed + e = ExcWithOverriddenStr('arg1', u'f\xf6\xf6', u'arg3', # 3 args + msg=u'f\xf6\xf6') + self.assertRaises(UnicodeEncodeError, str, e) + self.assertEqual(unicode(e), u'f\xf6\xf6') + + def test_main(): - run_unittest(ExceptionTests) + run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg) if __name__ == '__main__': test_main() Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Dec 24 23:32:25 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #6108: unicode(exception) and str(exception) should return the same + message when only __str__ (and not __unicode__) is overridden in the subclass. + - Issue #7491: Metaclass's __cmp__ method was ignored. - Add Py3k warnings for parameter names in parenthesis. Modified: python/branches/release26-maint/Objects/exceptions.c ============================================================================== --- python/branches/release26-maint/Objects/exceptions.c (original) +++ python/branches/release26-maint/Objects/exceptions.c Thu Dec 24 23:32:25 2009 @@ -123,6 +123,21 @@ { PyObject *out; + /* issue6108: if __str__ has been overridden in the subclass, unicode() + should return the message returned by __str__ as used to happen + before this method was implemented. */ + if (Py_TYPE(self)->tp_str != (reprfunc)BaseException_str) { + PyObject *str; + /* Unlike PyObject_Str, tp_str can return unicode (i.e. return the + equivalent of unicode(e.__str__()) instead of unicode(str(e))). */ + str = Py_TYPE(self)->tp_str((PyObject*)self); + if (str == NULL) + return NULL; + out = PyObject_Unicode(str); + Py_DECREF(str); + return out; + } + switch (PyTuple_GET_SIZE(self->args)) { case 0: out = PyUnicode_FromString(""); From python-checkins at python.org Thu Dec 24 23:54:06 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 24 Dec 2009 22:54:06 -0000 Subject: [Python-checkins] r77047 - python/branches/py3k/Lib/test/test_exceptions.py Message-ID: Author: ezio.melotti Date: Thu Dec 24 23:54:06 2009 New Revision: 77047 Log: Remove test for unicode(e) converted to str(e) by 2to3 Modified: python/branches/py3k/Lib/test/test_exceptions.py Modified: python/branches/py3k/Lib/test/test_exceptions.py ============================================================================== --- python/branches/py3k/Lib/test/test_exceptions.py (original) +++ python/branches/py3k/Lib/test/test_exceptions.py Thu Dec 24 23:54:06 2009 @@ -399,13 +399,11 @@ return -1 self.assertRaises(RuntimeError, g) - def testUnicodeStrUsage(self): - # Make sure both instances and classes have a str and unicode - # representation. + def test_str(self): + # Make sure both instances and classes have a str representation. self.assertTrue(str(Exception)) - self.assertTrue(str(Exception)) - self.assertTrue(str(Exception('a'))) self.assertTrue(str(Exception('a'))) + self.assertTrue(str(Exception('a', 'b'))) def testExceptionCleanupNames(self): # Make sure the local variable bound to the exception instance by From python-checkins at python.org Thu Dec 24 23:56:20 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 24 Dec 2009 22:56:20 -0000 Subject: [Python-checkins] r77048 - in python/branches/release31-maint: Lib/test/test_exceptions.py Message-ID: Author: ezio.melotti Date: Thu Dec 24 23:56:20 2009 New Revision: 77048 Log: Merged revisions 77047 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r77047 | ezio.melotti | 2009-12-25 00:54:06 +0200 (Fri, 25 Dec 2009) | 1 line Remove test for unicode(e) converted to str(e) by 2to3 ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_exceptions.py Modified: python/branches/release31-maint/Lib/test/test_exceptions.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_exceptions.py (original) +++ python/branches/release31-maint/Lib/test/test_exceptions.py Thu Dec 24 23:56:20 2009 @@ -399,13 +399,11 @@ return -1 self.assertRaises(RuntimeError, g) - def testUnicodeStrUsage(self): - # Make sure both instances and classes have a str and unicode - # representation. + def test_str(self): + # Make sure both instances and classes have a str representation. self.assertTrue(str(Exception)) - self.assertTrue(str(Exception)) - self.assertTrue(str(Exception('a'))) self.assertTrue(str(Exception('a'))) + self.assertTrue(str(Exception('a', 'b'))) def testExceptionCleanupNames(self): # Make sure the local variable bound to the exception instance by From python-checkins at python.org Fri Dec 25 00:01:35 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 24 Dec 2009 23:01:35 -0000 Subject: [Python-checkins] r77049 - python/branches/py3k Message-ID: Author: ezio.melotti Date: Fri Dec 25 00:01:34 2009 New Revision: 77049 Log: Blocked revisions 77045 via svnmerge ........ r77045 | ezio.melotti | 2009-12-25 00:25:17 +0200 (Fri, 25 Dec 2009) | 1 line #6108: unicode(exception) and str(exception) should return the same message ........ Modified: python/branches/py3k/ (props changed) From solipsis at pitrou.net Fri Dec 25 00:48:31 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 25 Dec 2009 00:48:31 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r77043): sum=0 Message-ID: <20091224234831.606FA17759@ns6635.ovh.net> py3k results for svn r77043 (hg cset dfe5ebff9c79) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogNC5eEm', '-x', 'test_httpservers'] From python-checkins at python.org Fri Dec 25 03:12:02 2009 From: python-checkins at python.org (ezio.melotti) Date: Fri, 25 Dec 2009 02:12:02 -0000 Subject: [Python-checkins] r77050 - python/trunk/Doc/library/sys.rst Message-ID: Author: ezio.melotti Date: Fri Dec 25 03:12:01 2009 New Revision: 77050 Log: Updated sys.flags table in Doc Modified: python/trunk/Doc/library/sys.rst Modified: python/trunk/Doc/library/sys.rst ============================================================================== --- python/trunk/Doc/library/sys.rst (original) +++ python/trunk/Doc/library/sys.rst Fri Dec 25 03:12:01 2009 @@ -275,6 +275,8 @@ +------------------------------+------------------------------------------+ | :const:`dont_write_bytecode` | -B | +------------------------------+------------------------------------------+ + | :const:`no_user_site` | -s | + +------------------------------+------------------------------------------+ | :const:`no_site` | -S | +------------------------------+------------------------------------------+ | :const:`ignore_environment` | -E | @@ -285,6 +287,8 @@ +------------------------------+------------------------------------------+ | :const:`unicode` | -U | +------------------------------+------------------------------------------+ + | :const:`bytes_warning` | -b | + +------------------------------+------------------------------------------+ .. versionadded:: 2.6 From python-checkins at python.org Fri Dec 25 03:13:25 2009 From: python-checkins at python.org (ezio.melotti) Date: Fri, 25 Dec 2009 02:13:25 -0000 Subject: [Python-checkins] r77051 - in python/branches/release26-maint: Doc/library/sys.rst Message-ID: Author: ezio.melotti Date: Fri Dec 25 03:13:25 2009 New Revision: 77051 Log: Merged revisions 77050 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77050 | ezio.melotti | 2009-12-25 04:12:01 +0200 (Fri, 25 Dec 2009) | 1 line Updated sys.flags table in Doc ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/sys.rst 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 Fri Dec 25 03:13:25 2009 @@ -275,6 +275,8 @@ +------------------------------+------------------------------------------+ | :const:`dont_write_bytecode` | -B | +------------------------------+------------------------------------------+ + | :const:`no_user_site` | -s | + +------------------------------+------------------------------------------+ | :const:`no_site` | -S | +------------------------------+------------------------------------------+ | :const:`ignore_environment` | -E | @@ -285,6 +287,8 @@ +------------------------------+------------------------------------------+ | :const:`unicode` | -U | +------------------------------+------------------------------------------+ + | :const:`bytes_warning` | -b | + +------------------------------+------------------------------------------+ .. versionadded:: 2.6 From python-checkins at python.org Fri Dec 25 03:16:56 2009 From: python-checkins at python.org (ezio.melotti) Date: Fri, 25 Dec 2009 02:16:56 -0000 Subject: [Python-checkins] r77052 - in python/branches/py3k: Doc/library/sys.rst Message-ID: Author: ezio.melotti Date: Fri Dec 25 03:16:56 2009 New Revision: 77052 Log: Merged revisions 77050 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77050 | ezio.melotti | 2009-12-25 04:12:01 +0200 (Fri, 25 Dec 2009) | 1 line Updated sys.flags table in Doc ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/sys.rst Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Fri Dec 25 03:16:56 2009 @@ -199,12 +199,8 @@ +==============================+==========================================+ | :const:`debug` | -d | +------------------------------+------------------------------------------+ - | :const:`py3k_warning` | -3 | - +------------------------------+------------------------------------------+ | :const:`division_warning` | -Q | +------------------------------+------------------------------------------+ - | :const:`division_new` | -Qnew | - +------------------------------+------------------------------------------+ | :const:`inspect` | -i | +------------------------------+------------------------------------------+ | :const:`interactive` | -i | @@ -213,13 +209,15 @@ +------------------------------+------------------------------------------+ | :const:`dont_write_bytecode` | -B | +------------------------------+------------------------------------------+ + | :const:`no_user_site` | -s | + +------------------------------+------------------------------------------+ | :const:`no_site` | -S | +------------------------------+------------------------------------------+ | :const:`ignore_environment` | -E | +------------------------------+------------------------------------------+ | :const:`verbose` | -v | +------------------------------+------------------------------------------+ - | :const:`unicode` | -U | + | :const:`bytes_warning` | -b | +------------------------------+------------------------------------------+ From python-checkins at python.org Fri Dec 25 03:18:57 2009 From: python-checkins at python.org (ezio.melotti) Date: Fri, 25 Dec 2009 02:18:57 -0000 Subject: [Python-checkins] r77053 - in python/branches/release31-maint: Doc/library/sys.rst Message-ID: Author: ezio.melotti Date: Fri Dec 25 03:18:56 2009 New Revision: 77053 Log: Merged revisions 77052 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77052 | ezio.melotti | 2009-12-25 04:16:56 +0200 (Fri, 25 Dec 2009) | 9 lines Merged revisions 77050 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77050 | ezio.melotti | 2009-12-25 04:12:01 +0200 (Fri, 25 Dec 2009) | 1 line Updated sys.flags table in Doc ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/sys.rst Modified: python/branches/release31-maint/Doc/library/sys.rst ============================================================================== --- python/branches/release31-maint/Doc/library/sys.rst (original) +++ python/branches/release31-maint/Doc/library/sys.rst Fri Dec 25 03:18:56 2009 @@ -199,12 +199,8 @@ +==============================+==========================================+ | :const:`debug` | -d | +------------------------------+------------------------------------------+ - | :const:`py3k_warning` | -3 | - +------------------------------+------------------------------------------+ | :const:`division_warning` | -Q | +------------------------------+------------------------------------------+ - | :const:`division_new` | -Qnew | - +------------------------------+------------------------------------------+ | :const:`inspect` | -i | +------------------------------+------------------------------------------+ | :const:`interactive` | -i | @@ -213,13 +209,15 @@ +------------------------------+------------------------------------------+ | :const:`dont_write_bytecode` | -B | +------------------------------+------------------------------------------+ + | :const:`no_user_site` | -s | + +------------------------------+------------------------------------------+ | :const:`no_site` | -S | +------------------------------+------------------------------------------+ | :const:`ignore_environment` | -E | +------------------------------+------------------------------------------+ | :const:`verbose` | -v | +------------------------------+------------------------------------------+ - | :const:`unicode` | -U | + | :const:`bytes_warning` | -b | +------------------------------+------------------------------------------+ From python-checkins at python.org Fri Dec 25 13:27:22 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 25 Dec 2009 12:27:22 -0000 Subject: [Python-checkins] r77054 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Fri Dec 25 13:27:22 2009 New Revision: 77054 Log: various fixes/changes from python-dev feedback Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Fri Dec 25 13:27:22 2009 @@ -27,10 +27,11 @@ 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", "Requires-External", "Requires-Dist", -"Provides-Dist", and "Obsoletes-Dist". This version also updates the -"Metadata-Version" field, and adds new fields, "Maintainer", -"Maintainer-email" and "Project-URL". This new version also adds -`environment markers`. +"Provides-Dist", and "Obsoletes-Dist". This version also changes the +"Platform" field. Three new fields were also added: "Maintainer", +"Maintainer-email" and "Project-URL". + +Last, this new version also adds `environment markers`. Fields ====== @@ -47,8 +48,7 @@ Metadata-Version :::::::::::::::: -Version of the file format; "1.0", "1.1" and "1.2" are the -only legal values here. +Version of the file format; "1.2" is the only legal value. Example:: @@ -79,14 +79,14 @@ Platform (multiple use) ::::::::::::::::::::::: -A comma-separated list of platform specifications, summarizing -the operating systems supported by the package which are not -listed in the "Operating System" Trove classifiers. See -"Classifier" below. +A Platform specification describing an operating system supported by +the package which is not listed in the "Operating System" Trove classifiers. +See "Classifier" below. -Example:: +Examples:: - Platform: ObscureUnix, RareDOS + Platform: ObscureUnix + Platform: RareDOS Supported-Platform (multiple use) @@ -257,86 +257,6 @@ Classifier: Environment :: Console (Text Based) -Requires (multiple use) (deprecated) -:::::::::::::::::::::::::::::::::::: - -**This field is now deprecated in favor of "Requires-Dist"** - -Each entry contains a string describing some other module or -package required by this package. - -The format of a requirement string is identical to that of a -module or package name usable with the ``import`` statement, -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 -distutils.version.StrictVersion class: two or three -dot-separated numeric components, with an optional "pre-release" -tag on the end consisting of the letter 'a' or 'b' followed by a -number. Example version numbers are "1.0", "2.3a2", "1.3.99", - -Any number of conditional operators can be specified, e.g. -the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. - -All of the following are possible requirement strings: "rfc822", -"zlib (>=1.1.4)", "zope". - -There's no canonical list of what strings should be used; the -Python community is left to choose its own standards. - -Examples:: - - Requires: re - Requires: sys - Requires: zlib - Requires: xml.parsers.expat (>1.0) - Requires: psycopg - - -Provides (multiple use) (deprecated) -:::::::::::::::::::::::::::::::::::: - -**This field is now deprecated in favor of "Provides-Dist"** - -Each entry contains a string describing a package or module that -will be provided by this package once it is installed. These -strings should match the ones used in Requirements fields. A -version declaration may be supplied (without a comparison -operator); the package's version number will be implied if none -is specified. - -Examples:: - - Provides: xml - Provides: xml.utils - Provides: xml.utils.iso8601 - Provides: xml.dom - Provides: xmltools (1.3) - - -Obsoletes (multiple use) (deprecated) -::::::::::::::::::::::::::::::::::::: - -**This field is now deprecated in favor of "Obsoletes-Dist"** - -Each entry contains a string describing a package or module -that 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 package name -changes, e.g. Gorgon 2.3 gets subsumed into Torqued Python 1.0. -When you install Torqued Python, the Gorgon package should be -removed. - -Example:: - - Obsoletes: Gorgon - - Requires-Dist (multiple use) :::::::::::::::::::::::::::: @@ -477,19 +397,6 @@ Requires-External: libpng (>=1.5) -Copyright -::::::::: - -Indicates the party or parties, and the year of copyright -covering the package. - -Examples:: - - Copyright: Guido van Rossum, 1991 - Copyright: Python Software Foundation, 2005 - Copyright: Public Domain - - Project-URL (multiple-use) :::::::::::::::::::::::::: From python-checkins at python.org Fri Dec 25 13:29:17 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 25 Dec 2009 12:29:17 -0000 Subject: [Python-checkins] r77055 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Fri Dec 25 13:29:16 2009 New Revision: 77055 Log: added Platform in the difference summary Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Fri Dec 25 13:29:16 2009 @@ -481,6 +481,10 @@ * Added the environment markers. +* Changed fields: + +- Platform + * Added fields: - Maintainer From python-checkins at python.org Fri Dec 25 14:29:11 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 25 Dec 2009 13:29:11 -0000 Subject: [Python-checkins] r77056 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Fri Dec 25 14:29:11 2009 New Revision: 77056 Log: added the encoding of reStructuredText Description - using a RFC822-compatible folding/unfolding technique Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Fri Dec 25 14:29:11 2009 @@ -127,12 +127,25 @@ field as-is. This means that authors should be conservative in the markup they use. +To support empty lines and lines with indentation with respect to +the RFC 822 format, any new line has to be suffixed by 7 spaces +followed by a pipe (`|`) char. As a result, the Description field is +encoded into a folded field that can be interpreted by RFC822 +parser [2]_. + Example:: - Description: This module collects votes from beagles - in order to determine their electoral wishes. - Do *not* try to use this module with basset hounds; - it makes them grumpy. + Description: This project provides powerful math functions + |For example, you can use `sum()` to sum numbers: + | + |Example:: + | + | >>> sum(1, 2) + | 3 + | + +This encoding implies that any occurences of ``\n |`` have to be replaced +by ``\n`` when the field is unfolded using a RFC822 reader. Keywords (optional) @@ -517,7 +530,8 @@ .. _`PEP 386`: http://www.python.org/dev/peps/pep-0386 - +.. [2] RFC 822 Long Header Fields: + http://www.freesoft.org/CIE/RFC/822/7.htm Copyright ========= From solipsis at pitrou.net Sat Dec 26 00:47:16 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 26 Dec 2009 00:47:16 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r77052): sum=0 Message-ID: <20091225234716.34DA617759@ns6635.ovh.net> py3k results for svn r77052 (hg cset 322795b97f60) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogB0NgSe', '-x', 'test_httpservers'] From python-checkins at python.org Sat Dec 26 14:16:15 2009 From: python-checkins at python.org (ronald.oussoren) Date: Sat, 26 Dec 2009 13:16:15 -0000 Subject: [Python-checkins] r77057 - python/branches/py3k/Lib/distutils/tests/test_util.py Message-ID: Author: ronald.oussoren Date: Sat Dec 26 14:16:15 2009 New Revision: 77057 Log: Fix merge issue where I forgot to replace sys.maxint by sys.maxsize. Modified: 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 Sat Dec 26 14:16:15 2009 @@ -119,6 +119,26 @@ sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) ' '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]') sys.platform = 'darwin' + + self._set_uname(('Darwin', 'macziade', '8.11.1', + ('Darwin Kernel Version 8.11.1: ' + 'Wed Oct 10 18:23:28 PDT 2007; ' + 'root:xnu-792.25.20~1/RELEASE_I386'), 'PowerPC')) + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3' + + get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' + '-fwrapv -O3 -Wall -Wstrict-prototypes') + + maxsize = sys.maxsize + try: + sys.maxsize = 2147483647 + self.assertEquals(get_platform(), 'macosx-10.3-ppc') + sys.maxsize = 9223372036854775807 + self.assertEquals(get_platform(), 'macosx-10.3-ppc64') + finally: + sys.maxsize = maxsize + + self._set_uname(('Darwin', 'macziade', '8.11.1', ('Darwin Kernel Version 8.11.1: ' 'Wed Oct 10 18:23:28 PDT 2007; ' @@ -128,7 +148,15 @@ get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' '-fwrapv -O3 -Wall -Wstrict-prototypes') - self.assertEquals(get_platform(), 'macosx-10.3-i386') + maxsize = sys.maxsize + try: + sys.maxsize = 2147483647 + self.assertEquals(get_platform(), 'macosx-10.3-i386') + sys.maxsize = 9223372036854775807 + self.assertEquals(get_platform(), 'macosx-10.3-x86_64') + finally: + sys.maxsize = maxsize + # macbook with fat binaries (fat, universal or fat64) os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.4' @@ -173,6 +201,7 @@ self.assertEquals(get_platform(), 'macosx-10.4-%s'%(arch,)) + # linux debian sarge os.name = 'posix' sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) ' From solipsis at pitrou.net Sun Dec 27 00:49:27 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 27 Dec 2009 00:49:27 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r77057): sum=0 Message-ID: <20091226234927.1AEBD17759@ns6635.ovh.net> py3k results for svn r77057 (hg cset 6d053bdb7efa) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogaUbEIN', '-x', 'test_httpservers'] From python-checkins at python.org Sun Dec 27 10:11:10 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 27 Dec 2009 09:11:10 -0000 Subject: [Python-checkins] r77058 - python/trunk/Lib/urllib2.py Message-ID: Author: senthil.kumaran Date: Sun Dec 27 10:11:09 2009 New Revision: 77058 Log: Fix for issue5625 - test_urllib2 fails - urlopen error file not on local host. This is on hosts with multiple ip addresses. Modified: python/trunk/Lib/urllib2.py Modified: python/trunk/Lib/urllib2.py ============================================================================== --- python/trunk/Lib/urllib2.py (original) +++ python/trunk/Lib/urllib2.py Sun Dec 27 10:11:09 2009 @@ -1264,8 +1264,9 @@ def get_names(self): if FileHandler.names is None: try: - FileHandler.names = (socket.gethostbyname('localhost'), - socket.gethostbyname(socket.gethostname())) + FileHandler.names = tuple( + socket.gethostbyname_ex('localhost')[2] + + socket.gethostbyname_ex(socket.gethostname())[2]) except socket.gaierror: FileHandler.names = (socket.gethostbyname('localhost'),) return FileHandler.names From python-checkins at python.org Sun Dec 27 10:16:31 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 27 Dec 2009 09:16:31 -0000 Subject: [Python-checkins] r77059 - in python/branches/release26-maint: Lib/urllib2.py Message-ID: Author: senthil.kumaran Date: Sun Dec 27 10:16:30 2009 New Revision: 77059 Log: Merged revisions 77058 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77058 | senthil.kumaran | 2009-12-27 14:41:09 +0530 (Sun, 27 Dec 2009) | 4 lines Fix for issue5625 - test_urllib2 fails - urlopen error file not on local host. This is on hosts with multiple ip addresses. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/urllib2.py Modified: python/branches/release26-maint/Lib/urllib2.py ============================================================================== --- python/branches/release26-maint/Lib/urllib2.py (original) +++ python/branches/release26-maint/Lib/urllib2.py Sun Dec 27 10:16:30 2009 @@ -1261,8 +1261,9 @@ def get_names(self): if FileHandler.names is None: try: - FileHandler.names = (socket.gethostbyname('localhost'), - socket.gethostbyname(socket.gethostname())) + FileHandler.names = tuple( + socket.gethostbyname_ex('localhost')[2] + + socket.gethostbyname_ex(socket.gethostname())[2]) except socket.gaierror: FileHandler.names = (socket.gethostbyname('localhost'),) return FileHandler.names From python-checkins at python.org Sun Dec 27 11:13:40 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 27 Dec 2009 10:13:40 -0000 Subject: [Python-checkins] r77060 - in python/branches/py3k: Lib/urllib/request.py Message-ID: Author: senthil.kumaran Date: Sun Dec 27 11:13:39 2009 New Revision: 77060 Log: Merged revisions 77058 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77058 | senthil.kumaran | 2009-12-27 14:41:09 +0530 (Sun, 27 Dec 2009) | 4 lines Fix for issue5625 - test_urllib2 fails - urlopen error file not on local host. This is on hosts with multiple ip addresses. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/urllib/request.py Modified: python/branches/py3k/Lib/urllib/request.py ============================================================================== --- python/branches/py3k/Lib/urllib/request.py (original) +++ python/branches/py3k/Lib/urllib/request.py Sun Dec 27 11:13:39 2009 @@ -1190,8 +1190,9 @@ def get_names(self): if FileHandler.names is None: try: - FileHandler.names = (socket.gethostbyname('localhost'), - socket.gethostbyname(socket.gethostname())) + FileHandler.names = tuple( + socket.gethostbyname_ex('localhost')[2] + + socket.gethostbyname_ex(socket.gethostname())[2]) except socket.gaierror: FileHandler.names = (socket.gethostbyname('localhost'),) return FileHandler.names @@ -1688,7 +1689,7 @@ return addinfourl(open(localname, 'rb'), headers, urlfile) host, port = splitport(host) if (not port - and socket.gethostbyname(host) in (localhost(), thishost())): + and socket.gethostbyname(host) in (localhost() + thishost())): urlfile = file if file[:1] == '/': urlfile = 'file://' + file @@ -1998,10 +1999,10 @@ _thishost = None def thishost(): - """Return the IP address of the current host.""" + """Return the IP addresses of the current host.""" global _thishost if _thishost is None: - _thishost = socket.gethostbyname(socket.gethostname()) + _thishost = tuple(socket.gethostbyname_ex(socket.gethostname()[2])) return _thishost _ftperrors = None From python-checkins at python.org Sun Dec 27 11:15:45 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 27 Dec 2009 10:15:45 -0000 Subject: [Python-checkins] r77061 - in python/branches/release31-maint: Lib/urllib/request.py Message-ID: Author: senthil.kumaran Date: Sun Dec 27 11:15:45 2009 New Revision: 77061 Log: Merged revisions 77060 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77060 | senthil.kumaran | 2009-12-27 15:43:39 +0530 (Sun, 27 Dec 2009) | 10 lines Merged revisions 77058 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77058 | senthil.kumaran | 2009-12-27 14:41:09 +0530 (Sun, 27 Dec 2009) | 4 lines Fix for issue5625 - test_urllib2 fails - urlopen error file not on local host. This is on hosts with multiple ip addresses. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/urllib/request.py Modified: python/branches/release31-maint/Lib/urllib/request.py ============================================================================== --- python/branches/release31-maint/Lib/urllib/request.py (original) +++ python/branches/release31-maint/Lib/urllib/request.py Sun Dec 27 11:15:45 2009 @@ -1190,8 +1190,9 @@ def get_names(self): if FileHandler.names is None: try: - FileHandler.names = (socket.gethostbyname('localhost'), - socket.gethostbyname(socket.gethostname())) + FileHandler.names = tuple( + socket.gethostbyname_ex('localhost')[2] + + socket.gethostbyname_ex(socket.gethostname())[2]) except socket.gaierror: FileHandler.names = (socket.gethostbyname('localhost'),) return FileHandler.names @@ -1690,7 +1691,7 @@ return addinfourl(open(localname, 'rb'), headers, urlfile) host, port = splitport(host) if (not port - and socket.gethostbyname(host) in (localhost(), thishost())): + and socket.gethostbyname(host) in (localhost() + thishost())): urlfile = file if file[:1] == '/': urlfile = 'file://' + file @@ -2000,10 +2001,10 @@ _thishost = None def thishost(): - """Return the IP address of the current host.""" + """Return the IP addresses of the current host.""" global _thishost if _thishost is None: - _thishost = socket.gethostbyname(socket.gethostname()) + _thishost = tuple(socket.gethostbyname_ex(socket.gethostname()[2])) return _thishost _ftperrors = None From python-checkins at python.org Sun Dec 27 15:55:57 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 14:55:57 -0000 Subject: [Python-checkins] r77062 - in python/trunk: Lib/test/test_long_future.py Misc/NEWS Objects/intobject.c Objects/longobject.c Message-ID: Author: mark.dickinson Date: Sun Dec 27 15:55:57 2009 New Revision: 77062 Log: Issue #1811: Improve accuracy and consistency of true division for integers. Modified: python/trunk/Lib/test/test_long_future.py python/trunk/Misc/NEWS python/trunk/Objects/intobject.c python/trunk/Objects/longobject.c Modified: python/trunk/Lib/test/test_long_future.py ============================================================================== --- python/trunk/Lib/test/test_long_future.py (original) +++ python/trunk/Lib/test/test_long_future.py Sun Dec 27 15:55:57 2009 @@ -3,9 +3,52 @@ # test_long.py instead. In the meantime, it's too obscure to try to # trick just part of test_long into using future division. +import sys +import random import unittest from test.test_support import run_unittest +# decorator for skipping tests on non-IEEE 754 platforms +requires_IEEE_754 = unittest.skipUnless( + float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + +DBL_MAX = sys.float_info.max +DBL_MAX_EXP = sys.float_info.max_exp +DBL_MIN_EXP = sys.float_info.min_exp +DBL_MANT_DIG = sys.float_info.mant_dig +DBL_MIN_OVERFLOW = 2**DBL_MAX_EXP - 2**(DBL_MAX_EXP - DBL_MANT_DIG - 1) + +# pure Python version of correctly-rounded true division +def truediv(a, b): + """Correctly-rounded true division for integers.""" + negative = a^b < 0 + a, b = abs(a), abs(b) + + # exceptions: division by zero, overflow + if not b: + raise ZeroDivisionError("division by zero") + if a >= DBL_MIN_OVERFLOW * b: + raise OverflowError("int/int too large to represent as a float") + + # find integer d satisfying 2**(d - 1) <= a/b < 2**d + d = a.bit_length() - b.bit_length() + if d >= 0 and a >= 2**d * b or d < 0 and a * 2**-d >= b: + d += 1 + + # compute 2**-exp * a / b for suitable exp + exp = max(d, DBL_MIN_EXP) - DBL_MANT_DIG + a, b = a << max(-exp, 0), b << max(exp, 0) + q, r = divmod(a, b) + + # round-half-to-even: fractional part is r/b, which is > 0.5 iff + # 2*r > b, and == 0.5 iff 2*r == b. + if 2*r > b or 2*r == b and q % 2 == 1: + q += 1 + + result = float(q) * 2.**exp + return -result if negative else result + class TrueDivisionTests(unittest.TestCase): def test(self): huge = 1L << 40000 @@ -45,6 +88,131 @@ with self.assertRaises(ZeroDivisionError): eval(zero, namespace) + def check_truediv(self, a, b, skip_small=True): + """Verify that the result of a/b is correctly rounded, by + comparing it with a pure Python implementation of correctly + rounded division. b should be nonzero.""" + + a, b = long(a), long(b) + + # skip check for small a and b: in this case, the current + # implementation converts the arguments to float directly and + # then applies a float division. This can give doubly-rounded + # results on x87-using machines (particularly 32-bit Linux). + if skip_small and max(abs(a), abs(b)) < 2**DBL_MANT_DIG: + return + + try: + # use repr so that we can distinguish between -0.0 and 0.0 + expected = repr(truediv(a, b)) + except OverflowError: + expected = 'overflow' + except ZeroDivisionError: + expected = 'zerodivision' + + try: + got = repr(a / b) + except OverflowError: + got = 'overflow' + except ZeroDivisionError: + got = 'zerodivision' + + if expected != got: + self.fail("Incorrectly rounded division {}/{}: expected {!r}, " + "got {!r}.".format(a, b, expected, got)) + + @requires_IEEE_754 + def test_correctly_rounded_true_division(self): + # more stringent tests than those above, checking that the + # result of true division of ints is always correctly rounded. + # This test should probably be considered CPython-specific. + + # Exercise all the code paths not involving Gb-sized ints. + # ... divisions involving zero + self.check_truediv(123, 0) + self.check_truediv(-456, 0) + self.check_truediv(0, 3) + self.check_truediv(0, -3) + self.check_truediv(0, 0) + # ... overflow or underflow by large margin + self.check_truediv(671 * 12345 * 2**DBL_MAX_EXP, 12345) + self.check_truediv(12345, 345678 * 2**(DBL_MANT_DIG - DBL_MIN_EXP)) + # ... a much larger or smaller than b + self.check_truediv(12345*2**100, 98765) + self.check_truediv(12345*2**30, 98765*7**81) + # ... a / b near a boundary: one of 1, 2**DBL_MANT_DIG, 2**DBL_MIN_EXP, + # 2**DBL_MAX_EXP, 2**(DBL_MIN_EXP-DBL_MANT_DIG) + bases = (0, DBL_MANT_DIG, DBL_MIN_EXP, + DBL_MAX_EXP, DBL_MIN_EXP - DBL_MANT_DIG) + for base in bases: + for exp in range(base - 15, base + 15): + self.check_truediv(75312*2**max(exp, 0), 69187*2**max(-exp, 0)) + self.check_truediv(69187*2**max(exp, 0), 75312*2**max(-exp, 0)) + + # overflow corner case + for m in [1, 2, 7, 17, 12345, 7**100, + -1, -2, -5, -23, -67891, -41**50]: + for n in range(-10, 10): + self.check_truediv(m*DBL_MIN_OVERFLOW + n, m) + self.check_truediv(m*DBL_MIN_OVERFLOW + n, -m) + + # check detection of inexactness in shifting stage + for n in range(250): + # (2**DBL_MANT_DIG+1)/(2**DBL_MANT_DIG) lies halfway + # between two representable floats, and would usually be + # rounded down under round-half-to-even. The tiniest of + # additions to the numerator should cause it to be rounded + # up instead. + self.check_truediv((2**DBL_MANT_DIG + 1)*12345*2**200 + 2**n, + 2**DBL_MANT_DIG*12345) + + # 1/2731 is one of the smallest division cases that's subject + # to double rounding on IEEE 754 machines working internally with + # 64-bit precision. On such machines, the next check would fail, + # were it not explicitly skipped in check_truediv. + self.check_truediv(1, 2731) + + # a particularly bad case for the old algorithm: gives an + # error of close to 3.5 ulps. + self.check_truediv(295147931372582273023, 295147932265116303360) + for i in range(1000): + self.check_truediv(10**(i+1), 10**i) + self.check_truediv(10**i, 10**(i+1)) + + # test round-half-to-even behaviour, normal result + for m in [1, 2, 4, 7, 8, 16, 17, 32, 12345, 7**100, + -1, -2, -5, -23, -67891, -41**50]: + for n in range(-10, 10): + self.check_truediv(2**DBL_MANT_DIG*m + n, m) + + # test round-half-to-even, subnormal result + for n in range(-20, 20): + self.check_truediv(n, 2**1076) + + # largeish random divisions: a/b where |a| <= |b| <= + # 2*|a|; |ans| is between 0.5 and 1.0, so error should + # always be bounded by 2**-54 with equality possible only + # if the least significant bit of q=ans*2**53 is zero. + for M in [10**10, 10**100, 10**1000]: + for i in range(1000): + a = random.randrange(1, M) + b = random.randrange(a, 2*a+1) + self.check_truediv(a, b) + self.check_truediv(-a, b) + self.check_truediv(a, -b) + self.check_truediv(-a, -b) + + # and some (genuinely) random tests + for _ in range(10000): + a_bits = random.randrange(1000) + b_bits = random.randrange(1, 1000) + x = random.randrange(2**a_bits) + y = random.randrange(1, 2**b_bits) + self.check_truediv(x, y) + self.check_truediv(x, -y) + self.check_truediv(-x, y) + self.check_truediv(-x, -y) + def test_main(): run_unittest(TrueDivisionTests) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Dec 27 15:55:57 2009 @@ -12,6 +12,11 @@ Core and Builtins ----------------- +- Issue #1811: improve accuracy and cross-platform consistency for + true division of integers: the result of a/b is now correctly + rounded for ints a and b (at least on IEEE 754 platforms), and in + particular does not depend on the internal representation of a long. + - Issue #6108: unicode(exception) and str(exception) should return the same message when only __str__ (and not __unicode__) is overridden in the subclass. Modified: python/trunk/Objects/intobject.c ============================================================================== --- python/trunk/Objects/intobject.c (original) +++ python/trunk/Objects/intobject.c Sun Dec 27 15:55:57 2009 @@ -645,16 +645,35 @@ } static PyObject * -int_true_divide(PyObject *v, PyObject *w) +int_true_divide(PyIntObject *x, PyIntObject *y) { + long xi, yi; /* If they aren't both ints, give someone else a chance. In particular, this lets int/long get handled by longs, which underflows to 0 gracefully if the long is too big to convert to float. */ - if (PyInt_Check(v) && PyInt_Check(w)) - return PyFloat_Type.tp_as_number->nb_true_divide(v, w); - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + CONVERT_TO_LONG(x, xi); + CONVERT_TO_LONG(y, yi); + if (yi == 0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "division by zero"); + return NULL; + } + if (xi == 0) + return PyFloat_FromDouble(yi < 0 ? -0.0 : 0.0); + +#define WIDTH_OF_ULONG (CHAR_BIT*SIZEOF_LONG) +#if DBL_MANT_DIG < WIDTH_OF_ULONG + if ((xi >= 0 ? 0UL + xi : 0UL - xi) >> DBL_MANT_DIG || + (yi >= 0 ? 0UL + yi : 0UL - yi) >> DBL_MANT_DIG) + /* Large x or y. Use long integer arithmetic. */ + return PyLong_Type.tp_as_number->nb_true_divide( + (PyObject *)x, (PyObject *)y); + else +#endif + /* Both ints can be exactly represented as doubles. Do a + floating-point division. */ + return PyFloat_FromDouble((double)xi / (double)yi); } static PyObject * @@ -1355,7 +1374,7 @@ 0, /*nb_inplace_xor*/ 0, /*nb_inplace_or*/ (binaryfunc)int_div, /* nb_floor_divide */ - int_true_divide, /* nb_true_divide */ + (binaryfunc)int_true_divide, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ (unaryfunc)int_int, /* nb_index */ Modified: python/trunk/Objects/longobject.c ============================================================================== --- python/trunk/Objects/longobject.c (original) +++ python/trunk/Objects/longobject.c Sun Dec 27 15:55:57 2009 @@ -3037,50 +3037,271 @@ return (PyObject *)div; } +/* PyLong/PyLong -> float, with correctly rounded result. */ + +#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT) +#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT) + static PyObject * long_true_divide(PyObject *v, PyObject *w) { - PyLongObject *a, *b; - double ad, bd; - int failed, aexp = -1, bexp = -1; + PyLongObject *a, *b, *x; + Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits; + digit mask, low; + int inexact, negate, a_is_small, b_is_small; + double dx, result; CONVERT_BINOP(v, w, &a, &b); - ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp); - bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp); - failed = (ad == -1.0 || bd == -1.0) && PyErr_Occurred(); - Py_DECREF(a); - Py_DECREF(b); - if (failed) - return NULL; - /* 'aexp' and 'bexp' were initialized to -1 to silence gcc-4.0.x, - but should really be set correctly after sucessful calls to - _PyLong_AsScaledDouble() */ - assert(aexp >= 0 && bexp >= 0); - if (bd == 0.0) { + /* + Method in a nutshell: + + 0. reduce to case a, b > 0; filter out obvious underflow/overflow + 1. choose a suitable integer 'shift' + 2. use integer arithmetic to compute x = floor(2**-shift*a/b) + 3. adjust x for correct rounding + 4. convert x to a double dx with the same value + 5. return ldexp(dx, shift). + + In more detail: + + 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b + returns either 0.0 or -0.0, depending on the sign of b. For a and + b both nonzero, ignore signs of a and b, and add the sign back in + at the end. Now write a_bits and b_bits for the bit lengths of a + and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise + for b). Then + + 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1). + + So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and + so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP - + DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of + the way, we can assume that + + DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP. + + 1. The integer 'shift' is chosen so that x has the right number of + bits for a double, plus two or three extra bits that will be used + in the rounding decisions. Writing a_bits and b_bits for the + number of significant bits in a and b respectively, a + straightforward formula for shift is: + + shift = a_bits - b_bits - DBL_MANT_DIG - 2 + + This is fine in the usual case, but if a/b is smaller than the + smallest normal float then it can lead to double rounding on an + IEEE 754 platform, giving incorrectly rounded results. So we + adjust the formula slightly. The actual formula used is: + + shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2 + + 2. The quantity x is computed by first shifting a (left -shift bits + if shift <= 0, right shift bits if shift > 0) and then dividing by + b. For both the shift and the division, we keep track of whether + the result is inexact, in a flag 'inexact'; this information is + needed at the rounding stage. + + With the choice of shift above, together with our assumption that + a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows + that x >= 1. + + 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace + this with an exactly representable float of the form + + round(x/2**extra_bits) * 2**(extra_bits+shift). + + For float representability, we need x/2**extra_bits < + 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP - + DBL_MANT_DIG. This translates to the condition: + + extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG + + To round, we just modify the bottom digit of x in-place; this can + end up giving a digit with value > PyLONG_MASK, but that's not a + problem since digits can hold values up to 2*PyLONG_MASK+1. + + With the original choices for shift above, extra_bits will always + be 2 or 3. Then rounding under the round-half-to-even rule, we + round up iff the most significant of the extra bits is 1, and + either: (a) the computation of x in step 2 had an inexact result, + or (b) at least one other of the extra bits is 1, or (c) the least + significant bit of x (above those to be rounded) is 1. + + 4. Conversion to a double is straightforward; all floating-point + operations involved in the conversion are exact, so there's no + danger of rounding errors. + + 5. Use ldexp(x, shift) to compute x*2**shift, the final result. + The result will always be exactly representable as a double, except + in the case that it overflows. To avoid dependence on the exact + behaviour of ldexp on overflow, we check for overflow before + applying ldexp. The result of ldexp is adjusted for sign before + returning. + */ + + /* Reduce to case where a and b are both positive. */ + a_size = ABS(Py_SIZE(a)); + b_size = ABS(Py_SIZE(b)); + negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); + if (b_size == 0) { PyErr_SetString(PyExc_ZeroDivisionError, - "long division or modulo by zero"); - return NULL; + "division by zero"); + goto error; } + if (a_size == 0) + goto underflow_or_zero; - /* True value is very close to ad/bd * 2**(PyLong_SHIFT*(aexp-bexp)) */ - ad /= bd; /* overflow/underflow impossible here */ - aexp -= bexp; - if (aexp > INT_MAX / PyLong_SHIFT) + /* Fast path for a and b small (exactly representable in a double). + Relies on floating-point division being correctly rounded; results + may be subject to double rounding on x86 machines that operate with + the x87 FPU set to 64-bit precision. */ + a_is_small = a_size <= MANT_DIG_DIGITS || + (a_size == MANT_DIG_DIGITS+1 && + a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + b_is_small = b_size <= MANT_DIG_DIGITS || + (b_size == MANT_DIG_DIGITS+1 && + b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + if (a_is_small && b_is_small) { + double da, db; + da = a->ob_digit[--a_size]; + while (a_size > 0) + da = da * PyLong_BASE + a->ob_digit[--a_size]; + db = b->ob_digit[--b_size]; + while (b_size > 0) + db = db * PyLong_BASE + b->ob_digit[--b_size]; + result = da / db; + goto success; + } + + /* Catch obvious cases of underflow and overflow */ + diff = a_size - b_size; + if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1) + /* Extreme overflow */ goto overflow; - else if (aexp < -(INT_MAX / PyLong_SHIFT)) - return PyFloat_FromDouble(0.0); /* underflow to 0 */ - errno = 0; - ad = ldexp(ad, aexp * PyLong_SHIFT); - if (Py_OVERFLOWED(ad)) /* ignore underflow to 0.0 */ + else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT) + /* Extreme underflow */ + goto underflow_or_zero; + /* Next line is now safe from overflowing a Py_ssize_t */ + diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) - + bits_in_digit(b->ob_digit[b_size - 1]); + /* Now diff = a_bits - b_bits. */ + if (diff > DBL_MAX_EXP) goto overflow; - return PyFloat_FromDouble(ad); + else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1) + goto underflow_or_zero; + + /* Choose value for shift; see comments for step 1 above. */ + shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2; -overflow: + inexact = 0; + + /* x = abs(a * 2**-shift) */ + if (shift <= 0) { + Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT; + digit rem; + /* x = a << -shift */ + if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) { + /* In practice, it's probably impossible to end up + here. Both a and b would have to be enormous, + using close to SIZE_T_MAX bytes of memory each. */ + PyErr_SetString(PyExc_OverflowError, + "intermediate overflow during division"); + goto error; + } + x = _PyLong_New(a_size + shift_digits + 1); + if (x == NULL) + goto error; + for (i = 0; i < shift_digits; i++) + x->ob_digit[i] = 0; + rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, + a_size, -shift % PyLong_SHIFT); + x->ob_digit[a_size + shift_digits] = rem; + } + else { + Py_ssize_t shift_digits = shift / PyLong_SHIFT; + digit rem; + /* x = a >> shift */ + assert(a_size >= shift_digits); + x = _PyLong_New(a_size - shift_digits); + if (x == NULL) + goto error; + rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, + a_size - shift_digits, shift % PyLong_SHIFT); + /* set inexact if any of the bits shifted out is nonzero */ + if (rem) + inexact = 1; + while (!inexact && shift_digits > 0) + if (a->ob_digit[--shift_digits]) + inexact = 1; + } + long_normalize(x); + x_size = Py_SIZE(x); + + /* x //= b. If the remainder is nonzero, set inexact. We own the only + reference to x, so it's safe to modify it in-place. */ + if (b_size == 1) { + digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, + b->ob_digit[0]); + long_normalize(x); + if (rem) + inexact = 1; + } + else { + PyLongObject *div, *rem; + div = x_divrem(x, b, &rem); + Py_DECREF(x); + x = div; + if (x == NULL) + goto error; + if (Py_SIZE(rem)) + inexact = 1; + Py_DECREF(rem); + } + x_size = ABS(Py_SIZE(x)); + assert(x_size > 0); /* result of division is never zero */ + x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]); + + /* The number of extra bits that have to be rounded away. */ + extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; + assert(extra_bits == 2 || extra_bits == 3); + + /* Round by directly modifying the low digit of x. */ + mask = (digit)1 << (extra_bits - 1); + low = x->ob_digit[0] | inexact; + if (low & mask && low & (3*mask-1)) + low += mask; + x->ob_digit[0] = low & ~(mask-1U); + + /* Convert x to a double dx; the conversion is exact. */ + dx = x->ob_digit[--x_size]; + while (x_size > 0) + dx = dx * PyLong_BASE + x->ob_digit[--x_size]; + Py_DECREF(x); + + /* Check whether ldexp result will overflow a double. */ + if (shift + x_bits >= DBL_MAX_EXP && + (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, x_bits))) + goto overflow; + result = ldexp(dx, shift); + + success: + Py_DECREF(a); + Py_DECREF(b); + return PyFloat_FromDouble(negate ? -result : result); + + underflow_or_zero: + Py_DECREF(a); + Py_DECREF(b); + return PyFloat_FromDouble(negate ? -0.0 : 0.0); + + overflow: PyErr_SetString(PyExc_OverflowError, - "long/long too large for a float"); + "integer division result too large for a float"); + error: + Py_DECREF(a); + Py_DECREF(b); return NULL; - } static PyObject * From python-checkins at python.org Sun Dec 27 16:09:50 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 15:09:50 -0000 Subject: [Python-checkins] r77063 - in python/branches/py3k: Lib/test/test_long.py Misc/NEWS Objects/longobject.c Message-ID: Author: mark.dickinson Date: Sun Dec 27 16:09:50 2009 New Revision: 77063 Log: Merged revisions 77062 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77062 | mark.dickinson | 2009-12-27 14:55:57 +0000 (Sun, 27 Dec 2009) | 2 lines Issue #1811: Improve accuracy and consistency of true division for integers. ........ 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 Sun Dec 27 16:09:50 2009 @@ -14,6 +14,11 @@ def __str__(self): return self.format % self.args +# decorator for skipping tests on non-IEEE 754 platforms +requires_IEEE_754 = unittest.skipUnless( + float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + # SHIFT should match the value in longintrepr.h for best testing. SHIFT = sys.int_info.bits_per_digit BASE = 2 ** SHIFT @@ -35,6 +40,43 @@ # add complements & negations special += [~x for x in special] + [-x for x in special] +DBL_MAX = sys.float_info.max +DBL_MAX_EXP = sys.float_info.max_exp +DBL_MIN_EXP = sys.float_info.min_exp +DBL_MANT_DIG = sys.float_info.mant_dig +DBL_MIN_OVERFLOW = 2**DBL_MAX_EXP - 2**(DBL_MAX_EXP - DBL_MANT_DIG - 1) + +# pure Python version of correctly-rounded true division +def truediv(a, b): + """Correctly-rounded true division for integers.""" + negative = a^b < 0 + a, b = abs(a), abs(b) + + # exceptions: division by zero, overflow + if not b: + raise ZeroDivisionError("division by zero") + if a >= DBL_MIN_OVERFLOW * b: + raise OverflowError("int/int too large to represent as a float") + + # find integer d satisfying 2**(d - 1) <= a/b < 2**d + d = a.bit_length() - b.bit_length() + if d >= 0 and a >= 2**d * b or d < 0 and a * 2**-d >= b: + d += 1 + + # compute 2**-exp * a / b for suitable exp + exp = max(d, DBL_MIN_EXP) - DBL_MANT_DIG + a, b = a << max(-exp, 0), b << max(exp, 0) + q, r = divmod(a, b) + + # round-half-to-even: fractional part is r/b, which is > 0.5 iff + # 2*r > b, and == 0.5 iff 2*r == b. + if 2*r > b or 2*r == b and q % 2 == 1: + q += 1 + + result = float(q) * 2.**exp + return -result if negative else result + + class LongTest(unittest.TestCase): # Get quasi-random long consisting of ndigits digits (in base BASE). @@ -306,10 +348,6 @@ @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, @@ -614,6 +652,128 @@ for zero in ["huge / 0", "mhuge / 0"]: self.assertRaises(ZeroDivisionError, eval, zero, namespace) + def check_truediv(self, a, b, skip_small=True): + """Verify that the result of a/b is correctly rounded, by + comparing it with a pure Python implementation of correctly + rounded division. b should be nonzero.""" + + # skip check for small a and b: in this case, the current + # implementation converts the arguments to float directly and + # then applies a float division. This can give doubly-rounded + # results on x87-using machines (particularly 32-bit Linux). + if skip_small and max(abs(a), abs(b)) < 2**DBL_MANT_DIG: + return + + try: + # use repr so that we can distinguish between -0.0 and 0.0 + expected = repr(truediv(a, b)) + except OverflowError: + expected = 'overflow' + except ZeroDivisionError: + expected = 'zerodivision' + + try: + got = repr(a / b) + except OverflowError: + got = 'overflow' + except ZeroDivisionError: + got = 'zerodivision' + + if expected != got: + self.fail("Incorrectly rounded division {}/{}: expected {!r}, " + "got {!r}.".format(a, b, expected, got)) + + @requires_IEEE_754 + def test_correctly_rounded_true_division(self): + # more stringent tests than those above, checking that the + # result of true division of ints is always correctly rounded. + # This test should probably be considered CPython-specific. + + # Exercise all the code paths not involving Gb-sized ints. + # ... divisions involving zero + self.check_truediv(123, 0) + self.check_truediv(-456, 0) + self.check_truediv(0, 3) + self.check_truediv(0, -3) + self.check_truediv(0, 0) + # ... overflow or underflow by large margin + self.check_truediv(671 * 12345 * 2**DBL_MAX_EXP, 12345) + self.check_truediv(12345, 345678 * 2**(DBL_MANT_DIG - DBL_MIN_EXP)) + # ... a much larger or smaller than b + self.check_truediv(12345*2**100, 98765) + self.check_truediv(12345*2**30, 98765*7**81) + # ... a / b near a boundary: one of 1, 2**DBL_MANT_DIG, 2**DBL_MIN_EXP, + # 2**DBL_MAX_EXP, 2**(DBL_MIN_EXP-DBL_MANT_DIG) + bases = (0, DBL_MANT_DIG, DBL_MIN_EXP, + DBL_MAX_EXP, DBL_MIN_EXP - DBL_MANT_DIG) + for base in bases: + for exp in range(base - 15, base + 15): + self.check_truediv(75312*2**max(exp, 0), 69187*2**max(-exp, 0)) + self.check_truediv(69187*2**max(exp, 0), 75312*2**max(-exp, 0)) + + # overflow corner case + for m in [1, 2, 7, 17, 12345, 7**100, + -1, -2, -5, -23, -67891, -41**50]: + for n in range(-10, 10): + self.check_truediv(m*DBL_MIN_OVERFLOW + n, m) + self.check_truediv(m*DBL_MIN_OVERFLOW + n, -m) + + # check detection of inexactness in shifting stage + for n in range(250): + # (2**DBL_MANT_DIG+1)/(2**DBL_MANT_DIG) lies halfway + # between two representable floats, and would usually be + # rounded down under round-half-to-even. The tiniest of + # additions to the numerator should cause it to be rounded + # up instead. + self.check_truediv((2**DBL_MANT_DIG + 1)*12345*2**200 + 2**n, + 2**DBL_MANT_DIG*12345) + + # 1/2731 is one of the smallest division cases that's subject + # to double rounding on IEEE 754 machines working internally with + # 64-bit precision. On such machines, the next check would fail, + # were it not explicitly skipped in check_truediv. + self.check_truediv(1, 2731) + + # a particularly bad case for the old algorithm: gives an + # error of close to 3.5 ulps. + self.check_truediv(295147931372582273023, 295147932265116303360) + for i in range(1000): + self.check_truediv(10**(i+1), 10**i) + self.check_truediv(10**i, 10**(i+1)) + + # test round-half-to-even behaviour, normal result + for m in [1, 2, 4, 7, 8, 16, 17, 32, 12345, 7**100, + -1, -2, -5, -23, -67891, -41**50]: + for n in range(-10, 10): + self.check_truediv(2**DBL_MANT_DIG*m + n, m) + + # test round-half-to-even, subnormal result + for n in range(-20, 20): + self.check_truediv(n, 2**1076) + + # largeish random divisions: a/b where |a| <= |b| <= + # 2*|a|; |ans| is between 0.5 and 1.0, so error should + # always be bounded by 2**-54 with equality possible only + # if the least significant bit of q=ans*2**53 is zero. + for M in [10**10, 10**100, 10**1000]: + for i in range(1000): + a = random.randrange(1, M) + b = random.randrange(a, 2*a+1) + self.check_truediv(a, b) + self.check_truediv(-a, b) + self.check_truediv(a, -b) + self.check_truediv(-a, -b) + + # and some (genuinely) random tests + for _ in range(10000): + a_bits = random.randrange(1000) + b_bits = random.randrange(1, 1000) + x = random.randrange(2**a_bits) + y = random.randrange(1, 2**b_bits) + self.check_truediv(x, y) + self.check_truediv(x, -y) + self.check_truediv(-x, y) + self.check_truediv(-x, -y) def test_small_ints(self): for i in range(-5, 257): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Dec 27 16:09:50 2009 @@ -12,6 +12,11 @@ Core and Builtins ----------------- +- Issue #1811: improve accuracy and cross-platform consistency for + true division of integers: the result of a/b is now correctly + rounded for ints a and b (at least on IEEE 754 platforms), and in + particular does not depend on the internal representation of an int. + - Issue #6834: replace the implementation for the 'python' and 'pythonw' executables on OSX. Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Sun Dec 27 16:09:50 2009 @@ -3213,47 +3213,267 @@ return (PyObject *)div; } +/* PyLong/PyLong -> float, with correctly rounded result. */ + +#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT) +#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT) + static PyObject * -long_true_divide(PyObject *a, PyObject *b) +long_true_divide(PyObject *v, PyObject *w) { - double ad, bd; - int failed, aexp = -1, bexp = -1; + PyLongObject *a, *b, *x; + Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits; + digit mask, low; + int inexact, negate, a_is_small, b_is_small; + double dx, result; - CHECK_BINOP(a, b); - ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp); - bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp); - failed = (ad == -1.0 || bd == -1.0) && PyErr_Occurred(); - if (failed) - return NULL; - /* 'aexp' and 'bexp' were initialized to -1 to silence gcc-4.0.x, - but should really be set correctly after sucessful calls to - _PyLong_AsScaledDouble() */ - assert(aexp >= 0 && bexp >= 0); + CHECK_BINOP(v, w); + a = (PyLongObject *)v; + b = (PyLongObject *)w; + + /* + Method in a nutshell: + + 0. reduce to case a, b > 0; filter out obvious underflow/overflow + 1. choose a suitable integer 'shift' + 2. use integer arithmetic to compute x = floor(2**-shift*a/b) + 3. adjust x for correct rounding + 4. convert x to a double dx with the same value + 5. return ldexp(dx, shift). + + In more detail: + + 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b + returns either 0.0 or -0.0, depending on the sign of b. For a and + b both nonzero, ignore signs of a and b, and add the sign back in + at the end. Now write a_bits and b_bits for the bit lengths of a + and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise + for b). Then + + 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1). + + So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and + so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP - + DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of + the way, we can assume that + + DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP. + + 1. The integer 'shift' is chosen so that x has the right number of + bits for a double, plus two or three extra bits that will be used + in the rounding decisions. Writing a_bits and b_bits for the + number of significant bits in a and b respectively, a + straightforward formula for shift is: + + shift = a_bits - b_bits - DBL_MANT_DIG - 2 + + This is fine in the usual case, but if a/b is smaller than the + smallest normal float then it can lead to double rounding on an + IEEE 754 platform, giving incorrectly rounded results. So we + adjust the formula slightly. The actual formula used is: + + shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2 + + 2. The quantity x is computed by first shifting a (left -shift bits + if shift <= 0, right shift bits if shift > 0) and then dividing by + b. For both the shift and the division, we keep track of whether + the result is inexact, in a flag 'inexact'; this information is + needed at the rounding stage. + + With the choice of shift above, together with our assumption that + a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows + that x >= 1. + + 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace + this with an exactly representable float of the form + + round(x/2**extra_bits) * 2**(extra_bits+shift). + + For float representability, we need x/2**extra_bits < + 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP - + DBL_MANT_DIG. This translates to the condition: + + extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG + + To round, we just modify the bottom digit of x in-place; this can + end up giving a digit with value > PyLONG_MASK, but that's not a + problem since digits can hold values up to 2*PyLONG_MASK+1. + + With the original choices for shift above, extra_bits will always + be 2 or 3. Then rounding under the round-half-to-even rule, we + round up iff the most significant of the extra bits is 1, and + either: (a) the computation of x in step 2 had an inexact result, + or (b) at least one other of the extra bits is 1, or (c) the least + significant bit of x (above those to be rounded) is 1. + + 4. Conversion to a double is straightforward; all floating-point + operations involved in the conversion are exact, so there's no + danger of rounding errors. + + 5. Use ldexp(x, shift) to compute x*2**shift, the final result. + The result will always be exactly representable as a double, except + in the case that it overflows. To avoid dependence on the exact + behaviour of ldexp on overflow, we check for overflow before + applying ldexp. The result of ldexp is adjusted for sign before + returning. + */ - if (bd == 0.0) { + /* Reduce to case where a and b are both positive. */ + a_size = ABS(Py_SIZE(a)); + b_size = ABS(Py_SIZE(b)); + negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); + if (b_size == 0) { PyErr_SetString(PyExc_ZeroDivisionError, - "integer division or modulo by zero"); - return NULL; + "division by zero"); + goto error; } + if (a_size == 0) + goto underflow_or_zero; - /* True value is very close to ad/bd * 2**(PyLong_SHIFT*(aexp-bexp)) */ - ad /= bd; /* overflow/underflow impossible here */ - aexp -= bexp; - if (aexp > INT_MAX / PyLong_SHIFT) + /* Fast path for a and b small (exactly representable in a double). + Relies on floating-point division being correctly rounded; results + may be subject to double rounding on x86 machines that operate with + the x87 FPU set to 64-bit precision. */ + a_is_small = a_size <= MANT_DIG_DIGITS || + (a_size == MANT_DIG_DIGITS+1 && + a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + b_is_small = b_size <= MANT_DIG_DIGITS || + (b_size == MANT_DIG_DIGITS+1 && + b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + if (a_is_small && b_is_small) { + double da, db; + da = a->ob_digit[--a_size]; + while (a_size > 0) + da = da * PyLong_BASE + a->ob_digit[--a_size]; + db = b->ob_digit[--b_size]; + while (b_size > 0) + db = db * PyLong_BASE + b->ob_digit[--b_size]; + result = da / db; + goto success; + } + + /* Catch obvious cases of underflow and overflow */ + diff = a_size - b_size; + if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1) + /* Extreme overflow */ goto overflow; - else if (aexp < -(INT_MAX / PyLong_SHIFT)) - return PyFloat_FromDouble(0.0); /* underflow to 0 */ - errno = 0; - ad = ldexp(ad, aexp * PyLong_SHIFT); - if (Py_OVERFLOWED(ad)) /* ignore underflow to 0.0 */ + else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT) + /* Extreme underflow */ + goto underflow_or_zero; + /* Next line is now safe from overflowing a Py_ssize_t */ + diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) - + bits_in_digit(b->ob_digit[b_size - 1]); + /* Now diff = a_bits - b_bits. */ + if (diff > DBL_MAX_EXP) goto overflow; - return PyFloat_FromDouble(ad); + else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1) + goto underflow_or_zero; + + /* Choose value for shift; see comments for step 1 above. */ + shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2; + + inexact = 0; -overflow: + /* x = abs(a * 2**-shift) */ + if (shift <= 0) { + Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT; + digit rem; + /* x = a << -shift */ + if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) { + /* In practice, it's probably impossible to end up + here. Both a and b would have to be enormous, + using close to SIZE_T_MAX bytes of memory each. */ + PyErr_SetString(PyExc_OverflowError, + "intermediate overflow during division"); + goto error; + } + x = _PyLong_New(a_size + shift_digits + 1); + if (x == NULL) + goto error; + for (i = 0; i < shift_digits; i++) + x->ob_digit[i] = 0; + rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, + a_size, -shift % PyLong_SHIFT); + x->ob_digit[a_size + shift_digits] = rem; + } + else { + Py_ssize_t shift_digits = shift / PyLong_SHIFT; + digit rem; + /* x = a >> shift */ + assert(a_size >= shift_digits); + x = _PyLong_New(a_size - shift_digits); + if (x == NULL) + goto error; + rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, + a_size - shift_digits, shift % PyLong_SHIFT); + /* set inexact if any of the bits shifted out is nonzero */ + if (rem) + inexact = 1; + while (!inexact && shift_digits > 0) + if (a->ob_digit[--shift_digits]) + inexact = 1; + } + long_normalize(x); + x_size = Py_SIZE(x); + + /* x //= b. If the remainder is nonzero, set inexact. We own the only + reference to x, so it's safe to modify it in-place. */ + if (b_size == 1) { + digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, + b->ob_digit[0]); + long_normalize(x); + if (rem) + inexact = 1; + } + else { + PyLongObject *div, *rem; + div = x_divrem(x, b, &rem); + Py_DECREF(x); + x = div; + if (x == NULL) + goto error; + if (Py_SIZE(rem)) + inexact = 1; + Py_DECREF(rem); + } + x_size = ABS(Py_SIZE(x)); + assert(x_size > 0); /* result of division is never zero */ + x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]); + + /* The number of extra bits that have to be rounded away. */ + extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; + assert(extra_bits == 2 || extra_bits == 3); + + /* Round by directly modifying the low digit of x. */ + mask = (digit)1 << (extra_bits - 1); + low = x->ob_digit[0] | inexact; + if (low & mask && low & (3*mask-1)) + low += mask; + x->ob_digit[0] = low & ~(mask-1U); + + /* Convert x to a double dx; the conversion is exact. */ + dx = x->ob_digit[--x_size]; + while (x_size > 0) + dx = dx * PyLong_BASE + x->ob_digit[--x_size]; + Py_DECREF(x); + + /* Check whether ldexp result will overflow a double. */ + if (shift + x_bits >= DBL_MAX_EXP && + (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, x_bits))) + goto overflow; + result = ldexp(dx, shift); + + success: + return PyFloat_FromDouble(negate ? -result : result); + + underflow_or_zero: + return PyFloat_FromDouble(negate ? -0.0 : 0.0); + + overflow: PyErr_SetString(PyExc_OverflowError, - "int/int too large for a float"); + "integer division result too large for a float"); + error: return NULL; - } static PyObject * From python-checkins at python.org Sun Dec 27 16:11:46 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 15:11:46 -0000 Subject: [Python-checkins] r77064 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sun Dec 27 16:11:46 2009 New Revision: 77064 Log: Blocked revisions 77062 via svnmerge ........ r77062 | mark.dickinson | 2009-12-27 14:55:57 +0000 (Sun, 27 Dec 2009) | 2 lines Issue #1811: Improve accuracy and consistency of true division for integers. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 27 16:12:15 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 15:12:15 -0000 Subject: [Python-checkins] r77065 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Dec 27 16:12:14 2009 New Revision: 77065 Log: Blocked revisions 77063 via svnmerge ................ r77063 | mark.dickinson | 2009-12-27 15:09:50 +0000 (Sun, 27 Dec 2009) | 9 lines Merged revisions 77062 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77062 | mark.dickinson | 2009-12-27 14:55:57 +0000 (Sun, 27 Dec 2009) | 2 lines Issue #1811: Improve accuracy and consistency of true division for integers. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Dec 27 17:16:02 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 16:16:02 -0000 Subject: [Python-checkins] r77066 - python/trunk/Lib/test/test_long_future.py Message-ID: Author: mark.dickinson Date: Sun Dec 27 17:16:02 2009 New Revision: 77066 Log: Use ldexp(q, exp) instead of q*2.**exp in true division test, to avoid bogus failures on platforms with broken pow (e.g., Ubuntu/ia64). Modified: python/trunk/Lib/test/test_long_future.py Modified: python/trunk/Lib/test/test_long_future.py ============================================================================== --- python/trunk/Lib/test/test_long_future.py (original) +++ python/trunk/Lib/test/test_long_future.py Sun Dec 27 17:16:02 2009 @@ -5,6 +5,7 @@ import sys import random +import math import unittest from test.test_support import run_unittest @@ -46,7 +47,7 @@ if 2*r > b or 2*r == b and q % 2 == 1: q += 1 - result = float(q) * 2.**exp + result = math.ldexp(float(q), exp) return -result if negative else result class TrueDivisionTests(unittest.TestCase): From python-checkins at python.org Sun Dec 27 20:03:31 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 19:03:31 -0000 Subject: [Python-checkins] r77067 - in python/branches/py3k: Lib/test/test_long.py Message-ID: Author: mark.dickinson Date: Sun Dec 27 20:03:31 2009 New Revision: 77067 Log: Merged revisions 77066 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77066 | mark.dickinson | 2009-12-27 16:16:02 +0000 (Sun, 27 Dec 2009) | 1 line Use ldexp(q, exp) instead of q*2.**exp in true division test, to avoid bogus failures on platforms with broken pow (e.g., Ubuntu/ia64). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_long.py 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 Sun Dec 27 20:03:31 2009 @@ -73,7 +73,7 @@ if 2*r > b or 2*r == b and q % 2 == 1: q += 1 - result = float(q) * 2.**exp + result = math.ldexp(q, exp) return -result if negative else result From python-checkins at python.org Sun Dec 27 20:04:17 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 19:04:17 -0000 Subject: [Python-checkins] r77068 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sun Dec 27 20:04:16 2009 New Revision: 77068 Log: Blocked revisions 77066 via svnmerge ........ r77066 | mark.dickinson | 2009-12-27 16:16:02 +0000 (Sun, 27 Dec 2009) | 1 line Use ldexp(q, exp) instead of q*2.**exp in true division test, to avoid bogus failures on platforms with broken pow (e.g., Ubuntu/ia64). ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 27 20:04:44 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 19:04:44 -0000 Subject: [Python-checkins] r77069 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Dec 27 20:04:44 2009 New Revision: 77069 Log: Blocked revisions 77067 via svnmerge ................ r77067 | mark.dickinson | 2009-12-27 19:03:31 +0000 (Sun, 27 Dec 2009) | 9 lines Merged revisions 77066 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77066 | mark.dickinson | 2009-12-27 16:16:02 +0000 (Sun, 27 Dec 2009) | 1 line Use ldexp(q, exp) instead of q*2.**exp in true division test, to avoid bogus failures on platforms with broken pow (e.g., Ubuntu/ia64). ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Dec 27 21:06:45 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Sun, 27 Dec 2009 20:06:45 -0000 Subject: [Python-checkins] r77070 - python/trunk/Modules/gcmodule.c Message-ID: Author: amaury.forgeotdarc Date: Sun Dec 27 21:06:44 2009 New Revision: 77070 Log: Fix a typo in comment Modified: python/trunk/Modules/gcmodule.c Modified: python/trunk/Modules/gcmodule.c ============================================================================== --- python/trunk/Modules/gcmodule.c (original) +++ python/trunk/Modules/gcmodule.c Sun Dec 27 21:06:44 2009 @@ -960,7 +960,7 @@ */ (void)handle_finalizers(&finalizers, old); - /* Clear free list only during the collection of the higest + /* Clear free list only during the collection of the highest * generation */ if (generation == NUM_GENERATIONS-1) { clear_freelists(); @@ -981,7 +981,7 @@ int i; Py_ssize_t n = 0; - /* Find the oldest generation (higest numbered) where the count + /* Find the oldest generation (highest numbered) where the count * exceeds the threshold. Objects in the that generation and * generations younger than it will be collected. */ for (i = NUM_GENERATIONS-1; i >= 0; i--) { From python-checkins at python.org Sun Dec 27 22:31:50 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 21:31:50 -0000 Subject: [Python-checkins] r77071 - python/trunk/Lib/test/test_long_future.py Message-ID: Author: mark.dickinson Date: Sun Dec 27 22:31:50 2009 New Revision: 77071 Log: Use a more idiomatic check in check_truediv. Modified: python/trunk/Lib/test/test_long_future.py Modified: python/trunk/Lib/test/test_long_future.py ============================================================================== --- python/trunk/Lib/test/test_long_future.py (original) +++ python/trunk/Lib/test/test_long_future.py Sun Dec 27 22:31:50 2009 @@ -118,9 +118,8 @@ except ZeroDivisionError: got = 'zerodivision' - if expected != got: - self.fail("Incorrectly rounded division {}/{}: expected {!r}, " - "got {!r}.".format(a, b, expected, got)) + self.assertEqual(expected, got, "Incorrectly rounded division {}/{}: " + "expected {}, got {}".format(a, b, expected, got)) @requires_IEEE_754 def test_correctly_rounded_true_division(self): From python-checkins at python.org Sun Dec 27 22:34:05 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 21:34:05 -0000 Subject: [Python-checkins] r77072 - in python/branches/py3k: Lib/test/test_long.py Message-ID: Author: mark.dickinson Date: Sun Dec 27 22:34:05 2009 New Revision: 77072 Log: Merged revisions 77071 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77071 | mark.dickinson | 2009-12-27 21:31:50 +0000 (Sun, 27 Dec 2009) | 1 line Use a more idiomatic check in check_truediv. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_long.py 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 Sun Dec 27 22:34:05 2009 @@ -679,9 +679,8 @@ except ZeroDivisionError: got = 'zerodivision' - if expected != got: - self.fail("Incorrectly rounded division {}/{}: expected {!r}, " - "got {!r}.".format(a, b, expected, got)) + self.assertEqual(expected, got, "Incorrectly rounded division {}/{}: " + "expected {}, got {}".format(a, b, expected, got)) @requires_IEEE_754 def test_correctly_rounded_true_division(self): From python-checkins at python.org Sun Dec 27 22:35:26 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 21:35:26 -0000 Subject: [Python-checkins] r77073 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sun Dec 27 22:35:25 2009 New Revision: 77073 Log: Blocked revisions 77071 via svnmerge ........ r77071 | mark.dickinson | 2009-12-27 21:31:50 +0000 (Sun, 27 Dec 2009) | 1 line Use a more idiomatic check in check_truediv. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Dec 27 22:35:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 27 Dec 2009 21:35:56 -0000 Subject: [Python-checkins] r77074 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Dec 27 22:35:56 2009 New Revision: 77074 Log: Blocked revisions 77072 via svnmerge ................ r77072 | mark.dickinson | 2009-12-27 21:34:05 +0000 (Sun, 27 Dec 2009) | 9 lines Merged revisions 77071 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77071 | mark.dickinson | 2009-12-27 21:31:50 +0000 (Sun, 27 Dec 2009) | 1 line Use a more idiomatic check in check_truediv. ........ ................ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Mon Dec 28 00:49:46 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 28 Dec 2009 00:49:46 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r77072): sum=0 Message-ID: <20091227234946.B23A017722@ns6635.ovh.net> py3k results for svn r77072 (hg cset 2bf45f312f4c) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog1xWxJN', '-x', 'test_httpservers'] From python-checkins at python.org Mon Dec 28 00:50:39 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 27 Dec 2009 23:50:39 -0000 Subject: [Python-checkins] r77075 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Mon Dec 28 00:50:39 2009 New Revision: 77075 Log: added the range operator, and more details on versions Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Mon Dec 28 00:50:39 2009 @@ -283,15 +283,8 @@ The distutils project names should correspond to names as found on the `Python Package Index`_. -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 specified in `PEP 386`_. -If no operator is provided with a version, the "==" operator -is used by default. - -Any number of conditional operators can be specified, e.g. -the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. +Version declarations must follow the rules described in +`Version Specifiers`_ Examples:: @@ -322,10 +315,9 @@ that it provides ``ORM-bindings``, allowing other projects to depend only on having at most one of them installed. -A version declaration may be supplied (without a comparison -operator); the distribution's version number will be implied if none -is specified. Version numbers must be in the format specified in -`PEP 386`_. +A version declaration may be supplied and must follow the rules described +in `Version Specifiers`_. The distribution's version number will be implied +if none is specified. Examples:: @@ -342,7 +334,7 @@ should not be installed at the same time. Version declarations can be supplied. Version numbers must be in the -format specified in `PEP 386`_. +format specified in `Version Specifiers`_. 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. @@ -359,19 +351,13 @@ ::::::::::::::: This field specifies the Python version(s) that the package is -guaranteed to be compatible with. The format of the field is a -series of conditional operators and version numbers, separated -by commas. Conditional operators must be one of "<", ">", "<=", -">=", "==", and "!=". If no operator is provided with a version, -the "==" operator is used by default. +guaranteed to be compatible with. -Version numbers must be in the format specified in `PEP 386`_. - -Any number of conditional operators can be specified, e.g. -the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. +Version numbers must be in the format specified in `Version Specifiers`_. Examples:: + Requires-Python: 2.5 Requires-Python: >2.1 Requires-Python: >=2.3.4 Requires-Python: 2.5, 2.6 @@ -389,19 +375,13 @@ dependency, 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 "!=". If no -operator is provided with a version, the "==" operator is used by default. +Version numbers must be in the format specified in `Version Specifiers`_. Because they refer to non-Python software releases, version numbers for this field are **not** required to conform to the format specified in `PEP 386`_: they should correspond to the version scheme used by the external dependency. -Any number of conditional operators can be specified, e.g. -the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. - Notice that there's is no particular rule on the strings to be used. Examples:: @@ -426,8 +406,38 @@ Version Specifiers ================== -The specification for distribution version specifiers has been moved to -`PEP 386`_. +Version specifiers are a series of conditional operators and +version numbers, separated by commas. Conditional operators +must be one of "<", ">", "<=", ">=", "==", "~=" and "!=". + +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 comma (``,``) is equivalent to the **or** operator. + +Each version number must be in the format specified in `PEP 386`_. + +The range operator ("~=") is a special operator that can be used to +define a range of versions by describing a MAJOR or a MAJOR.MINOR +version. All versions that starts with the definition will +be included in the range. + +Examples: + +- ``Requires-Python: ~=2.5`` means all versions of Python 2.5. +- ``Requires-Python: ~=2`` means all versions of Python 2. +- ``~=2.5.2`` is equivalent to ``==2.5.2`` + +The range operator is limited to the MAJOR and MINOR parts of +a version string, as specified in `PEP 386`_. Post and pre-releases +are not included in range operators. + +The ``Requires-External`` field can use the operators described in this +section but since the version scheme might not be compatible with `PEP 386`_, +the range operator might not be appliable. + +For each field that uses a version, if no operator is provided, the +range operator is used by default. For example, ``Requires-Python: 2.5`` +is equivalent to ``Requires-Python: ~=2.5``. Environment markers @@ -445,17 +455,6 @@ Requires-Dist: bar; python_version == '2.4' or python_version == '2.5' Requires-External: libxslt; 'linux' in sys.platform -These markers are using a micro-language that can be interpreted using a -function ``interpret_marker`` provided in the ``distutils.util`` module -in the stdlib:: - - >>> from distutils.util import interpret_marker - >>> interpret_marker("sys.platform == 'win32'") - True - -Depending if the execution environment meets the requirements, the function -will return True or False. - The micro-language behind this is the simplest possible: it compares only strings, with the ``==`` and ``in`` operators (and their opposites), and with the ability to combine expressions. It makes it also easy to understand @@ -545,8 +544,8 @@ Fred Drake, Anthony Baxter and Matthias Klose have all contributed to the ideas presented in this PEP. -Tres Seaver, Jim Fulton, Marc-Andr? Lemburg, Tarek Ziad? and other people at -the Distutils-SIG have contributed to the new updated version. +Tres Seaver, Jim Fulton, Marc-Andr? Lemburg, Martin von L?wis, Tarek Ziad? and +other people at the Distutils-SIG have contributed to the new updated version. .. From python-checkins at python.org Mon Dec 28 01:08:53 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 28 Dec 2009 00:08:53 -0000 Subject: [Python-checkins] r77076 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Mon Dec 28 01:08:53 2009 New Revision: 77076 Log: python.org's parser will do the PEP linking, no need to add reST on these PEP references Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Mon Dec 28 01:08:53 2009 @@ -69,7 +69,7 @@ ::::::: A string containing the package's version number. This -field must be in the format specified in `PEP 386`_. +field must be in the format specified in PEP 386. Example:: @@ -379,7 +379,7 @@ Because they refer to non-Python software releases, version numbers for this field are **not** required to conform to the format -specified in `PEP 386`_: they should correspond to the +specified in PEP 386: they should correspond to the version scheme used by the external dependency. Notice that there's is no particular rule on the strings to be used. @@ -414,7 +414,7 @@ the string ``>1.0, !=1.3.4, <2.0`` is a legal version declaration. The comma (``,``) is equivalent to the **or** operator. -Each version number must be in the format specified in `PEP 386`_. +Each version number must be in the format specified in PEP 386. The range operator ("~=") is a special operator that can be used to define a range of versions by describing a MAJOR or a MAJOR.MINOR @@ -428,11 +428,11 @@ - ``~=2.5.2`` is equivalent to ``==2.5.2`` The range operator is limited to the MAJOR and MINOR parts of -a version string, as specified in `PEP 386`_. Post and pre-releases +a version string, as specified in PEP 386. Post and pre-releases are not included in range operators. The ``Requires-External`` field can use the operators described in this -section but since the version scheme might not be compatible with `PEP 386`_, +section but since the version scheme might not be compatible with PEP 386, the range operator might not be appliable. For each field that uses a version, if no operator is provided, the @@ -527,8 +527,6 @@ .. _`Python Package Index`: http://pypi.python.org/pypi/ -.. _`PEP 386`: http://www.python.org/dev/peps/pep-0386 - .. [2] RFC 822 Long Header Fields: http://www.freesoft.org/CIE/RFC/822/7.htm From python-checkins at python.org Mon Dec 28 01:10:20 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 28 Dec 2009 00:10:20 -0000 Subject: [Python-checkins] r77077 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Mon Dec 28 01:10:20 2009 New Revision: 77077 Log: PEP 345 does not replace 314. It just specifies 1.2 Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Mon Dec 28 01:10:20 2009 @@ -10,7 +10,6 @@ Created: 28-Apr-2005 Python-Version: 2.5 Post-History: -Replaces: 314 Abstract From python-checkins at python.org Mon Dec 28 01:13:16 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 28 Dec 2009 00:13:16 -0000 Subject: [Python-checkins] r77078 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Mon Dec 28 01:13:16 2009 New Revision: 77078 Log: more editing Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Mon Dec 28 01:13:16 2009 @@ -128,7 +128,7 @@ To support empty lines and lines with indentation with respect to the RFC 822 format, any new line has to be suffixed by 7 spaces -followed by a pipe (`|`) char. As a result, the Description field is +followed by a pipe ("|") char. As a result, the Description field is encoded into a folded field that can be interpreted by RFC822 parser [2]_. @@ -143,8 +143,8 @@ | 3 | -This encoding implies that any occurences of ``\n |`` have to be replaced -by ``\n`` when the field is unfolded using a RFC822 reader. +This encoding implies that any occurences of "\n |" have to be replaced +by "\n" when the field is unfolded using a RFC822 reader. Keywords (optional) @@ -410,8 +410,8 @@ must be one of "<", ">", "<=", ">=", "==", "~=" and "!=". 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 comma (``,``) is equivalent to the **or** operator. +the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. +The comma (",") is equivalent to the **or** operator. Each version number must be in the format specified in PEP 386. @@ -443,7 +443,7 @@ =================== An **environment marker** is a marker that can be added at the end of a -field after a semi-colon (';'), to add a condition about the execution +field after a semi-colon (";"), to add a condition about the execution environment. Here are some example of fields using such markers:: From python-checkins at python.org Mon Dec 28 01:21:16 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 28 Dec 2009 00:21:16 -0000 Subject: [Python-checkins] r77079 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Mon Dec 28 01:21:16 2009 New Revision: 77079 Log: escaping EOLs Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Mon Dec 28 01:21:16 2009 @@ -143,8 +143,8 @@ | 3 | -This encoding implies that any occurences of "\n |" have to be replaced -by "\n" when the field is unfolded using a RFC822 reader. +This encoding implies that any occurences of "``\n |``" have to be replaced +by "``\n``" when the field is unfolded using a RFC822 reader. Keywords (optional) From python-checkins at python.org Mon Dec 28 02:07:29 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 28 Dec 2009 01:07:29 -0000 Subject: [Python-checkins] r77080 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Mon Dec 28 02:07:29 2009 New Revision: 77080 Log: fixed the comma operator (it's AND) Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Mon Dec 28 02:07:29 2009 @@ -359,7 +359,7 @@ Requires-Python: 2.5 Requires-Python: >2.1 Requires-Python: >=2.3.4 - Requires-Python: 2.5, 2.6 + Requires-Python: >=2.5,<2.7 Requires-External (multiple use) @@ -411,7 +411,7 @@ 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 comma (",") is equivalent to the **or** operator. +The comma (",") is equivalent to the **and** operator. Each version number must be in the format specified in PEP 386. From python-checkins at python.org Mon Dec 28 08:59:06 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 07:59:06 -0000 Subject: [Python-checkins] r77081 - python/trunk/Doc/c-api/buffer.rst Message-ID: Author: georg.brandl Date: Mon Dec 28 08:59:05 2009 New Revision: 77081 Log: #7577: fix signature of PyBuffer_FillInfo(). 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 Mon Dec 28 08:59:05 2009 @@ -294,7 +294,7 @@ 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) +.. cfunction:: int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, 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 From python-checkins at python.org Mon Dec 28 08:59:21 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 07:59:21 -0000 Subject: [Python-checkins] r77082 - python/branches/py3k/Doc/c-api/typeobj.rst Message-ID: Author: georg.brandl Date: Mon Dec 28 08:59:20 2009 New Revision: 77082 Log: #7577: fix signature info for getbufferproc. Modified: python/branches/py3k/Doc/c-api/typeobj.rst Modified: python/branches/py3k/Doc/c-api/typeobj.rst ============================================================================== --- python/branches/py3k/Doc/c-api/typeobj.rst (original) +++ python/branches/py3k/Doc/c-api/typeobj.rst Mon Dec 28 08:59:20 2009 @@ -1210,7 +1210,7 @@ This should fill a :ctype:`Py_buffer` with the necessary data for exporting the type. The signature of :data:`getbufferproc` is ``int - (PyObject *obj, PyObject *view, int flags)``. *obj* is the object to + (PyObject *obj, Py_buffer *view, int flags)``. *obj* is the object to export, *view* is the :ctype:`Py_buffer` struct to fill, and *flags* gives the conditions the caller wants the memory under. (See :cfunc:`PyObject_GetBuffer` for all flags.) :cmember:`bf_getbuffer` is From python-checkins at python.org Mon Dec 28 09:00:47 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:00:47 -0000 Subject: [Python-checkins] r77083 - in python/branches/py3k: Doc/c-api/buffer.rst Message-ID: Author: georg.brandl Date: Mon Dec 28 09:00:47 2009 New Revision: 77083 Log: Merged revisions 77081 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77081 | georg.brandl | 2009-12-28 08:59:05 +0100 (Mo, 28 Dez 2009) | 1 line #7577: fix signature of PyBuffer_FillInfo(). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/buffer.rst Modified: python/branches/py3k/Doc/c-api/buffer.rst ============================================================================== --- python/branches/py3k/Doc/c-api/buffer.rst (original) +++ python/branches/py3k/Doc/c-api/buffer.rst Mon Dec 28 09:00:47 2009 @@ -289,7 +289,7 @@ 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) +.. cfunction:: int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, 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 From python-checkins at python.org Mon Dec 28 09:01:59 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:01:59 -0000 Subject: [Python-checkins] r77084 - python/trunk/Doc/library/collections.rst Message-ID: Author: georg.brandl Date: Mon Dec 28 09:01:59 2009 New Revision: 77084 Log: #7586: fix typo. 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 Mon Dec 28 09:01:59 2009 @@ -818,7 +818,7 @@ Point: x= 3.000 y= 4.000 hypot= 5.000 Point: x=14.000 y= 0.714 hypot=14.018 -The subclass shown above sets ``__slots__`` to an empty tuple. This keeps +The subclass shown above sets ``__slots__`` to an empty tuple. This helps keep memory requirements low by preventing the creation of instance dictionaries. Subclassing is not useful for adding new, stored fields. Instead, simply From python-checkins at python.org Mon Dec 28 09:02:38 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:02:38 -0000 Subject: [Python-checkins] r77085 - in python/branches/py3k: Doc/library/collections.rst Message-ID: Author: georg.brandl Date: Mon Dec 28 09:02:38 2009 New Revision: 77085 Log: Merged revisions 77084 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77084 | georg.brandl | 2009-12-28 09:01:59 +0100 (Mo, 28 Dez 2009) | 1 line #7586: fix typo. ........ Modified: python/branches/py3k/ (props changed) 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 Mon Dec 28 09:02:38 2009 @@ -794,7 +794,7 @@ Point: x= 3.000 y= 4.000 hypot= 5.000 Point: x=14.000 y= 0.714 hypot=14.018 -The subclass shown above sets ``__slots__`` to an empty tuple. This keeps +The subclass shown above sets ``__slots__`` to an empty tuple. This helps keep memory requirements low by preventing the creation of instance dictionaries. From python-checkins at python.org Mon Dec 28 09:09:33 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:09:33 -0000 Subject: [Python-checkins] r77086 - python/trunk/Lib/subprocess.py Message-ID: Author: georg.brandl Date: Mon Dec 28 09:09:32 2009 New Revision: 77086 Log: #7381: consistency update, and backport avoiding ``None >= 0`` check from py3k. Modified: python/trunk/Lib/subprocess.py Modified: python/trunk/Lib/subprocess.py ============================================================================== --- python/trunk/Lib/subprocess.py (original) +++ python/trunk/Lib/subprocess.py Mon Dec 28 09:09:32 2009 @@ -136,7 +136,8 @@ The arguments are the same as for the Popen constructor. Example: - output = subprocess.check_output(["ls", "-l", "/dev/null"]) + output = check_output(["ls", "-l", "/dev/null"]) + Exceptions ---------- @@ -462,7 +463,8 @@ def _cleanup(): for inst in _active[:]: - if inst._internal_poll(_deadstate=sys.maxint) >= 0: + res = inst._internal_poll(_deadstate=sys.maxint) + if res is not None and res >= 0: try: _active.remove(inst) except ValueError: @@ -517,11 +519,11 @@ '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=STDOUT. >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], - ... stderr=subprocess.STDOUT) + ... stderr=STDOUT) 'ls: non_existent_file: No such file or directory\n' """ if 'stdout' in kwargs: From python-checkins at python.org Mon Dec 28 09:10:39 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:10:39 -0000 Subject: [Python-checkins] r77087 - in python/branches/py3k: Lib/subprocess.py Message-ID: Author: georg.brandl Date: Mon Dec 28 09:10:38 2009 New Revision: 77087 Log: Recorded merge of revisions 77086 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77086 | georg.brandl | 2009-12-28 09:09:32 +0100 (Mo, 28 Dez 2009) | 1 line #7381: consistency update, and backport avoiding ``None >= 0`` check from py3k. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/subprocess.py Modified: python/branches/py3k/Lib/subprocess.py ============================================================================== --- python/branches/py3k/Lib/subprocess.py (original) +++ python/branches/py3k/Lib/subprocess.py Mon Dec 28 09:10:38 2009 @@ -449,11 +449,11 @@ b'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=STDOUT. >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], - ... stderr=subprocess.STDOUT) + ... stderr=STDOUT) b'ls: non_existent_file: No such file or directory\n' """ if 'stdout' in kwargs: From python-checkins at python.org Mon Dec 28 09:34:58 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:34:58 -0000 Subject: [Python-checkins] r77088 - in python/trunk: Doc/c-api/exceptions.rst Doc/data/refcounts.dat Include/pyerrors.h Lib/test/test_exceptions.py Misc/NEWS Modules/_testcapimodule.c Python/errors.c Message-ID: Author: georg.brandl Date: Mon Dec 28 09:34:58 2009 New Revision: 77088 Log: #7033: add new API function PyErr_NewExceptionWithDoc, for easily giving new exceptions a docstring. Modified: python/trunk/Doc/c-api/exceptions.rst python/trunk/Doc/data/refcounts.dat python/trunk/Include/pyerrors.h python/trunk/Lib/test/test_exceptions.py python/trunk/Misc/NEWS python/trunk/Modules/_testcapimodule.c python/trunk/Python/errors.c Modified: python/trunk/Doc/c-api/exceptions.rst ============================================================================== --- python/trunk/Doc/c-api/exceptions.rst (original) +++ python/trunk/Doc/c-api/exceptions.rst Mon Dec 28 09:34:58 2009 @@ -433,6 +433,15 @@ argument can be used to specify a dictionary of class variables and methods. +.. cfunction:: PyObject* PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict) + + Same as :cfunc:`PyErr_NewException`, except that the new exception class can + easily be given a docstring: If *doc* is non-*NULL*, it will be used as the + docstring for the exception class. + + .. versionadded:: 2.7 + + .. cfunction:: void PyErr_WriteUnraisable(PyObject *obj) This utility function prints a warning message to ``sys.stderr`` when an Modified: python/trunk/Doc/data/refcounts.dat ============================================================================== --- python/trunk/Doc/data/refcounts.dat (original) +++ python/trunk/Doc/data/refcounts.dat Mon Dec 28 09:34:58 2009 @@ -242,6 +242,12 @@ PyErr_NewException:PyObject*:base:0: PyErr_NewException:PyObject*:dict:0: +PyErr_NewExceptionWithDoc:PyObject*::+1: +PyErr_NewExceptionWithDoc:char*:name:: +PyErr_NewExceptionWithDoc:char*:doc:: +PyErr_NewExceptionWithDoc:PyObject*:base:0: +PyErr_NewExceptionWithDoc:PyObject*:dict:0: + PyErr_NoMemory:PyObject*::null: PyErr_NormalizeException:void::: Modified: python/trunk/Include/pyerrors.h ============================================================================== --- python/trunk/Include/pyerrors.h (original) +++ python/trunk/Include/pyerrors.h Mon Dec 28 09:34:58 2009 @@ -220,8 +220,10 @@ #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) /* Function to create a new exception */ -PyAPI_FUNC(PyObject *) PyErr_NewException(char *name, PyObject *base, - PyObject *dict); +PyAPI_FUNC(PyObject *) PyErr_NewException( + char *name, PyObject *base, PyObject *dict); +PyAPI_FUNC(PyObject *) PyErr_NewExceptionWithDoc( + char *name, char *doc, PyObject *base, PyObject *dict); PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); /* In sigcheck.c or signalmodule.c */ Modified: python/trunk/Lib/test/test_exceptions.py ============================================================================== --- python/trunk/Lib/test/test_exceptions.py (original) +++ python/trunk/Lib/test/test_exceptions.py Mon Dec 28 09:34:58 2009 @@ -537,6 +537,45 @@ self.assertRaises(UnicodeEncodeError, str, e) self.assertEqual(unicode(e), u'f\xf6\xf6') + def test_exception_with_doc(self): + import _testcapi + doc2 = "This is a test docstring." + doc4 = "This is another test docstring." + + self.assertRaises(SystemError, _testcapi.make_exception_with_doc, + "error1") + + # test basic usage of PyErr_NewException + error1 = _testcapi.make_exception_with_doc("_testcapi.error1") + self.assertIs(type(error1), type) + self.assertTrue(issubclass(error1, Exception)) + self.assertIsNone(error1.__doc__) + + # test with given docstring + error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2) + self.assertEqual(error2.__doc__, doc2) + + # test with explicit base (without docstring) + error3 = _testcapi.make_exception_with_doc("_testcapi.error3", + base=error2) + self.assertTrue(issubclass(error3, error2)) + + # test with explicit base tuple + class C(object): + pass + error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4, + (error3, C)) + self.assertTrue(issubclass(error4, error3)) + self.assertTrue(issubclass(error4, C)) + self.assertEqual(error4.__doc__, doc4) + + # test with explicit dictionary + error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "", + error4, {'a': 1}) + self.assertTrue(issubclass(error5, error4)) + self.assertEqual(error5.a, 1) + self.assertEqual(error5.__doc__, "") + def test_main(): run_unittest(ExceptionTests, TestSameStrAndUnicodeMsg) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Dec 28 09:34:58 2009 @@ -70,6 +70,11 @@ - Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata. +C-API +----- + +- Issue #7033: function ``PyErr_NewExceptionWithDoc()`` added. + Build ----- Modified: python/trunk/Modules/_testcapimodule.c ============================================================================== --- python/trunk/Modules/_testcapimodule.c (original) +++ python/trunk/Modules/_testcapimodule.c Mon Dec 28 09:34:58 2009 @@ -1198,6 +1198,26 @@ return (PyObject *)PyCode_NewEmpty(filename, funcname, firstlineno); } +/* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). + Run via Lib/test/test_exceptions.py */ +static PyObject * +make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs) +{ + char *name; + char *doc = NULL; + PyObject *base = NULL; + PyObject *dict = NULL; + + static char *kwlist[] = {"name", "doc", "base", "dict", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "s|sOO:make_exception_with_doc", kwlist, + &name, &doc, &base, &dict)) + return NULL; + + return PyErr_NewExceptionWithDoc(name, doc, base, dict); +} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"test_config", (PyCFunction)test_config, METH_NOARGS}, @@ -1248,6 +1268,8 @@ #endif {"traceback_print", traceback_print, METH_VARARGS}, {"code_newempty", code_newempty, METH_VARARGS}, + {"make_exception_with_doc", (PyCFunction)make_exception_with_doc, + METH_VARARGS | METH_KEYWORDS}, {NULL, NULL} /* sentinel */ }; Modified: python/trunk/Python/errors.c ============================================================================== --- python/trunk/Python/errors.c (original) +++ python/trunk/Python/errors.c Mon Dec 28 09:34:58 2009 @@ -604,6 +604,40 @@ return result; } + +/* Create an exception with docstring */ +PyObject * +PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict) +{ + int result; + PyObject *ret = NULL; + PyObject *mydict = NULL; /* points to the dict only if we create it */ + PyObject *docobj; + + if (dict == NULL) { + dict = mydict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + } + + if (doc != NULL) { + docobj = PyString_FromString(doc); + if (docobj == NULL) + goto failure; + result = PyDict_SetItemString(dict, "__doc__", docobj); + Py_DECREF(docobj); + if (result < 0) + goto failure; + } + + ret = PyErr_NewException(name, base, dict); + failure: + Py_XDECREF(mydict); + return ret; +} + + /* Call when an exception has occurred but there is no way for Python to handle it. Examples: exception in __del__ or during GC. */ void From python-checkins at python.org Mon Dec 28 09:41:02 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:41:02 -0000 Subject: [Python-checkins] r77089 - in python/branches/py3k: Doc/c-api/exceptions.rst Doc/data/refcounts.dat Include/pyerrors.h Lib/test/test_exceptions.py Misc/NEWS Modules/_testcapimodule.c Python/errors.c Message-ID: Author: georg.brandl Date: Mon Dec 28 09:41:01 2009 New Revision: 77089 Log: Merged revisions 77088 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77088 | georg.brandl | 2009-12-28 09:34:58 +0100 (Mo, 28 Dez 2009) | 1 line #7033: add new API function PyErr_NewExceptionWithDoc, for easily giving new exceptions a docstring. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/exceptions.rst python/branches/py3k/Doc/data/refcounts.dat python/branches/py3k/Include/pyerrors.h python/branches/py3k/Lib/test/test_exceptions.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_testcapimodule.c python/branches/py3k/Python/errors.c Modified: python/branches/py3k/Doc/c-api/exceptions.rst ============================================================================== --- python/branches/py3k/Doc/c-api/exceptions.rst (original) +++ python/branches/py3k/Doc/c-api/exceptions.rst Mon Dec 28 09:41:01 2009 @@ -404,6 +404,15 @@ argument can be used to specify a dictionary of class variables and methods. +.. cfunction:: PyObject* PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict) + + Same as :cfunc:`PyErr_NewException`, except that the new exception class can + easily be given a docstring: If *doc* is non-*NULL*, it will be used as the + docstring for the exception class. + + .. versionadded:: 3.2 + + .. cfunction:: void PyErr_WriteUnraisable(PyObject *obj) This utility function prints a warning message to ``sys.stderr`` when an Modified: python/branches/py3k/Doc/data/refcounts.dat ============================================================================== --- python/branches/py3k/Doc/data/refcounts.dat (original) +++ python/branches/py3k/Doc/data/refcounts.dat Mon Dec 28 09:41:01 2009 @@ -281,6 +281,12 @@ PyErr_NewException:PyObject*:base:0: PyErr_NewException:PyObject*:dict:0: +PyErr_NewExceptionWithDoc:PyObject*::+1: +PyErr_NewExceptionWithDoc:char*:name:: +PyErr_NewExceptionWithDoc:char*:doc:: +PyErr_NewExceptionWithDoc:PyObject*:base:0: +PyErr_NewExceptionWithDoc:PyObject*:dict:0: + PyErr_NoMemory:PyObject*::null: PyErr_NormalizeException:void::: Modified: python/branches/py3k/Include/pyerrors.h ============================================================================== --- python/branches/py3k/Include/pyerrors.h (original) +++ python/branches/py3k/Include/pyerrors.h Mon Dec 28 09:41:01 2009 @@ -210,8 +210,10 @@ #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) /* Function to create a new exception */ -PyAPI_FUNC(PyObject *) PyErr_NewException(const char *name, PyObject *base, - PyObject *dict); +PyAPI_FUNC(PyObject *) PyErr_NewException( + const char *name, PyObject *base, PyObject *dict); +PyAPI_FUNC(PyObject *) PyErr_NewExceptionWithDoc( + const char *name, const char *doc, PyObject *base, PyObject *dict); PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); /* In sigcheck.c or signalmodule.c */ Modified: python/branches/py3k/Lib/test/test_exceptions.py ============================================================================== --- python/branches/py3k/Lib/test/test_exceptions.py (original) +++ python/branches/py3k/Lib/test/test_exceptions.py Mon Dec 28 09:41:01 2009 @@ -618,6 +618,46 @@ tb2 = raiseMemError() self.assertEqual(tb1, tb2) + def test_exception_with_doc(self): + import _testcapi + doc2 = "This is a test docstring." + doc4 = "This is another test docstring." + + self.assertRaises(SystemError, _testcapi.make_exception_with_doc, + "error1") + + # test basic usage of PyErr_NewException + error1 = _testcapi.make_exception_with_doc("_testcapi.error1") + self.assertIs(type(error1), type) + self.assertTrue(issubclass(error1, Exception)) + self.assertIsNone(error1.__doc__) + + # test with given docstring + error2 = _testcapi.make_exception_with_doc("_testcapi.error2", doc2) + self.assertEqual(error2.__doc__, doc2) + + # test with explicit base (without docstring) + error3 = _testcapi.make_exception_with_doc("_testcapi.error3", + base=error2) + self.assertTrue(issubclass(error3, error2)) + + # test with explicit base tuple + class C(object): + pass + error4 = _testcapi.make_exception_with_doc("_testcapi.error4", doc4, + (error3, C)) + self.assertTrue(issubclass(error4, error3)) + self.assertTrue(issubclass(error4, C)) + self.assertEqual(error4.__doc__, doc4) + + # test with explicit dictionary + error5 = _testcapi.make_exception_with_doc("_testcapi.error5", "", + error4, {'a': 1}) + self.assertTrue(issubclass(error5, error4)) + self.assertEqual(error5.a, 1) + self.assertEqual(error5.__doc__, "") + + def test_main(): run_unittest(ExceptionTests) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Dec 28 09:41:01 2009 @@ -136,6 +136,8 @@ C-API ----- +- Issue #7033: function ``PyErr_NewExceptionWithDoc()`` added. + - Issue #7414: 'C' code wasn't being skipped properly (for keyword arguments) in PyArg_ParseTupleAndKeywords. Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Mon Dec 28 09:41:01 2009 @@ -1716,6 +1716,26 @@ return (PyObject *)PyCode_NewEmpty(filename, funcname, firstlineno); } +/* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). + Run via Lib/test/test_exceptions.py */ +static PyObject * +make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *name; + const char *doc = NULL; + PyObject *base = NULL; + PyObject *dict = NULL; + + static char *kwlist[] = {"name", "doc", "base", "dict", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "s|sOO:make_exception_with_doc", kwlist, + &name, &doc, &base, &dict)) + return NULL; + + return PyErr_NewExceptionWithDoc(name, doc, base, dict); +} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS}, @@ -1774,6 +1794,8 @@ {"exception_print", exception_print, METH_VARARGS}, {"argparsing", argparsing, METH_VARARGS}, {"code_newempty", code_newempty, METH_VARARGS}, + {"make_exception_with_doc", (PyCFunction)make_exception_with_doc, + METH_VARARGS | METH_KEYWORDS}, {NULL, NULL} /* sentinel */ }; Modified: python/branches/py3k/Python/errors.c ============================================================================== --- python/branches/py3k/Python/errors.c (original) +++ python/branches/py3k/Python/errors.c Mon Dec 28 09:41:01 2009 @@ -693,6 +693,41 @@ return result; } + +/* Create an exception with docstring */ +PyObject * +PyErr_NewExceptionWithDoc(const char *name, const char *doc, + PyObject *base, PyObject *dict) +{ + int result; + PyObject *ret = NULL; + PyObject *mydict = NULL; /* points to the dict only if we create it */ + PyObject *docobj; + + if (dict == NULL) { + dict = mydict = PyDict_New(); + if (dict == NULL) { + return NULL; + } + } + + if (doc != NULL) { + docobj = PyUnicode_FromString(doc); + if (docobj == NULL) + goto failure; + result = PyDict_SetItemString(dict, "__doc__", docobj); + Py_DECREF(docobj); + if (result < 0) + goto failure; + } + + ret = PyErr_NewException(name, base, dict); + failure: + Py_XDECREF(mydict); + return ret; +} + + /* Call when an exception has occurred but there is no way for Python to handle it. Examples: exception in __del__ or during GC. */ void From python-checkins at python.org Mon Dec 28 09:42:45 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:42:45 -0000 Subject: [Python-checkins] r77090 - python/branches/release31-maint Message-ID: Author: georg.brandl Date: Mon Dec 28 09:42:45 2009 New Revision: 77090 Log: Blocked revisions 77089 via svnmerge ................ r77089 | georg.brandl | 2009-12-28 09:41:01 +0100 (Mo, 28 Dez 2009) | 9 lines Merged revisions 77088 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77088 | georg.brandl | 2009-12-28 09:34:58 +0100 (Mo, 28 Dez 2009) | 1 line #7033: add new API function PyErr_NewExceptionWithDoc, for easily giving new exceptions a docstring. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Dec 28 09:43:20 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:43:20 -0000 Subject: [Python-checkins] r77091 - python/branches/release26-maint Message-ID: Author: georg.brandl Date: Mon Dec 28 09:43:19 2009 New Revision: 77091 Log: Blocked revisions 77088 via svnmerge ........ r77088 | georg.brandl | 2009-12-28 09:34:58 +0100 (Mo, 28 Dez 2009) | 1 line #7033: add new API function PyErr_NewExceptionWithDoc, for easily giving new exceptions a docstring. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Dec 28 09:48:24 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 28 Dec 2009 08:48:24 -0000 Subject: [Python-checkins] r77092 - python/trunk/Doc/library/optparse.rst Message-ID: Author: georg.brandl Date: Mon Dec 28 09:48:24 2009 New Revision: 77092 Log: #7404: remove reference to non-existing example files. Modified: python/trunk/Doc/library/optparse.rst Modified: python/trunk/Doc/library/optparse.rst ============================================================================== --- python/trunk/Doc/library/optparse.rst (original) +++ python/trunk/Doc/library/optparse.rst Mon Dec 28 09:48:24 2009 @@ -157,9 +157,7 @@ an option that must be supplied on the command-line; note that the phrase "required option" is self-contradictory in English. :mod:`optparse` doesn't prevent you from implementing required options, but doesn't give you much - help at it either. See ``examples/required_1.py`` and - ``examples/required_2.py`` in the :mod:`optparse` source distribution for two - ways to implement required options with :mod:`optparse`. + help at it either. For example, consider this hypothetical command-line:: From python-checkins at python.org Mon Dec 28 21:43:32 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 20:43:32 -0000 Subject: [Python-checkins] r77093 - in sandbox/trunk/2to3/lib2to3: fixes/fix_callable.py tests/test_fixers.py Message-ID: Author: benjamin.peterson Date: Mon Dec 28 21:43:32 2009 New Revision: 77093 Log: replace callable(x) with isinstance(x, collections.Callable) #7006 This is a more accurate translation than hasattr(x, '__call__') which failed in the case that somebody had put __call__ in the instance dictionary. Patch mostly by Joe Amenta. Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py (original) +++ sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py Mon Dec 28 21:43:32 2009 @@ -3,12 +3,13 @@ """Fixer for callable(). -This converts callable(obj) into hasattr(obj, '__call__').""" +This converts callable(obj) into isinstance(obj, collections.Callable), adding a +collections import if needed.""" # Local imports from .. import pytree from .. import fixer_base -from ..fixer_util import Call, Name, String +from ..fixer_util import Call, Name, String, Attr, touch_import class FixCallable(fixer_base.BaseFix): @@ -25,7 +26,10 @@ """ def transform(self, node, results): - func = results["func"] + func = results['func'] - args = [func.clone(), String(u', '), String(u"'__call__'")] - return Call(Name(u"hasattr"), args, prefix=node.prefix) + touch_import(None, u'collections', node=node) + + args = [func.clone(), String(u', ')] + args.extend(Attr(Name(u'collections'), Name(u'Callable'))) + return Call(Name(u'isinstance'), args, prefix=node.prefix) Modified: sandbox/trunk/2to3/lib2to3/tests/test_fixers.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_fixers.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Mon Dec 28 21:43:32 2009 @@ -2725,18 +2725,81 @@ def test_prefix_preservation(self): b = """callable( x)""" - a = """hasattr( x, '__call__')""" + a = """import collections\nisinstance( x, collections.Callable)""" self.check(b, a) b = """if callable(x): pass""" - a = """if hasattr(x, '__call__'): pass""" + a = """import collections +if isinstance(x, collections.Callable): pass""" self.check(b, a) def test_callable_call(self): b = """callable(x)""" - a = """hasattr(x, '__call__')""" + a = """import collections\nisinstance(x, collections.Callable)""" self.check(b, a) + def test_global_import(self): + b = """ +def spam(foo): + callable(foo)"""[1:] + a = """ +import collections +def spam(foo): + isinstance(foo, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +import collections +def spam(foo): + callable(foo)"""[1:] + # same output if it was already imported + self.check(b, a) + + b = """ +from collections import * +def spam(foo): + callable(foo)"""[1:] + a = """ +from collections import * +import collections +def spam(foo): + isinstance(foo, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +do_stuff() +do_some_other_stuff() +assert callable(do_stuff)"""[1:] + a = """ +import collections +do_stuff() +do_some_other_stuff() +assert isinstance(do_stuff, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +if isinstance(do_stuff, Callable): + assert callable(do_stuff) + do_stuff(do_stuff) + if not callable(do_stuff): + exit(1) + else: + assert callable(do_stuff) +else: + assert not callable(do_stuff)"""[1:] + a = """ +import collections +if isinstance(do_stuff, Callable): + assert isinstance(do_stuff, collections.Callable) + do_stuff(do_stuff) + if not isinstance(do_stuff, collections.Callable): + exit(1) + else: + assert isinstance(do_stuff, collections.Callable) +else: + assert not isinstance(do_stuff, collections.Callable)"""[1:] + self.check(b, a) + def test_callable_should_not_change(self): a = """callable(*x)""" self.unchanged(a) From python-checkins at python.org Mon Dec 28 21:45:13 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 20:45:13 -0000 Subject: [Python-checkins] r77094 - sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py Message-ID: Author: benjamin.peterson Date: Mon Dec 28 21:45:13 2009 New Revision: 77094 Log: deuglify field names Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py (original) +++ sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py Mon Dec 28 21:45:13 2009 @@ -7,9 +7,8 @@ collections import if needed.""" # Local imports -from .. import pytree -from .. import fixer_base -from ..fixer_util import Call, Name, String, Attr, touch_import +from lib2to3 import fixer_base +from lib2to3.fixer_util import Call, Name, String, Attr, touch_import class FixCallable(fixer_base.BaseFix): From python-checkins at python.org Mon Dec 28 21:45:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 20:45:47 -0000 Subject: [Python-checkins] r77094 - svn:log Message-ID: Author: benjamin.peterson Revision: 77094 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -deuglify field names \ No newline at end of file +deuglify imports From python-checkins at python.org Mon Dec 28 21:49:24 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 20:49:24 -0000 Subject: [Python-checkins] r77095 - sandbox/trunk/2to3/lib2to3/fixer_util.py Message-ID: Author: benjamin.peterson Date: Mon Dec 28 21:49:23 2009 New Revision: 77095 Log: remove unused flag Modified: sandbox/trunk/2to3/lib2to3/fixer_util.py Modified: sandbox/trunk/2to3/lib2to3/fixer_util.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixer_util.py (original) +++ sandbox/trunk/2to3/lib2to3/fixer_util.py Mon Dec 28 21:49:23 2009 @@ -291,8 +291,6 @@ 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 @@ -312,7 +310,6 @@ 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: @@ -324,8 +321,6 @@ import_ = FromImport(package, [Leaf(token.NAME, name, prefix=u' ')]) children = [import_, Newline()] - if add_newline_before: - children.insert(0, Newline()) root.insert_child(insert_pos, Node(syms.simple_stmt, children)) From python-checkins at python.org Mon Dec 28 21:51:18 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 20:51:18 -0000 Subject: [Python-checkins] r77096 - python/trunk/Doc/library/2to3.rst Message-ID: Author: benjamin.peterson Date: Mon Dec 28 21:51:17 2009 New Revision: 77096 Log: document new fix_callable behavior Modified: python/trunk/Doc/library/2to3.rst Modified: python/trunk/Doc/library/2to3.rst ============================================================================== --- python/trunk/Doc/library/2to3.rst (original) +++ python/trunk/Doc/library/2to3.rst Mon Dec 28 21:51:17 2009 @@ -122,7 +122,8 @@ .. 2to3fixer:: callable - Converts ``callable(x)`` to ``hasattr(x, "__call_")``. + Converts ``callable(x)`` to ``isinstance(x, collections.Callable)``, adding + an import to :mod:`collections` if needed. .. 2to3fixer:: dict From python-checkins at python.org Mon Dec 28 23:12:14 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 22:12:14 -0000 Subject: [Python-checkins] r77097 - sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py Message-ID: Author: benjamin.peterson Date: Mon Dec 28 23:12:13 2009 New Revision: 77097 Log: clean up imports and whitespace Modified: sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py Mon Dec 28 23:12:13 2009 @@ -9,11 +9,12 @@ import unittest # Local imports -from .. import pytree -from .. import refactor +from lib2to3 import refactor from . import support + class Test_all(support.TestCase): + def setUp(self): self.refactor = support.get_refactorer() From python-checkins at python.org Mon Dec 28 23:43:35 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 22:43:35 -0000 Subject: [Python-checkins] r77098 - sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Message-ID: Author: benjamin.peterson Date: Mon Dec 28 23:43:35 2009 New Revision: 77098 Log: *** empty log message *** Modified: sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_fixers.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_fixers.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Mon Dec 28 23:43:35 2009 @@ -2792,28 +2792,6 @@ if isinstance(do_stuff, Callable): assert isinstance(do_stuff, collections.Callable) do_stuff(do_stuff) - if not isinstance(do_stuff, collections.Callable): - exit(1) - else: - assert isinstance(do_stuff, collections.Callable) -else: - assert not isinstance(do_stuff, collections.Callable)"""[1:] - 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): From python-checkins at python.org Mon Dec 28 23:45:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 22:45:10 -0000 Subject: [Python-checkins] r77099 - in sandbox/trunk/2to3/lib2to3: fixer_util.py tests/test_fixers.py Message-ID: Author: benjamin.peterson Date: Mon Dec 28 23:45:10 2009 New Revision: 77099 Log: revert unintended change Modified: sandbox/trunk/2to3/lib2to3/fixer_util.py sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Modified: sandbox/trunk/2to3/lib2to3/fixer_util.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixer_util.py (original) +++ sandbox/trunk/2to3/lib2to3/fixer_util.py Mon Dec 28 23:45:10 2009 @@ -291,8 +291,6 @@ if does_tree_import(package, name, root): return - # 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): Modified: sandbox/trunk/2to3/lib2to3/tests/test_fixers.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_fixers.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Mon Dec 28 23:45:10 2009 @@ -2792,6 +2792,28 @@ if isinstance(do_stuff, Callable): assert isinstance(do_stuff, collections.Callable) do_stuff(do_stuff) + if not isinstance(do_stuff, collections.Callable): + exit(1) + else: + assert isinstance(do_stuff, collections.Callable) +else: + assert not isinstance(do_stuff, collections.Callable)"""[1:] + 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): From python-checkins at python.org Mon Dec 28 23:53:21 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 22:53:21 -0000 Subject: [Python-checkins] r77100 - sandbox/trunk/2to3/lib2to3/fixer_util.py Message-ID: Author: benjamin.peterson Date: Mon Dec 28 23:53:21 2009 New Revision: 77100 Log: revert unintended changes Modified: sandbox/trunk/2to3/lib2to3/fixer_util.py Modified: sandbox/trunk/2to3/lib2to3/fixer_util.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixer_util.py (original) +++ sandbox/trunk/2to3/lib2to3/fixer_util.py Mon Dec 28 23:53:21 2009 @@ -291,6 +291,8 @@ if does_tree_import(package, name, root): return + # 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): From python-checkins at python.org Tue Dec 29 00:46:03 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 23:46:03 -0000 Subject: [Python-checkins] r77101 - sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Message-ID: Author: benjamin.peterson Date: Tue Dec 29 00:46:02 2009 New Revision: 77101 Log: normalize whitespace Modified: sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_fixers.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_fixers.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Tue Dec 29 00:46:02 2009 @@ -2799,7 +2799,7 @@ else: assert not isinstance(do_stuff, collections.Callable)"""[1:] self.check(b, a) - + def test_callable_should_not_change(self): a = """callable(*x)""" self.unchanged(a) From solipsis at pitrou.net Tue Dec 29 00:49:32 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 29 Dec 2009 00:49:32 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r77089): sum=0 Message-ID: <20091228234932.8271117722@ns6635.ovh.net> py3k results for svn r77089 (hg cset 73329aadb23a) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog3o4h0X', '-x', 'test_httpservers'] From python-checkins at python.org Tue Dec 29 00:50:41 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 28 Dec 2009 23:50:41 -0000 Subject: [Python-checkins] r77102 - in python/trunk/Lib/lib2to3: fixer_util.py fixes/fix_callable.py main.py tests/test_all_fixers.py tests/test_fixers.py tests/test_main.py Message-ID: Author: benjamin.peterson Date: Tue Dec 29 00:50:41 2009 New Revision: 77102 Log: Merged revisions 76871-76872,77093-77095,77097-77101 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76871 | benjamin.peterson | 2009-12-17 20:49:21 -0600 (Thu, 17 Dec 2009) | 1 line handle unencodable diffs gracefully #5093 ........ r76872 | benjamin.peterson | 2009-12-17 20:51:37 -0600 (Thu, 17 Dec 2009) | 1 line fix emacs header ........ r77093 | benjamin.peterson | 2009-12-28 14:43:32 -0600 (Mon, 28 Dec 2009) | 7 lines replace callable(x) with isinstance(x, collections.Callable) #7006 This is a more accurate translation than hasattr(x, '__call__') which failed in the case that somebody had put __call__ in the instance dictionary. Patch mostly by Joe Amenta. ........ r77094 | benjamin.peterson | 2009-12-28 14:45:13 -0600 (Mon, 28 Dec 2009) | 2 lines deuglify imports ........ r77095 | benjamin.peterson | 2009-12-28 14:49:23 -0600 (Mon, 28 Dec 2009) | 1 line remove unused flag ........ r77097 | benjamin.peterson | 2009-12-28 16:12:13 -0600 (Mon, 28 Dec 2009) | 2 lines clean up imports and whitespace ........ r77098 | benjamin.peterson | 2009-12-28 16:43:35 -0600 (Mon, 28 Dec 2009) | 1 line *** empty log message *** ........ r77099 | benjamin.peterson | 2009-12-28 16:45:10 -0600 (Mon, 28 Dec 2009) | 1 line revert unintended change ........ r77100 | benjamin.peterson | 2009-12-28 16:53:21 -0600 (Mon, 28 Dec 2009) | 1 line revert unintended changes ........ r77101 | benjamin.peterson | 2009-12-28 17:46:02 -0600 (Mon, 28 Dec 2009) | 1 line normalize whitespace ........ Added: python/trunk/Lib/lib2to3/tests/test_main.py - copied unchanged from r77101, /sandbox/trunk/2to3/lib2to3/tests/test_main.py Modified: python/trunk/Lib/lib2to3/ (props changed) python/trunk/Lib/lib2to3/fixer_util.py python/trunk/Lib/lib2to3/fixes/fix_callable.py python/trunk/Lib/lib2to3/main.py python/trunk/Lib/lib2to3/tests/test_all_fixers.py python/trunk/Lib/lib2to3/tests/test_fixers.py Modified: python/trunk/Lib/lib2to3/fixer_util.py ============================================================================== --- python/trunk/Lib/lib2to3/fixer_util.py (original) +++ python/trunk/Lib/lib2to3/fixer_util.py Tue Dec 29 00:50:41 2009 @@ -291,8 +291,6 @@ 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 @@ -312,7 +310,6 @@ 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: @@ -324,8 +321,6 @@ import_ = FromImport(package, [Leaf(token.NAME, name, prefix=u' ')]) children = [import_, Newline()] - if add_newline_before: - children.insert(0, Newline()) root.insert_child(insert_pos, Node(syms.simple_stmt, children)) Modified: python/trunk/Lib/lib2to3/fixes/fix_callable.py ============================================================================== --- python/trunk/Lib/lib2to3/fixes/fix_callable.py (original) +++ python/trunk/Lib/lib2to3/fixes/fix_callable.py Tue Dec 29 00:50:41 2009 @@ -3,12 +3,12 @@ """Fixer for callable(). -This converts callable(obj) into hasattr(obj, '__call__').""" +This converts callable(obj) into isinstance(obj, collections.Callable), adding a +collections import if needed.""" # Local imports -from .. import pytree -from .. import fixer_base -from ..fixer_util import Call, Name, String +from lib2to3 import fixer_base +from lib2to3.fixer_util import Call, Name, String, Attr, touch_import class FixCallable(fixer_base.BaseFix): @@ -25,7 +25,10 @@ """ def transform(self, node, results): - func = results["func"] + func = results['func'] - args = [func.clone(), String(u', '), String(u"'__call__'")] - return Call(Name(u"hasattr"), args, prefix=node.prefix) + touch_import(None, u'collections', node=node) + + args = [func.clone(), String(u', ')] + args.extend(Attr(Name(u'collections'), Name(u'Callable'))) + return Call(Name(u'isinstance'), args, prefix=node.prefix) Modified: python/trunk/Lib/lib2to3/main.py ============================================================================== --- python/trunk/Lib/lib2to3/main.py (original) +++ python/trunk/Lib/lib2to3/main.py Tue Dec 29 00:50:41 2009 @@ -60,8 +60,14 @@ else: self.log_message("Refactored %s", filename) if self.show_diffs: - for line in diff_texts(old, new, filename): - print line + diff_lines = diff_texts(old, new, filename) + try: + for line in diff_lines: + print line + except UnicodeEncodeError: + warn("couldn't encode %s's diff for your terminal" % + (filename,)) + return def warn(msg): Modified: python/trunk/Lib/lib2to3/tests/test_all_fixers.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_all_fixers.py (original) +++ python/trunk/Lib/lib2to3/tests/test_all_fixers.py Tue Dec 29 00:50:41 2009 @@ -9,11 +9,12 @@ import unittest # Local imports -from .. import pytree -from .. import refactor +from lib2to3 import refactor from . import support + class Test_all(support.TestCase): + def setUp(self): self.refactor = support.get_refactorer() Modified: python/trunk/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_fixers.py (original) +++ python/trunk/Lib/lib2to3/tests/test_fixers.py Tue Dec 29 00:50:41 2009 @@ -2725,16 +2725,79 @@ def test_prefix_preservation(self): b = """callable( x)""" - a = """hasattr( x, '__call__')""" + a = """import collections\nisinstance( x, collections.Callable)""" self.check(b, a) b = """if callable(x): pass""" - a = """if hasattr(x, '__call__'): pass""" + a = """import collections +if isinstance(x, collections.Callable): pass""" self.check(b, a) def test_callable_call(self): b = """callable(x)""" - a = """hasattr(x, '__call__')""" + a = """import collections\nisinstance(x, collections.Callable)""" + self.check(b, a) + + def test_global_import(self): + b = """ +def spam(foo): + callable(foo)"""[1:] + a = """ +import collections +def spam(foo): + isinstance(foo, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +import collections +def spam(foo): + callable(foo)"""[1:] + # same output if it was already imported + self.check(b, a) + + b = """ +from collections import * +def spam(foo): + callable(foo)"""[1:] + a = """ +from collections import * +import collections +def spam(foo): + isinstance(foo, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +do_stuff() +do_some_other_stuff() +assert callable(do_stuff)"""[1:] + a = """ +import collections +do_stuff() +do_some_other_stuff() +assert isinstance(do_stuff, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +if isinstance(do_stuff, Callable): + assert callable(do_stuff) + do_stuff(do_stuff) + if not callable(do_stuff): + exit(1) + else: + assert callable(do_stuff) +else: + assert not callable(do_stuff)"""[1:] + a = """ +import collections +if isinstance(do_stuff, Callable): + assert isinstance(do_stuff, collections.Callable) + do_stuff(do_stuff) + if not isinstance(do_stuff, collections.Callable): + exit(1) + else: + assert isinstance(do_stuff, collections.Callable) +else: + assert not isinstance(do_stuff, collections.Callable)"""[1:] self.check(b, a) def test_callable_should_not_change(self): From python-checkins at python.org Tue Dec 29 01:06:20 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 29 Dec 2009 00:06:20 -0000 Subject: [Python-checkins] r77103 - in python/branches/py3k: Lib/lib2to3/fixer_util.py Lib/lib2to3/fixes/fix_callable.py Lib/lib2to3/main.py Lib/lib2to3/tests/test_all_fixers.py Lib/lib2to3/tests/test_fixers.py Lib/lib2to3/tests/test_main.py Message-ID: Author: benjamin.peterson Date: Tue Dec 29 01:06:20 2009 New Revision: 77103 Log: Merged revisions 77102 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r77102 | benjamin.peterson | 2009-12-28 17:50:41 -0600 (Mon, 28 Dec 2009) | 50 lines Merged revisions 76871-76872,77093-77095,77097-77101 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76871 | benjamin.peterson | 2009-12-17 20:49:21 -0600 (Thu, 17 Dec 2009) | 1 line handle unencodable diffs gracefully #5093 ........ r76872 | benjamin.peterson | 2009-12-17 20:51:37 -0600 (Thu, 17 Dec 2009) | 1 line fix emacs header ........ r77093 | benjamin.peterson | 2009-12-28 14:43:32 -0600 (Mon, 28 Dec 2009) | 7 lines replace callable(x) with isinstance(x, collections.Callable) #7006 This is a more accurate translation than hasattr(x, '__call__') which failed in the case that somebody had put __call__ in the instance dictionary. Patch mostly by Joe Amenta. ........ r77094 | benjamin.peterson | 2009-12-28 14:45:13 -0600 (Mon, 28 Dec 2009) | 2 lines deuglify imports ........ r77095 | benjamin.peterson | 2009-12-28 14:49:23 -0600 (Mon, 28 Dec 2009) | 1 line remove unused flag ........ r77097 | benjamin.peterson | 2009-12-28 16:12:13 -0600 (Mon, 28 Dec 2009) | 2 lines clean up imports and whitespace ........ r77098 | benjamin.peterson | 2009-12-28 16:43:35 -0600 (Mon, 28 Dec 2009) | 1 line *** empty log message *** ........ r77099 | benjamin.peterson | 2009-12-28 16:45:10 -0600 (Mon, 28 Dec 2009) | 1 line revert unintended change ........ r77100 | benjamin.peterson | 2009-12-28 16:53:21 -0600 (Mon, 28 Dec 2009) | 1 line revert unintended changes ........ r77101 | benjamin.peterson | 2009-12-28 17:46:02 -0600 (Mon, 28 Dec 2009) | 1 line normalize whitespace ........ ................ Added: python/branches/py3k/Lib/lib2to3/tests/test_main.py - copied, changed from r77102, /python/trunk/Lib/lib2to3/tests/test_main.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/lib2to3/fixer_util.py python/branches/py3k/Lib/lib2to3/fixes/fix_callable.py python/branches/py3k/Lib/lib2to3/main.py python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py python/branches/py3k/Lib/lib2to3/tests/test_fixers.py Modified: python/branches/py3k/Lib/lib2to3/fixer_util.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixer_util.py (original) +++ python/branches/py3k/Lib/lib2to3/fixer_util.py Tue Dec 29 01:06:20 2009 @@ -291,8 +291,6 @@ 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 @@ -312,7 +310,6 @@ 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: @@ -324,8 +321,6 @@ 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)) Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_callable.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixes/fix_callable.py (original) +++ python/branches/py3k/Lib/lib2to3/fixes/fix_callable.py Tue Dec 29 01:06:20 2009 @@ -3,12 +3,12 @@ """Fixer for callable(). -This converts callable(obj) into hasattr(obj, '__call__').""" +This converts callable(obj) into isinstance(obj, collections.Callable), adding a +collections import if needed.""" # Local imports -from .. import pytree -from .. import fixer_base -from ..fixer_util import Call, Name, String +from lib2to3 import fixer_base +from lib2to3.fixer_util import Call, Name, String, Attr, touch_import class FixCallable(fixer_base.BaseFix): @@ -25,7 +25,10 @@ """ def transform(self, node, results): - func = results["func"] + func = results['func'] - args = [func.clone(), String(', '), String("'__call__'")] - return Call(Name("hasattr"), args, prefix=node.prefix) + touch_import(None, 'collections', node=node) + + args = [func.clone(), String(', ')] + args.extend(Attr(Name('collections'), Name('Callable'))) + return Call(Name('isinstance'), args, prefix=node.prefix) Modified: python/branches/py3k/Lib/lib2to3/main.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/main.py (original) +++ python/branches/py3k/Lib/lib2to3/main.py Tue Dec 29 01:06:20 2009 @@ -60,8 +60,14 @@ else: self.log_message("Refactored %s", filename) if self.show_diffs: - for line in diff_texts(old, new, filename): - print(line) + diff_lines = diff_texts(old, new, filename) + try: + for line in diff_lines: + print(line) + except UnicodeEncodeError: + warn("couldn't encode %s's diff for your terminal" % + (filename,)) + return def warn(msg): print("WARNING: %s" % (msg,), file=sys.stderr) Modified: python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py Tue Dec 29 01:06:20 2009 @@ -9,12 +9,12 @@ import unittest # Local imports -from .. import pytree -from .. import refactor +from lib2to3 import refactor from . import support class Test_all(support.TestCase): + def setUp(self): self.refactor = support.get_refactorer() Modified: python/branches/py3k/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_fixers.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_fixers.py Tue Dec 29 01:06:20 2009 @@ -2725,16 +2725,79 @@ def test_prefix_preservation(self): b = """callable( x)""" - a = """hasattr( x, '__call__')""" + a = """import collections\nisinstance( x, collections.Callable)""" self.check(b, a) b = """if callable(x): pass""" - a = """if hasattr(x, '__call__'): pass""" + a = """import collections +if isinstance(x, collections.Callable): pass""" self.check(b, a) def test_callable_call(self): b = """callable(x)""" - a = """hasattr(x, '__call__')""" + a = """import collections\nisinstance(x, collections.Callable)""" + self.check(b, a) + + def test_global_import(self): + b = """ +def spam(foo): + callable(foo)"""[1:] + a = """ +import collections +def spam(foo): + isinstance(foo, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +import collections +def spam(foo): + callable(foo)"""[1:] + # same output if it was already imported + self.check(b, a) + + b = """ +from collections import * +def spam(foo): + callable(foo)"""[1:] + a = """ +from collections import * +import collections +def spam(foo): + isinstance(foo, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +do_stuff() +do_some_other_stuff() +assert callable(do_stuff)"""[1:] + a = """ +import collections +do_stuff() +do_some_other_stuff() +assert isinstance(do_stuff, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +if isinstance(do_stuff, Callable): + assert callable(do_stuff) + do_stuff(do_stuff) + if not callable(do_stuff): + exit(1) + else: + assert callable(do_stuff) +else: + assert not callable(do_stuff)"""[1:] + a = """ +import collections +if isinstance(do_stuff, Callable): + assert isinstance(do_stuff, collections.Callable) + do_stuff(do_stuff) + if not isinstance(do_stuff, collections.Callable): + exit(1) + else: + assert isinstance(do_stuff, collections.Callable) +else: + assert not isinstance(do_stuff, collections.Callable)"""[1:] self.check(b, a) def test_callable_should_not_change(self): Copied: python/branches/py3k/Lib/lib2to3/tests/test_main.py (from r77102, /python/trunk/Lib/lib2to3/tests/test_main.py) ============================================================================== --- /python/trunk/Lib/lib2to3/tests/test_main.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_main.py Tue Dec 29 01:06:20 2009 @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import sys import codecs -import StringIO +import io import unittest from lib2to3 import main @@ -24,10 +24,10 @@ sys.stderr = save_stderr def test_unencodable_diff(self): - input_stream = StringIO.StringIO(u"print 'nothing'\nprint u'?ber'\n") - out = StringIO.StringIO() + input_stream = io.StringIO("print 'nothing'\nprint u'?ber'\n") + out = io.StringIO() out_enc = codecs.getwriter("ascii")(out) - err = StringIO.StringIO() + err = io.StringIO() ret = self.run_2to3_capture(["-"], input_stream, out_enc, err) self.assertEqual(ret, 0) output = out.getvalue() From python-checkins at python.org Tue Dec 29 01:09:33 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 29 Dec 2009 00:09:33 -0000 Subject: [Python-checkins] r77104 - python/trunk/Lib/test/test_lib2to3.py Message-ID: Author: benjamin.peterson Date: Tue Dec 29 01:09:33 2009 New Revision: 77104 Log: enable test_main.py Modified: python/trunk/Lib/test/test_lib2to3.py Modified: python/trunk/Lib/test/test_lib2to3.py ============================================================================== --- python/trunk/Lib/test/test_lib2to3.py (original) +++ python/trunk/Lib/test/test_lib2to3.py Tue Dec 29 01:09:33 2009 @@ -1,14 +1,15 @@ # Skipping test_parser and test_all_fixers # because of running from lib2to3.tests import (test_fixers, test_pytree, test_util, test_refactor, - test_parser) + test_parser, test_main as test_main_) import unittest from test.test_support import run_unittest def suite(): tests = unittest.TestSuite() loader = unittest.TestLoader() - for m in (test_fixers, test_pytree,test_util, test_refactor, test_parser): + for m in (test_fixers, test_pytree,test_util, test_refactor, test_parser, + test_main_): tests.addTests(loader.loadTestsFromModule(m)) return tests From python-checkins at python.org Tue Dec 29 01:37:04 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 29 Dec 2009 00:37:04 -0000 Subject: [Python-checkins] r77105 - python/branches/py3k/Lib/lib2to3/tests/test_main.py Message-ID: Author: benjamin.peterson Date: Tue Dec 29 01:37:04 2009 New Revision: 77105 Log: fix test on py3 Modified: python/branches/py3k/Lib/lib2to3/tests/test_main.py Modified: python/branches/py3k/Lib/lib2to3/tests/test_main.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_main.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_main.py Tue Dec 29 01:37:04 2009 @@ -25,12 +25,12 @@ def test_unencodable_diff(self): input_stream = io.StringIO("print 'nothing'\nprint u'?ber'\n") - out = io.StringIO() + out = io.BytesIO() out_enc = codecs.getwriter("ascii")(out) err = io.StringIO() ret = self.run_2to3_capture(["-"], input_stream, out_enc, err) self.assertEqual(ret, 0) - output = out.getvalue() + output = out.getvalue().decode("ascii") self.assertTrue("-print 'nothing'" in output) self.assertTrue("WARNING: couldn't encode 's diff for " "your terminal" in err.getvalue()) From python-checkins at python.org Tue Dec 29 01:38:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 29 Dec 2009 00:38:47 -0000 Subject: [Python-checkins] r77106 - in python/branches/py3k: Lib/test/test_lib2to3.py Message-ID: Author: benjamin.peterson Date: Tue Dec 29 01:38:47 2009 New Revision: 77106 Log: Merged revisions 77104 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77104 | benjamin.peterson | 2009-12-28 18:09:33 -0600 (Mon, 28 Dec 2009) | 1 line enable test_main.py ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_lib2to3.py Modified: python/branches/py3k/Lib/test/test_lib2to3.py ============================================================================== --- python/branches/py3k/Lib/test/test_lib2to3.py (original) +++ python/branches/py3k/Lib/test/test_lib2to3.py Tue Dec 29 01:38:47 2009 @@ -1,13 +1,15 @@ # Skipping test_parser and test_all_fixers # because of running -from lib2to3.tests import test_fixers, test_pytree, test_util, test_refactor +from lib2to3.tests import (test_fixers, test_pytree, test_util, test_refactor, + test_main as test_main_) import unittest from test.support import run_unittest def suite(): tests = unittest.TestSuite() loader = unittest.TestLoader() - for m in (test_fixers,test_pytree,test_util, test_refactor): + for m in (test_fixers, test_pytree,test_util, test_refactor, + test_main_): tests.addTests(loader.loadTestsFromModule(m)) return tests From python-checkins at python.org Tue Dec 29 01:44:14 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 29 Dec 2009 00:44:14 -0000 Subject: [Python-checkins] r77107 - in python/branches/release31-maint: Lib/lib2to3/fixer_util.py Lib/lib2to3/fixes/fix_callable.py Lib/lib2to3/main.py Lib/lib2to3/tests/test_all_fixers.py Lib/lib2to3/tests/test_fixers.py Lib/lib2to3/tests/test_main.py Lib/test/test_lib2to3.py Message-ID: Author: benjamin.peterson Date: Tue Dec 29 01:44:14 2009 New Revision: 77107 Log: Merged revisions 77103,77105-77106 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77103 | benjamin.peterson | 2009-12-28 18:06:20 -0600 (Mon, 28 Dec 2009) | 57 lines Merged revisions 77102 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r77102 | benjamin.peterson | 2009-12-28 17:50:41 -0600 (Mon, 28 Dec 2009) | 50 lines Merged revisions 76871-76872,77093-77095,77097-77101 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76871 | benjamin.peterson | 2009-12-17 20:49:21 -0600 (Thu, 17 Dec 2009) | 1 line handle unencodable diffs gracefully #5093 ........ r76872 | benjamin.peterson | 2009-12-17 20:51:37 -0600 (Thu, 17 Dec 2009) | 1 line fix emacs header ........ r77093 | benjamin.peterson | 2009-12-28 14:43:32 -0600 (Mon, 28 Dec 2009) | 7 lines replace callable(x) with isinstance(x, collections.Callable) #7006 This is a more accurate translation than hasattr(x, '__call__') which failed in the case that somebody had put __call__ in the instance dictionary. Patch mostly by Joe Amenta. ........ r77094 | benjamin.peterson | 2009-12-28 14:45:13 -0600 (Mon, 28 Dec 2009) | 2 lines deuglify imports ........ r77095 | benjamin.peterson | 2009-12-28 14:49:23 -0600 (Mon, 28 Dec 2009) | 1 line remove unused flag ........ r77097 | benjamin.peterson | 2009-12-28 16:12:13 -0600 (Mon, 28 Dec 2009) | 2 lines clean up imports and whitespace ........ r77098 | benjamin.peterson | 2009-12-28 16:43:35 -0600 (Mon, 28 Dec 2009) | 1 line *** empty log message *** ........ r77099 | benjamin.peterson | 2009-12-28 16:45:10 -0600 (Mon, 28 Dec 2009) | 1 line revert unintended change ........ r77100 | benjamin.peterson | 2009-12-28 16:53:21 -0600 (Mon, 28 Dec 2009) | 1 line revert unintended changes ........ r77101 | benjamin.peterson | 2009-12-28 17:46:02 -0600 (Mon, 28 Dec 2009) | 1 line normalize whitespace ........ ................ ................ r77105 | benjamin.peterson | 2009-12-28 18:37:04 -0600 (Mon, 28 Dec 2009) | 1 line fix test on py3 ................ r77106 | benjamin.peterson | 2009-12-28 18:38:47 -0600 (Mon, 28 Dec 2009) | 9 lines Merged revisions 77104 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77104 | benjamin.peterson | 2009-12-28 18:09:33 -0600 (Mon, 28 Dec 2009) | 1 line enable test_main.py ........ ................ Added: python/branches/release31-maint/Lib/lib2to3/tests/test_main.py - copied unchanged from r77106, /python/branches/py3k/Lib/lib2to3/tests/test_main.py Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/lib2to3/fixer_util.py python/branches/release31-maint/Lib/lib2to3/fixes/fix_callable.py python/branches/release31-maint/Lib/lib2to3/main.py python/branches/release31-maint/Lib/lib2to3/tests/test_all_fixers.py python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py python/branches/release31-maint/Lib/test/test_lib2to3.py Modified: python/branches/release31-maint/Lib/lib2to3/fixer_util.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixer_util.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixer_util.py Tue Dec 29 01:44:14 2009 @@ -291,8 +291,6 @@ 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 @@ -312,7 +310,6 @@ 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: @@ -324,8 +321,6 @@ 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)) Modified: python/branches/release31-maint/Lib/lib2to3/fixes/fix_callable.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixes/fix_callable.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixes/fix_callable.py Tue Dec 29 01:44:14 2009 @@ -3,12 +3,12 @@ """Fixer for callable(). -This converts callable(obj) into hasattr(obj, '__call__').""" +This converts callable(obj) into isinstance(obj, collections.Callable), adding a +collections import if needed.""" # Local imports -from .. import pytree -from .. import fixer_base -from ..fixer_util import Call, Name, String +from lib2to3 import fixer_base +from lib2to3.fixer_util import Call, Name, String, Attr, touch_import class FixCallable(fixer_base.BaseFix): @@ -25,7 +25,10 @@ """ def transform(self, node, results): - func = results["func"] + func = results['func'] - args = [func.clone(), String(', '), String("'__call__'")] - return Call(Name("hasattr"), args, prefix=node.prefix) + touch_import(None, 'collections', node=node) + + args = [func.clone(), String(', ')] + args.extend(Attr(Name('collections'), Name('Callable'))) + return Call(Name('isinstance'), args, prefix=node.prefix) Modified: python/branches/release31-maint/Lib/lib2to3/main.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/main.py (original) +++ python/branches/release31-maint/Lib/lib2to3/main.py Tue Dec 29 01:44:14 2009 @@ -60,8 +60,14 @@ else: self.log_message("Refactored %s", filename) if self.show_diffs: - for line in diff_texts(old, new, filename): - print(line) + diff_lines = diff_texts(old, new, filename) + try: + for line in diff_lines: + print(line) + except UnicodeEncodeError: + warn("couldn't encode %s's diff for your terminal" % + (filename,)) + return def warn(msg): print("WARNING: %s" % (msg,), file=sys.stderr) Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_all_fixers.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_all_fixers.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_all_fixers.py Tue Dec 29 01:44:14 2009 @@ -9,12 +9,12 @@ import unittest # Local imports -from .. import pytree -from .. import refactor +from lib2to3 import refactor from . import support class Test_all(support.TestCase): + def setUp(self): self.refactor = support.get_refactorer() Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py Tue Dec 29 01:44:14 2009 @@ -2725,16 +2725,79 @@ def test_prefix_preservation(self): b = """callable( x)""" - a = """hasattr( x, '__call__')""" + a = """import collections\nisinstance( x, collections.Callable)""" self.check(b, a) b = """if callable(x): pass""" - a = """if hasattr(x, '__call__'): pass""" + a = """import collections +if isinstance(x, collections.Callable): pass""" self.check(b, a) def test_callable_call(self): b = """callable(x)""" - a = """hasattr(x, '__call__')""" + a = """import collections\nisinstance(x, collections.Callable)""" + self.check(b, a) + + def test_global_import(self): + b = """ +def spam(foo): + callable(foo)"""[1:] + a = """ +import collections +def spam(foo): + isinstance(foo, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +import collections +def spam(foo): + callable(foo)"""[1:] + # same output if it was already imported + self.check(b, a) + + b = """ +from collections import * +def spam(foo): + callable(foo)"""[1:] + a = """ +from collections import * +import collections +def spam(foo): + isinstance(foo, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +do_stuff() +do_some_other_stuff() +assert callable(do_stuff)"""[1:] + a = """ +import collections +do_stuff() +do_some_other_stuff() +assert isinstance(do_stuff, collections.Callable)"""[1:] + self.check(b, a) + + b = """ +if isinstance(do_stuff, Callable): + assert callable(do_stuff) + do_stuff(do_stuff) + if not callable(do_stuff): + exit(1) + else: + assert callable(do_stuff) +else: + assert not callable(do_stuff)"""[1:] + a = """ +import collections +if isinstance(do_stuff, Callable): + assert isinstance(do_stuff, collections.Callable) + do_stuff(do_stuff) + if not isinstance(do_stuff, collections.Callable): + exit(1) + else: + assert isinstance(do_stuff, collections.Callable) +else: + assert not isinstance(do_stuff, collections.Callable)"""[1:] self.check(b, a) def test_callable_should_not_change(self): Modified: python/branches/release31-maint/Lib/test/test_lib2to3.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_lib2to3.py (original) +++ python/branches/release31-maint/Lib/test/test_lib2to3.py Tue Dec 29 01:44:14 2009 @@ -1,13 +1,15 @@ # Skipping test_parser and test_all_fixers # because of running -from lib2to3.tests import test_fixers, test_pytree, test_util, test_refactor +from lib2to3.tests import (test_fixers, test_pytree, test_util, test_refactor, + test_main as test_main_) import unittest from test.support import run_unittest def suite(): tests = unittest.TestSuite() loader = unittest.TestLoader() - for m in (test_fixers,test_pytree,test_util, test_refactor): + for m in (test_fixers, test_pytree,test_util, test_refactor, + test_main_): tests.addTests(loader.loadTestsFromModule(m)) return tests From python-checkins at python.org Tue Dec 29 11:34:34 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 29 Dec 2009 10:34:34 -0000 Subject: [Python-checkins] r77108 - python/trunk/Doc/library/ctypes.rst Message-ID: Author: georg.brandl Date: Tue Dec 29 11:34:34 2009 New Revision: 77108 Log: #7569: clarification about c_char_p. Modified: python/trunk/Doc/library/ctypes.rst Modified: python/trunk/Doc/library/ctypes.rst ============================================================================== --- python/trunk/Doc/library/ctypes.rst (original) +++ python/trunk/Doc/library/ctypes.rst Tue Dec 29 11:34:34 2009 @@ -2163,8 +2163,10 @@ .. class:: c_char_p - Represents the C char \* datatype, which must be a pointer to a zero-terminated - string. The constructor accepts an integer address, or a string. + Represents the C char \* datatype when it points to a zero-terminated + string. For a general character pointer that may also point to binary data, + ``POINTER(c_char)`` must be used. The constructor accepts an integer + address, or a string. .. class:: c_double From python-checkins at python.org Tue Dec 29 12:06:31 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 29 Dec 2009 11:06:31 -0000 Subject: [Python-checkins] r77109 - python/trunk/Doc/library/ctypes.rst Message-ID: Author: georg.brandl Date: Tue Dec 29 12:06:31 2009 New Revision: 77109 Log: Improve markup of ctypes docs. Modified: python/trunk/Doc/library/ctypes.rst Modified: python/trunk/Doc/library/ctypes.rst ============================================================================== --- python/trunk/Doc/library/ctypes.rst (original) +++ python/trunk/Doc/library/ctypes.rst Tue Dec 29 12:06:31 2009 @@ -8,7 +8,7 @@ .. versionadded:: 2.5 -``ctypes`` is a foreign function library for Python. It provides C compatible +:mod:`ctypes` is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python. @@ -18,9 +18,9 @@ ctypes tutorial --------------- -Note: The code samples in this tutorial use ``doctest`` to make sure that they -actually work. Since some code samples behave differently under Linux, Windows, -or Mac OS X, they contain doctest directives in comments. +Note: The code samples in this tutorial use :mod:`doctest` to make sure that +they actually work. Since some code samples behave differently under Linux, +Windows, or Mac OS X, they contain doctest directives in comments. Note: Some code samples reference the ctypes :class:`c_int` type. This type is an alias for the :class:`c_long` type on 32-bit systems. So, you should not be @@ -33,16 +33,16 @@ Loading dynamic link libraries ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``ctypes`` exports the *cdll*, and on Windows *windll* and *oledll* +:mod:`ctypes` exports the *cdll*, and on Windows *windll* and *oledll* objects, for loading dynamic link libraries. You load libraries by accessing them as attributes of these objects. *cdll* loads libraries which export functions using the standard ``cdecl`` calling convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and -assumes the functions return a Windows :class:`HRESULT` error code. The error -code is used to automatically raise a :class:`WindowsError` exception when -the function call fails. +assumes the functions return a Windows :ctype:`HRESULT` error code. The error +code is used to automatically raise a :class:`WindowsError` exception when the +function call fails. Here are some examples for Windows. Note that ``msvcrt`` is the MS standard C library containing most standard C functions, and uses the cdecl calling @@ -112,8 +112,8 @@ respectively. Sometimes, dlls export functions with names which aren't valid Python -identifiers, like ``"??2 at YAPAXI@Z"``. In this case you have to use ``getattr`` -to retrieve the function:: +identifiers, like ``"??2 at YAPAXI@Z"``. In this case you have to use +:func:`getattr` to retrieve the function:: >>> getattr(cdll.msvcrt, "??2 at YAPAXI@Z") # doctest: +WINDOWS <_FuncPtr object at 0x...> @@ -152,8 +152,8 @@ 0x1d000000 >>> -``ctypes`` tries to protect you from calling functions with the wrong number of -arguments or the wrong calling convention. Unfortunately this only works on +:mod:`ctypes` tries to protect you from calling functions with the wrong number +of arguments or the wrong calling convention. Unfortunately this only works on Windows. It does this by examining the stack after the function returns, so although an error is raised the function *has* been called:: @@ -185,7 +185,7 @@ To find out the correct calling convention you have to look into the C header file or the documentation for the function you want to call. -On Windows, ``ctypes`` uses win32 structured exception handling to prevent +On Windows, :mod:`ctypes` uses win32 structured exception handling to prevent crashes from general protection faults when functions are called with invalid argument values:: @@ -195,18 +195,19 @@ WindowsError: exception: access violation reading 0x00000020 >>> -There are, however, enough ways to crash Python with ``ctypes``, so you should -be careful anyway. +There are, however, enough ways to crash Python with :mod:`ctypes`, so you +should be careful anyway. ``None``, integers, longs, byte strings and unicode strings are the only native Python objects that can directly be used as parameters in these function calls. ``None`` is passed as a C ``NULL`` pointer, byte strings and unicode strings are -passed as pointer to the memory block that contains their data (``char *`` or -``wchar_t *``). Python integers and Python longs are passed as the platforms -default C ``int`` type, their value is masked to fit into the C type. +passed as pointer to the memory block that contains their data (:ctype:`char *` +or :ctype:`wchar_t *`). Python integers and Python longs are passed as the +platforms default C :ctype:`int` type, their value is masked to fit into the C +type. Before we move on calling functions with other parameter types, we have to learn -more about ``ctypes`` data types. +more about :mod:`ctypes` data types. .. _ctypes-fundamental-data-types: @@ -214,49 +215,48 @@ Fundamental data types ^^^^^^^^^^^^^^^^^^^^^^ -``ctypes`` defines a number of primitive C compatible data types : - - +----------------------+--------------------------------+----------------------------+ - | ctypes type | C type | Python type | - +======================+================================+============================+ - | :class:`c_char` | ``char`` | 1-character string | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_wchar` | ``wchar_t`` | 1-character unicode string | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_byte` | ``char`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ubyte` | ``unsigned char`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_short` | ``short`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ushort` | ``unsigned short`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_int` | ``int`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_uint` | ``unsigned int`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_long` | ``long`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ulong` | ``unsigned long`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_longlong` | ``__int64`` or ``long long`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ulonglong` | ``unsigned __int64`` or | int/long | - | | ``unsigned long long`` | | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_float` | ``float`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_double` | ``double`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_longdouble`| ``long double`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_char_p` | ``char *`` (NUL terminated) | string or ``None`` | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_wchar_p` | ``wchar_t *`` (NUL terminated) | unicode or ``None`` | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_void_p` | ``void *`` | int/long or ``None`` | - +----------------------+--------------------------------+----------------------------+ +:mod:`ctypes` defines a number of primitive C compatible data types : ++----------------------+----------------------------------------+----------------------------+ +| ctypes type | C type | Python type | ++======================+========================================+============================+ +| :class:`c_char` | :ctype:`char` | 1-character string | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_wchar` | :ctype:`wchar_t` | 1-character unicode string | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_byte` | :ctype:`char` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ubyte` | :ctype:`unsigned char` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_short` | :ctype:`short` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ushort` | :ctype:`unsigned short` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_int` | :ctype:`int` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_uint` | :ctype:`unsigned int` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_long` | :ctype:`long` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ulong` | :ctype:`unsigned long` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_longlong` | :ctype:`__int64` or :ctype:`long long` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ulonglong` | :ctype:`unsigned __int64` or | int/long | +| | :ctype:`unsigned long long` | | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_float` | :ctype:`float` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_double` | :ctype:`double` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_longdouble`| :ctype:`long double` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_char_p` | :ctype:`char *` (NUL terminated) | string or ``None`` | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_wchar_p` | :ctype:`wchar_t *` (NUL terminated) | unicode or ``None`` | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_void_p` | :ctype:`void *` | int/long or ``None`` | ++----------------------+----------------------------------------+----------------------------+ All these types can be created by calling them with an optional initializer of the correct type and value:: @@ -299,7 +299,7 @@ You should be careful, however, not to pass them to functions expecting pointers to mutable memory. If you need mutable memory blocks, ctypes has a -``create_string_buffer`` function which creates these in various ways. The +:func:`create_string_buffer` function which creates these in various ways. The current memory block contents can be accessed (or changed) with the ``raw`` property; if you want to access it as NUL terminated string, use the ``value`` property:: @@ -321,10 +321,11 @@ 10 'Hi\x00lo\x00\x00\x00\x00\x00' >>> -The ``create_string_buffer`` function replaces the ``c_buffer`` function (which -is still available as an alias), as well as the ``c_string`` function from -earlier ctypes releases. To create a mutable memory block containing unicode -characters of the C type ``wchar_t`` use the ``create_unicode_buffer`` function. +The :func:`create_string_buffer` function replaces the :func:`c_buffer` function +(which is still available as an alias), as well as the :func:`c_string` function +from earlier ctypes releases. To create a mutable memory block containing +unicode characters of the C type :ctype:`wchar_t` use the +:func:`create_unicode_buffer` function. .. _ctypes-calling-functions-continued: @@ -333,8 +334,8 @@ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Note that printf prints to the real standard output channel, *not* to -``sys.stdout``, so these examples will only work at the console prompt, not from -within *IDLE* or *PythonWin*:: +:data:`sys.stdout`, so these examples will only work at the console prompt, not +from within *IDLE* or *PythonWin*:: >>> printf = libc.printf >>> printf("Hello, %s\n", "World!") @@ -353,7 +354,7 @@ >>> As has been mentioned before, all Python types except integers, strings, and -unicode strings have to be wrapped in their corresponding ``ctypes`` type, so +unicode strings have to be wrapped in their corresponding :mod:`ctypes` type, so that they can be converted to the required C data type:: >>> printf("An int %d, a double %f\n", 1234, c_double(3.14)) @@ -367,9 +368,9 @@ Calling functions with your own custom data types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can also customize ``ctypes`` argument conversion to allow instances of your -own classes be used as function arguments. ``ctypes`` looks for an -:attr:`_as_parameter_` attribute and uses this as the function argument. Of +You can also customize :mod:`ctypes` argument conversion to allow instances of +your own classes be used as function arguments. :mod:`ctypes` looks for an +:attr:`_as_parameter_` attribute and uses this as the function argument. Of course, it must be one of integer, string, or unicode:: >>> class Bottles(object): @@ -383,7 +384,7 @@ >>> If you don't want to store the instance's data in the :attr:`_as_parameter_` -instance variable, you could define a ``property`` which makes the data +instance variable, you could define a :func:`property` which makes the data available. @@ -425,7 +426,7 @@ whatever is needed to make sure this object is acceptable, and then return the object itself, its :attr:`_as_parameter_` attribute, or whatever you want to pass as the C function argument in this case. Again, the result should be an -integer, string, unicode, a ``ctypes`` instance, or an object with an +integer, string, unicode, a :mod:`ctypes` instance, or an object with an :attr:`_as_parameter_` attribute. @@ -434,9 +435,9 @@ Return types ^^^^^^^^^^^^ -By default functions are assumed to return the C ``int`` type. Other return -types can be specified by setting the :attr:`restype` attribute of the function -object. +By default functions are assumed to return the C :ctype:`int` type. Other +return types can be specified by setting the :attr:`restype` attribute of the +function object. Here is a more advanced example, it uses the ``strchr`` function, which expects a string pointer and a char, and returns a pointer to a string:: @@ -471,7 +472,7 @@ You can also use a callable Python object (a function or a class for example) as the :attr:`restype` attribute, if the foreign function returns an integer. The -callable will be called with the ``integer`` the C function returns, and the +callable will be called with the *integer* the C function returns, and the result of this call will be used as the result of your function call. This is useful to check for error return values and automatically raise an exception:: @@ -510,11 +511,11 @@ probably to write into the corresponding location, or if the data is too large to be passed by value. This is also known as *passing parameters by reference*. -``ctypes`` exports the :func:`byref` function which is used to pass parameters -by reference. The same effect can be achieved with the ``pointer`` function, -although ``pointer`` does a lot more work since it constructs a real pointer -object, so it is faster to use :func:`byref` if you don't need the pointer -object in Python itself:: +:mod:`ctypes` exports the :func:`byref` function which is used to pass +parameters by reference. The same effect can be achieved with the +:cfunc:`pointer` function, although :cfunc:`pointer` does a lot more work since +it constructs a real pointer object, so it is faster to use :func:`byref` if you +don't need the pointer object in Python itself:: >>> i = c_int() >>> f = c_float() @@ -535,16 +536,15 @@ ^^^^^^^^^^^^^^^^^^^^^ Structures and unions must derive from the :class:`Structure` and :class:`Union` -base classes which are defined in the ``ctypes`` module. Each subclass must +base classes which are defined in the :mod:`ctypes` module. Each subclass must define a :attr:`_fields_` attribute. :attr:`_fields_` must be a list of *2-tuples*, containing a *field name* and a *field type*. -The field type must be a ``ctypes`` type like :class:`c_int`, or any other -derived ``ctypes`` type: structure, union, array, pointer. +The field type must be a :mod:`ctypes` type like :class:`c_int`, or any other +derived :mod:`ctypes` type: structure, union, array, pointer. Here is a simple example of a POINT structure, which contains two integers named -``x`` and ``y``, and also shows how to initialize a structure in the -constructor:: +*x* and *y*, and also shows how to initialize a structure in the constructor:: >>> from ctypes import * >>> class POINT(Structure): @@ -566,8 +566,8 @@ You can, however, build much more complicated structures. Structures can itself contain other structures by using a structure as a field type. -Here is a RECT structure which contains two POINTs named ``upperleft`` and -``lowerright`` :: +Here is a RECT structure which contains two POINTs named *upperleft* and +*lowerright*:: >>> class RECT(Structure): ... _fields_ = [("upperleft", POINT), @@ -606,10 +606,11 @@ positive integer and specifies the maximum alignment for the fields. This is what ``#pragma pack(n)`` also does in MSVC. -``ctypes`` uses the native byte order for Structures and Unions. To build +:mod:`ctypes` uses the native byte order for Structures and Unions. To build structures with non-native byte order, you can use one of the -BigEndianStructure, LittleEndianStructure, BigEndianUnion, and LittleEndianUnion -base classes. These classes cannot contain pointer fields. +:class:`BigEndianStructure`, :class:`LittleEndianStructure`, +:class:`BigEndianUnion`, and :class:`LittleEndianUnion` base classes. These +classes cannot contain pointer fields. .. _ctypes-bit-fields-in-structures-unions: @@ -687,22 +688,22 @@ Pointers ^^^^^^^^ -Pointer instances are created by calling the ``pointer`` function on a -``ctypes`` type:: +Pointer instances are created by calling the :func:`pointer` function on a +:mod:`ctypes` type:: >>> from ctypes import * >>> i = c_int(42) >>> pi = pointer(i) >>> -Pointer instances have a ``contents`` attribute which returns the object to +Pointer instances have a :attr:`contents` attribute which returns the object to which the pointer points, the ``i`` object above:: >>> pi.contents c_long(42) >>> -Note that ``ctypes`` does not have OOR (original object return), it constructs a +Note that :mod:`ctypes` does not have OOR (original object return), it constructs a new, equivalent object each time you retrieve an attribute:: >>> pi.contents is i @@ -720,7 +721,8 @@ c_long(99) >>> -.. XXX Document dereferencing pointers, and that it is preferred over the .contents attribute. +.. XXX Document dereferencing pointers, and that it is preferred over the + .contents attribute. Pointer instances can also be indexed with integers:: @@ -743,10 +745,10 @@ and you *know* that the pointer actually points to an array instead of a single item. -Behind the scenes, the ``pointer`` function does more than simply create pointer -instances, it has to create pointer *types* first. This is done with the -``POINTER`` function, which accepts any ``ctypes`` type, and returns a new -type:: +Behind the scenes, the :func:`pointer` function does more than simply create +pointer instances, it has to create pointer *types* first. This is done with +the :func:`POINTER` function, which accepts any :mod:`ctypes` type, and returns +a new type:: >>> PI = POINTER(c_int) >>> PI @@ -767,7 +769,7 @@ False >>> -``ctypes`` checks for ``NULL`` when dereferencing pointers (but dereferencing +:mod:`ctypes` checks for ``NULL`` when dereferencing pointers (but dereferencing invalid non-\ ``NULL`` pointers would crash Python):: >>> null_ptr[0] @@ -816,8 +818,8 @@ .. XXX list other conversions... -Sometimes you have instances of incompatible types. In C, you can cast one -type into another type. ``ctypes`` provides a ``cast`` function which can be +Sometimes you have instances of incompatible types. In C, you can cast one type +into another type. :mod:`ctypes` provides a :func:`cast` function which can be used in the same way. The ``Bar`` structure defined above accepts ``POINTER(c_int)`` pointers or :class:`c_int` arrays for its ``values`` field, but not instances of other types:: @@ -828,20 +830,20 @@ TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance >>> -For these cases, the ``cast`` function is handy. +For these cases, the :func:`cast` function is handy. -The ``cast`` function can be used to cast a ctypes instance into a pointer to a -different ctypes data type. ``cast`` takes two parameters, a ctypes object that -is or can be converted to a pointer of some kind, and a ctypes pointer type. It -returns an instance of the second argument, which references the same memory -block as the first argument:: +The :func:`cast` function can be used to cast a ctypes instance into a pointer +to a different ctypes data type. :func:`cast` takes two parameters, a ctypes +object that is or can be converted to a pointer of some kind, and a ctypes +pointer type. It returns an instance of the second argument, which references +the same memory block as the first argument:: >>> a = (c_byte * 4)() >>> cast(a, POINTER(c_int)) >>> -So, ``cast`` can be used to assign to the ``values`` field of ``Bar`` the +So, :func:`cast` can be used to assign to the ``values`` field of ``Bar`` the structure:: >>> bar = Bar() @@ -881,7 +883,7 @@ >>> because the new ``class cell`` is not available in the class statement itself. -In ``ctypes``, we can define the ``cell`` class and set the :attr:`_fields_` +In :mod:`ctypes`, we can define the ``cell`` class and set the :attr:`_fields_` attribute later, after the class statement:: >>> from ctypes import * @@ -915,7 +917,7 @@ Callback functions ^^^^^^^^^^^^^^^^^^ -``ctypes`` allows to create C callable function pointers from Python callables. +:mod:`ctypes` allows to create C callable function pointers from Python callables. These are sometimes called *callback functions*. First, you must create a class for the callback function, the class knows the @@ -1064,7 +1066,7 @@ **Important note for callback functions:** Make sure you keep references to CFUNCTYPE objects as long as they are used from -C code. ``ctypes`` doesn't, and if you don't, they may be garbage collected, +C code. :mod:`ctypes` doesn't, and if you don't, they may be garbage collected, crashing your program when a callback is made. @@ -1078,7 +1080,7 @@ to 0, 1, or 2, depending on the :option:`-O` or :option:`-OO` flag given on startup. -``ctypes`` can access values like this with the :meth:`in_dll` class methods of +:mod:`ctypes` can access values like this with the :meth:`in_dll` class methods of the type. *pythonapi* is a predefined symbol giving access to the Python C api:: @@ -1101,7 +1103,7 @@ frozen modules.* So manipulating this pointer could even prove useful. To restrict the example -size, we show only how this table can be read with ``ctypes``:: +size, we show only how this table can be read with :mod:`ctypes`:: >>> from ctypes import * >>> @@ -1146,7 +1148,7 @@ Surprises ^^^^^^^^^ -There are some edges in ``ctypes`` where you may be expect something else than +There are some edges in :mod:`ctypes` where you may be expect something else than what actually happens. Consider the following example:: @@ -1209,13 +1211,13 @@ Variable-sized data types ^^^^^^^^^^^^^^^^^^^^^^^^^ -``ctypes`` provides some support for variable-sized arrays and structures. +:mod:`ctypes` provides some support for variable-sized arrays and structures. -The ``resize`` function can be used to resize the memory buffer of an existing -ctypes object. The function takes the object as first argument, and the -requested size in bytes as the second argument. The memory block cannot be made -smaller than the natural memory block specified by the objects type, a -``ValueError`` is raised if this is tried:: +The :func:`resize` function can be used to resize the memory buffer of an +existing ctypes object. The function takes the object as first argument, and +the requested size in bytes as the second argument. The memory block cannot be +made smaller than the natural memory block specified by the objects type, a +:exc:`ValueError` is raised if this is tried:: >>> short_array = (c_short * 4)() >>> print sizeof(short_array) @@ -1243,7 +1245,7 @@ IndexError: invalid index >>> -Another way to use variable-sized data types with ``ctypes`` is to use the +Another way to use variable-sized data types with :mod:`ctypes` is to use the dynamic nature of Python, and (re-)define the data type after the required size is already known, on a case by case basis. @@ -1262,12 +1264,12 @@ When programming in a compiled language, shared libraries are accessed when compiling/linking a program, and when the program is run. -The purpose of the ``find_library`` function is to locate a library in a way +The purpose of the :func:`find_library` function is to locate a library in a way similar to what the compiler does (on platforms with several versions of a shared library the most recent should be loaded), while the ctypes library loaders act like when a program is run, and call the runtime loader directly. -The ``ctypes.util`` module provides a function which can help to determine the +The :mod:`ctypes.util` module provides a function which can help to determine the library to load. @@ -1282,9 +1284,9 @@ The exact functionality is system dependent. -On Linux, ``find_library`` tries to run external programs (/sbin/ldconfig, gcc, -and objdump) to find the library file. It returns the filename of the library -file. Here are some examples:: +On Linux, :func:`find_library` tries to run external programs +(``/sbin/ldconfig``, ``gcc``, and ``objdump``) to find the library file. It +returns the filename of the library file. Here are some examples:: >>> from ctypes.util import find_library >>> find_library("m") @@ -1295,8 +1297,8 @@ 'libbz2.so.1.0' >>> -On OS X, ``find_library`` tries several predefined naming schemes and paths to -locate the library, and returns a full pathname if successful:: +On OS X, :func:`find_library` tries several predefined naming schemes and paths +to locate the library, and returns a full pathname if successful:: >>> from ctypes.util import find_library >>> find_library("c") @@ -1309,13 +1311,13 @@ '/System/Library/Frameworks/AGL.framework/AGL' >>> -On Windows, ``find_library`` searches along the system search path, and returns -the full pathname, but since there is no predefined naming scheme a call like -``find_library("c")`` will fail and return ``None``. +On Windows, :func:`find_library` searches along the system search path, and +returns the full pathname, but since there is no predefined naming scheme a call +like ``find_library("c")`` will fail and return ``None``. -If wrapping a shared library with ``ctypes``, it *may* be better to determine +If wrapping a shared library with :mod:`ctypes`, it *may* be better to determine the shared library name at development type, and hardcode that into the wrapper -module instead of using ``find_library`` to locate the library at runtime. +module instead of using :func:`find_library` to locate the library at runtime. .. _ctypes-loading-shared-libraries: @@ -1331,7 +1333,7 @@ Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return - ``int``. + :ctype:`int`. .. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False) @@ -1348,7 +1350,7 @@ Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the ``stdcall`` calling convention, and are - assumed to return ``int`` by default. + assumed to return :ctype:`int` by default. On Windows CE only the standard calling convention is used, for convenience the :class:`WinDLL` and :class:`OleDLL` use the standard calling convention on this @@ -1370,12 +1372,13 @@ All these classes can be instantiated by calling them with at least one argument, the pathname of the shared library. If you have an existing handle to an already loaded shared library, it can be passed as the ``handle`` named -parameter, otherwise the underlying platforms ``dlopen`` or :meth:`LoadLibrary` +parameter, otherwise the underlying platforms ``dlopen`` or ``LoadLibrary`` function is used to load the library into the process, and to get a handle to it. The *mode* parameter can be used to specify how the library is loaded. For -details, consult the ``dlopen(3)`` manpage, on Windows, *mode* is ignored. +details, consult the :manpage:`dlopen(3)` manpage, on Windows, *mode* is +ignored. The *use_errno* parameter, when set to True, enables a ctypes mechanism that allows to access the system :data:`errno` error number in a safe way. @@ -1395,8 +1398,7 @@ copy of the windows error code. .. versionadded:: 2.6 - The ``use_last_error`` and ``use_errno`` optional parameters - were added. + The *use_last_error* and *use_errno* optional parameters were added. .. data:: RTLD_GLOBAL :noindex: @@ -1445,7 +1447,7 @@ .. class:: LibraryLoader(dlltype) - Class which loads shared libraries. ``dlltype`` should be one of the + Class which loads shared libraries. *dlltype* should be one of the :class:`CDLL`, :class:`PyDLL`, :class:`WinDLL`, or :class:`OleDLL` types. :meth:`__getattr__` has special behavior: It allows to load a shared library by @@ -1491,10 +1493,10 @@ .. data:: pythonapi :noindex: - An instance of :class:`PyDLL` that exposes Python C api functions as attributes. - Note that all these functions are assumed to return C ``int``, which is of - course not always the truth, so you have to assign the correct :attr:`restype` - attribute to use these functions. + An instance of :class:`PyDLL` that exposes Python C API functions as + attributes. Note that all these functions are assumed to return C + :ctype:`int`, which is of course not always the truth, so you have to assign + the correct :attr:`restype` attribute to use these functions. .. _ctypes-foreign-functions: @@ -1523,11 +1525,11 @@ .. attribute:: restype Assign a ctypes type to specify the result type of the foreign function. - Use ``None`` for ``void`` a function not returning anything. + Use ``None`` for :ctype:`void`, a function not returning anything. It is possible to assign a callable Python object that is not a ctypes - type, in this case the function is assumed to return a C ``int``, and the - callable will be called with this integer, allowing to do further + type, in this case the function is assumed to return a C :ctype:`int`, and + the callable will be called with this integer, allowing to do further processing or error checking. Using this is deprecated, for more flexible post processing or error checking use a ctypes data type as :attr:`restype` and assign a callable to the :attr:`errcheck` attribute. @@ -1562,16 +1564,16 @@ .. function:: callable(result, func, arguments) :noindex: - ``result`` is what the foreign function returns, as specified - by the :attr:`restype` attribute. + *result* is what the foreign function returns, as specified by the + :attr:`restype` attribute. - ``func`` is the foreign function object itself, this allows - to reuse the same callable object to check or post process - the results of several functions. - - ``arguments`` is a tuple containing the parameters originally - passed to the function call, this allows to specialize the - behavior on the arguments used. + *func* is the foreign function object itself, this allows to reuse the + same callable object to check or post process the results of several + functions. + + *arguments* is a tuple containing the parameters originally passed to + the function call, this allows to specialize the behavior on the + arguments used. The object that this function returns will be returned from the foreign function call, but it can also check the result value @@ -1638,14 +1640,14 @@ :noindex: :module: - Create a C callable function (a callback function) from a Python ``callable``. + Create a C callable function (a callback function) from a Python *callable*. .. function:: prototype(func_spec[, paramflags]) :noindex: :module: - Returns a foreign function exported by a shared library. ``func_spec`` must be a + Returns a foreign function exported by a shared library. *func_spec* must be a 2-tuple ``(name_or_ordinal, library)``. The first item is the name of the exported function as string, or the ordinal of the exported function as small integer. The second item is the shared library instance. @@ -1655,7 +1657,7 @@ :noindex: :module: - Returns a foreign function that will call a COM method. ``vtbl_index`` is the + Returns a foreign function that will call a COM method. *vtbl_index* is the index into the virtual function table, a small non-negative integer. *name* is name of the COM method. *iid* is an optional pointer to the interface identifier which is used in extended error reporting. @@ -1700,7 +1702,7 @@ LPCSTR lpCaption, UINT uType); -Here is the wrapping with ``ctypes``:: +Here is the wrapping with :mod:`ctypes`:: >>> from ctypes import c_int, WINFUNCTYPE, windll >>> from ctypes.wintypes import HWND, LPCSTR, UINT @@ -1725,7 +1727,7 @@ HWND hWnd, LPRECT lpRect); -Here is the wrapping with ``ctypes``:: +Here is the wrapping with :mod:`ctypes`:: >>> from ctypes import POINTER, WINFUNCTYPE, windll, WinError >>> from ctypes.wintypes import BOOL, HWND, RECT @@ -1753,7 +1755,7 @@ >>> If the :attr:`errcheck` function returns the argument tuple it receives -unchanged, ``ctypes`` continues the normal processing it does on the output +unchanged, :mod:`ctypes` continues the normal processing it does on the output parameters. If you want to return a tuple of window coordinates instead of a ``RECT`` instance, you can retrieve the fields in the function and return them instead, the normal processing will no longer take place:: @@ -1776,21 +1778,21 @@ .. function:: addressof(obj) - Returns the address of the memory buffer as integer. ``obj`` must be an + Returns the address of the memory buffer as integer. *obj* must be an instance of a ctypes type. .. function:: alignment(obj_or_type) - Returns the alignment requirements of a ctypes type. ``obj_or_type`` must be a + Returns the alignment requirements of a ctypes type. *obj_or_type* must be a ctypes type or instance. .. function:: byref(obj[, offset]) - Returns a light-weight pointer to ``obj``, which must be an - instance of a ctypes type. ``offset`` defaults to zero, and must be - an integer that will be added to the internal pointer value. + Returns a light-weight pointer to *obj*, which must be an instance of a + ctypes type. *offset* defaults to zero, and must be an integer that will be + added to the internal pointer value. ``byref(obj, offset)`` corresponds to this C code:: @@ -1801,14 +1803,15 @@ construction is a lot faster. .. versionadded:: 2.6 - The ``offset`` optional argument was added. + The *offset* optional argument was added. + .. function:: cast(obj, type) - This function is similar to the cast operator in C. It returns a new instance of - ``type`` which points to the same memory block as ``obj``. ``type`` must be a - pointer type, and ``obj`` must be an object that can be interpreted as a - pointer. + This function is similar to the cast operator in C. It returns a new + instance of *type* which points to the same memory block as *obj*. *type* + must be a pointer type, and *obj* must be an object that can be interpreted + as a pointer. .. function:: create_string_buffer(init_or_size[, size]) @@ -1816,7 +1819,7 @@ This function creates a mutable character buffer. The returned object is a ctypes array of :class:`c_char`. - ``init_or_size`` must be an integer which specifies the size of the array, or a + *init_or_size* must be an integer which specifies the size of the array, or a string which will be used to initialize the array items. If a string is specified as first argument, the buffer is made one item larger @@ -1833,7 +1836,7 @@ This function creates a mutable unicode character buffer. The returned object is a ctypes array of :class:`c_wchar`. - ``init_or_size`` must be an integer which specifies the size of the array, or a + *init_or_size* must be an integer which specifies the size of the array, or a unicode string which will be used to initialize the array items. If a unicode string is specified as first argument, the buffer is made one item @@ -1848,16 +1851,17 @@ .. function:: DllCanUnloadNow() - Windows only: This function is a hook which allows to implement in-process COM - servers with ctypes. It is called from the DllCanUnloadNow function that the - _ctypes extension dll exports. + Windows only: This function is a hook which allows to implement in-process + COM servers with ctypes. It is called from the DllCanUnloadNow function that + the _ctypes extension dll exports. .. function:: DllGetClassObject() - Windows only: This function is a hook which allows to implement in-process COM - servers with ctypes. It is called from the DllGetClassObject function that the - ``_ctypes`` extension dll exports. + Windows only: This function is a hook which allows to implement in-process + COM servers with ctypes. It is called from the DllGetClassObject function + that the ``_ctypes`` extension dll exports. + .. function:: find_library(name) :module: ctypes.util @@ -1870,28 +1874,29 @@ The exact functionality is system dependent. .. versionchanged:: 2.6 - Windows only: ``find_library("m")`` or - ``find_library("c")`` return the result of a call to - ``find_msvcrt()``. + Windows only: ``find_library("m")`` or ``find_library("c")`` return the + result of a call to ``find_msvcrt()``. + .. function:: find_msvcrt() :module: ctypes.util - Windows only: return the filename of the VC runtype library used - by Python, and by the extension modules. If the name of the - library cannot be determined, ``None`` is returned. - - If you need to free memory, for example, allocated by an extension - module with a call to the ``free(void *)``, it is important that you - use the function in the same library that allocated the memory. + Windows only: return the filename of the VC runtype library used by Python, + and by the extension modules. If the name of the library cannot be + determined, ``None`` is returned. + + If you need to free memory, for example, allocated by an extension module + with a call to the ``free(void *)``, it is important that you use the + function in the same library that allocated the memory. .. versionadded:: 2.6 + .. function:: FormatError([code]) - Windows only: Returns a textual description of the error code. If no error code - is specified, the last error code is used by calling the Windows api function - GetLastError. + Windows only: Returns a textual description of the error code *code*. If no + error code is specified, the last error code is used by calling the Windows + api function GetLastError. .. function:: GetLastError() @@ -1917,8 +1922,8 @@ .. function:: memmove(dst, src, count) Same as the standard C memmove library function: copies *count* bytes from - ``src`` to *dst*. *dst* and ``src`` must be integers or ctypes instances that - can be converted to pointers. + *src* to *dst*. *dst* and *src* must be integers or ctypes instances that can + be converted to pointers. .. function:: memset(dst, c, count) @@ -1932,13 +1937,13 @@ This factory function creates and returns a new ctypes pointer type. Pointer types are cached an reused internally, so calling this function repeatedly is - cheap. type must be a ctypes type. + cheap. *type* must be a ctypes type. .. function:: pointer(obj) - This function creates a new pointer instance, pointing to ``obj``. The returned - object is of the type POINTER(type(obj)). + This function creates a new pointer instance, pointing to *obj*. The returned + object is of the type ``POINTER(type(obj))``. Note: If you just want to pass a pointer to an object to a foreign function call, you should use ``byref(obj)`` which is much faster. @@ -1946,23 +1951,23 @@ .. function:: resize(obj, size) - This function resizes the internal memory buffer of obj, which must be an - instance of a ctypes type. It is not possible to make the buffer smaller than - the native size of the objects type, as given by sizeof(type(obj)), but it is - possible to enlarge the buffer. + This function resizes the internal memory buffer of *obj*, which must be an + instance of a ctypes type. It is not possible to make the buffer smaller + than the native size of the objects type, as given by ``sizeof(type(obj))``, + but it is possible to enlarge the buffer. .. function:: set_conversion_mode(encoding, errors) This function sets the rules that ctypes objects use when converting between - 8-bit strings and unicode strings. encoding must be a string specifying an - encoding, like ``'utf-8'`` or ``'mbcs'``, errors must be a string specifying the - error handling on encoding/decoding errors. Examples of possible values are - ``"strict"``, ``"replace"``, or ``"ignore"``. - - ``set_conversion_mode`` returns a 2-tuple containing the previous conversion - rules. On windows, the initial conversion rules are ``('mbcs', 'ignore')``, on - other systems ``('ascii', 'strict')``. + 8-bit strings and unicode strings. *encoding* must be a string specifying an + encoding, like ``'utf-8'`` or ``'mbcs'``, *errors* must be a string + specifying the error handling on encoding/decoding errors. Examples of + possible values are ``"strict"``, ``"replace"``, or ``"ignore"``. + + :func:`set_conversion_mode` returns a 2-tuple containing the previous + conversion rules. On windows, the initial conversion rules are ``('mbcs', + 'ignore')``, on other systems ``('ascii', 'strict')``. .. function:: set_errno(value) @@ -1972,6 +1977,7 @@ .. versionadded:: 2.6 + .. function:: set_last_error(value) Windows only: set the current value of the ctypes-private copy of the system @@ -1980,6 +1986,7 @@ .. versionadded:: 2.6 + .. function:: sizeof(obj_or_type) Returns the size in bytes of a ctypes type or instance memory buffer. Does the @@ -1995,17 +2002,17 @@ .. function:: WinError(code=None, descr=None) - Windows only: this function is probably the worst-named thing in ctypes. It - creates an instance of WindowsError. If *code* is not specified, - ``GetLastError`` is called to determine the error code. If ``descr`` is not + Windows only: this function is probably the worst-named thing in ctypes. It + creates an instance of WindowsError. If *code* is not specified, + ``GetLastError`` is called to determine the error code. If ``descr`` is not specified, :func:`FormatError` is called to get a textual description of the error. -.. function:: wstring_at(address) +.. function:: wstring_at(address[, size]) This function returns the wide character string starting at memory address - ``address`` as unicode string. If ``size`` is specified, it is used as the + *address* as unicode string. If *size* is specified, it is used as the number of characters of the string, otherwise the string is assumed to be zero-terminated. @@ -2018,12 +2025,12 @@ .. class:: _CData - This non-public class is the common base class of all ctypes data types. Among - other things, all ctypes type instances contain a memory block that hold C - compatible data; the address of the memory block is returned by the - ``addressof()`` helper function. Another instance variable is exposed as - :attr:`_objects`; this contains other Python objects that need to be kept alive - in case the memory block contains pointers. + This non-public class is the common base class of all ctypes data types. + Among other things, all ctypes type instances contain a memory block that + hold C compatible data; the address of the memory block is returned by the + :func:`addressof` helper function. Another instance variable is exposed as + :attr:`_objects`; this contains other Python objects that need to be kept + alive in case the memory block contains pointers. Common methods of ctypes data types, these are all class methods (to be exact, they are methods of the :term:`metaclass`): @@ -2031,22 +2038,22 @@ .. method:: _CData.from_buffer(source[, offset]) - This method returns a ctypes instance that shares the buffer of - the ``source`` object. The ``source`` object must support the - writeable buffer interface. The optional ``offset`` parameter - specifies an offset into the source buffer in bytes; the default - is zero. If the source buffer is not large enough a ValueError - is raised. + This method returns a ctypes instance that shares the buffer of the + *source* object. The *source* object must support the writeable buffer + interface. The optional *offset* parameter specifies an offset into the + source buffer in bytes; the default is zero. If the source buffer is not + large enough a :exc:`ValueError` is raised. .. versionadded:: 2.6 + .. method:: _CData.from_buffer_copy(source[, offset]) - This method creates a ctypes instance, copying the buffer from - the source object buffer which must be readable. The optional - ``offset`` parameter specifies an offset into the source buffer - in bytes; the default is zero. If the source buffer is not - large enough a ValueError is raised. + This method creates a ctypes instance, copying the buffer from the + *source* object buffer which must be readable. The optional *offset* + parameter specifies an offset into the source buffer in bytes; the default + is zero. If the source buffer is not large enough a :exc:`ValueError` is + raised. .. versionadded:: 2.6 @@ -2054,7 +2061,7 @@ .. method:: from_address(address) This method returns a ctypes type instance using the memory specified by - address which must be an integer. + *address* which must be an integer. .. method:: from_param(obj) @@ -2065,7 +2072,7 @@ can be used as a function call parameter. All ctypes data types have a default implementation of this classmethod - that normally returns ``obj`` if that is an instance of the type. Some + that normally returns *obj* if that is an instance of the type. Some types accept other objects as well. @@ -2078,7 +2085,6 @@ Common instance variables of ctypes data types: - .. attribute:: _b_base_ Sometimes ctypes data instances do not own the memory block they contain, @@ -2109,18 +2115,17 @@ .. class:: _SimpleCData - This non-public class is the base class of all fundamental ctypes data types. It - is mentioned here because it contains the common attributes of the fundamental - ctypes data types. ``_SimpleCData`` is a subclass of ``_CData``, so it inherits - their methods and attributes. + This non-public class is the base class of all fundamental ctypes data + types. It is mentioned here because it contains the common attributes of the + fundamental ctypes data types. :class:`_SimpleCData` is a subclass of + :class:`_CData`, so it inherits their methods and attributes. .. versionchanged:: 2.6 - ctypes data types that are not and do not contain pointers can - now be pickled. + ctypes data types that are not and do not contain pointers can now be + pickled. Instances have a single attribute: - .. attribute:: value This attribute contains the actual value of the instance. For integer and @@ -2129,10 +2134,11 @@ unicode string. When the ``value`` attribute is retrieved from a ctypes instance, usually - a new object is returned each time. ``ctypes`` does *not* implement + a new object is returned each time. :mod:`ctypes` does *not* implement original object return, always a new object is constructed. The same is true for all other ctypes object instances. + Fundamental data types, when returned as foreign function call results, or, for example, by retrieving structure field members or array items, are transparently converted to native Python types. In other words, if a foreign function has a @@ -2146,24 +2152,23 @@ These are the fundamental ctypes data types: - .. class:: c_byte - Represents the C signed char datatype, and interprets the value as small - integer. The constructor accepts an optional integer initializer; no overflow - checking is done. + Represents the C :ctype:`signed char` datatype, and interprets the value as + small integer. The constructor accepts an optional integer initializer; no + overflow checking is done. .. class:: c_char - Represents the C char datatype, and interprets the value as a single character. - The constructor accepts an optional string initializer, the length of the string - must be exactly one character. + Represents the C :ctype:`char` datatype, and interprets the value as a single + character. The constructor accepts an optional string initializer, the + length of the string must be exactly one character. .. class:: c_char_p - Represents the C char \* datatype when it points to a zero-terminated + Represents the C :ctype:`char *` datatype when it points to a zero-terminated string. For a general character pointer that may also point to binary data, ``POINTER(c_char)`` must be used. The constructor accepts an integer address, or a string. @@ -2171,177 +2176,177 @@ .. class:: c_double - Represents the C double datatype. The constructor accepts an optional float - initializer. + Represents the C :ctype:`double` datatype. The constructor accepts an + optional float initializer. .. class:: c_longdouble - Represents the C long double datatype. The constructor accepts an - optional float initializer. On platforms where ``sizeof(long - double) == sizeof(double)`` it is an alias to :class:`c_double`. + Represents the C :ctype:`long double` datatype. The constructor accepts an + optional float initializer. On platforms where ``sizeof(long double) == + sizeof(double)`` it is an alias to :class:`c_double`. .. versionadded:: 2.6 .. class:: c_float - Represents the C float datatype. The constructor accepts an optional float - initializer. + Represents the C :ctype:`float` datatype. The constructor accepts an + optional float initializer. .. class:: c_int - Represents the C signed int datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. On platforms where - ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`. + Represents the C :ctype:`signed int` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. On platforms + where ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`. .. class:: c_int8 - Represents the C 8-bit ``signed int`` datatype. Usually an alias for + Represents the C 8-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_byte`. .. class:: c_int16 - Represents the C 16-bit signed int datatype. Usually an alias for + Represents the C 16-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_short`. .. class:: c_int32 - Represents the C 32-bit signed int datatype. Usually an alias for + Represents the C 32-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_int`. .. class:: c_int64 - Represents the C 64-bit ``signed int`` datatype. Usually an alias for + Represents the C 64-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_longlong`. .. class:: c_long - Represents the C ``signed long`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`signed long` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_longlong - Represents the C ``signed long long`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`signed long long` datatype. The constructor accepts + an optional integer initializer; no overflow checking is done. .. class:: c_short - Represents the C ``signed short`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`signed short` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_size_t - Represents the C ``size_t`` datatype. + Represents the C :ctype:`size_t` datatype. .. class:: c_ubyte - Represents the C ``unsigned char`` datatype, it interprets the value as small - integer. The constructor accepts an optional integer initializer; no overflow - checking is done. + Represents the C :ctype:`unsigned char` datatype, it interprets the value as + small integer. The constructor accepts an optional integer initializer; no + overflow checking is done. .. class:: c_uint - Represents the C ``unsigned int`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. On platforms where - ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`. + Represents the C :ctype:`unsigned int` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. On platforms + where ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`. .. class:: c_uint8 - Represents the C 8-bit unsigned int datatype. Usually an alias for + Represents the C 8-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ubyte`. .. class:: c_uint16 - Represents the C 16-bit unsigned int datatype. Usually an alias for + Represents the C 16-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ushort`. .. class:: c_uint32 - Represents the C 32-bit unsigned int datatype. Usually an alias for + Represents the C 32-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_uint`. .. class:: c_uint64 - Represents the C 64-bit unsigned int datatype. Usually an alias for + Represents the C 64-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ulonglong`. .. class:: c_ulong - Represents the C ``unsigned long`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned long` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_ulonglong - Represents the C ``unsigned long long`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned long long` datatype. The constructor + accepts an optional integer initializer; no overflow checking is done. .. class:: c_ushort - Represents the C ``unsigned short`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned short` datatype. The constructor accepts + an optional integer initializer; no overflow checking is done. .. class:: c_void_p - Represents the C ``void *`` type. The value is represented as integer. The - constructor accepts an optional integer initializer. + Represents the C :ctype:`void *` type. The value is represented as integer. + The constructor accepts an optional integer initializer. .. class:: c_wchar - Represents the C ``wchar_t`` datatype, and interprets the value as a single - character unicode string. The constructor accepts an optional string + Represents the C :ctype:`wchar_t` datatype, and interprets the value as a + single character unicode string. The constructor accepts an optional string initializer, the length of the string must be exactly one character. .. class:: c_wchar_p - Represents the C ``wchar_t *`` datatype, which must be a pointer to a - zero-terminated wide character string. The constructor accepts an integer + Represents the C :ctype:`wchar_t *` datatype, which must be a pointer to a + zero-terminated wide character string. The constructor accepts an integer address, or a string. .. class:: c_bool - Represent the C ``bool`` datatype (more accurately, _Bool from C99). Its value - can be True or False, and the constructor accepts any object that has a truth - value. + Represent the C :ctype:`bool` datatype (more accurately, :ctype:`_Bool` from + C99). Its value can be True or False, and the constructor accepts any object + that has a truth value. .. versionadded:: 2.6 .. class:: HRESULT - Windows only: Represents a :class:`HRESULT` value, which contains success or + Windows only: Represents a :ctype:`HRESULT` value, which contains success or error information for a function or method call. .. class:: py_object - Represents the C ``PyObject *`` datatype. Calling this without an argument - creates a ``NULL`` ``PyObject *`` pointer. + Represents the C :ctype:`PyObject *` datatype. Calling this without an + argument creates a ``NULL`` :ctype:`PyObject *` pointer. -The ``ctypes.wintypes`` module provides quite some other Windows specific data -types, for example ``HWND``, ``WPARAM``, or ``DWORD``. Some useful structures -like ``MSG`` or ``RECT`` are also defined. +The :mod:`ctypes.wintypes` module provides quite some other Windows specific +data types, for example :ctype:`HWND`, :ctype:`WPARAM`, or :ctype:`DWORD`. Some +useful structures like :ctype:`MSG` or :ctype:`RECT` are also defined. .. _ctypes-structured-data-types: @@ -2373,7 +2378,7 @@ Abstract base class for structures in *native* byte order. Concrete structure and union types must be created by subclassing one of these - types, and at least define a :attr:`_fields_` class variable. ``ctypes`` will + types, and at least define a :attr:`_fields_` class variable. :mod:`ctypes` will create :term:`descriptor`\s which allow reading and writing the fields by direct attribute accesses. These are the @@ -2426,11 +2431,11 @@ .. attribute:: _anonymous_ An optional sequence that lists the names of unnamed (anonymous) fields. - ``_anonymous_`` must be already defined when :attr:`_fields_` is assigned, - otherwise it will have no effect. + :attr:`_anonymous_` must be already defined when :attr:`_fields_` is + assigned, otherwise it will have no effect. The fields listed in this variable must be structure or union type fields. - ``ctypes`` will create descriptors in the structure type that allows to + :mod:`ctypes` will create descriptors in the structure type that allows to access the nested fields directly, without the need to create the structure or union field. @@ -2459,17 +2464,17 @@ td.lptdesc = POINTER(some_type) td.u.lptdesc = POINTER(some_type) -It is possible to defined sub-subclasses of structures, they inherit the fields -of the base class. If the subclass definition has a separate :attr:`_fields_` -variable, the fields specified in this are appended to the fields of the base -class. - -Structure and union constructors accept both positional and keyword arguments. -Positional arguments are used to initialize member fields in the same order as -they are appear in :attr:`_fields_`. Keyword arguments in the constructor are -interpreted as attribute assignments, so they will initialize :attr:`_fields_` -with the same name, or create new attributes for names not present in -:attr:`_fields_`. + It is possible to defined sub-subclasses of structures, they inherit the + fields of the base class. If the subclass definition has a separate + :attr:`_fields_` variable, the fields specified in this are appended to the + fields of the base class. + + Structure and union constructors accept both positional and keyword + arguments. Positional arguments are used to initialize member fields in the + same order as they are appear in :attr:`_fields_`. Keyword arguments in the + constructor are interpreted as attribute assignments, so they will initialize + :attr:`_fields_` with the same name, or create new attributes for names not + present in :attr:`_fields_`. .. _ctypes-arrays-pointers: @@ -2477,6 +2482,6 @@ Arrays and pointers ^^^^^^^^^^^^^^^^^^^ -Not yet written - please see the sections :ref:`ctypes-pointers` and -section :ref:`ctypes-arrays` in the tutorial. +Not yet written - please see the sections :ref:`ctypes-pointers` and section +:ref:`ctypes-arrays` in the tutorial. From python-checkins at python.org Tue Dec 29 12:24:00 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 29 Dec 2009 11:24:00 -0000 Subject: [Python-checkins] r77110 - in python/branches/py3k: Doc/library/ctypes.rst Message-ID: Author: georg.brandl Date: Tue Dec 29 12:24:00 2009 New Revision: 77110 Log: Merged revisions 77108-77109 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77108 | georg.brandl | 2009-12-29 11:34:34 +0100 (Di, 29 Dez 2009) | 1 line #7569: clarification about c_char_p. ........ r77109 | georg.brandl | 2009-12-29 12:06:31 +0100 (Di, 29 Dez 2009) | 1 line Improve markup of ctypes docs. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/ctypes.rst Modified: python/branches/py3k/Doc/library/ctypes.rst ============================================================================== --- python/branches/py3k/Doc/library/ctypes.rst (original) +++ python/branches/py3k/Doc/library/ctypes.rst Tue Dec 29 12:24:00 2009 @@ -6,7 +6,7 @@ .. moduleauthor:: Thomas Heller -``ctypes`` is a foreign function library for Python. It provides C compatible +:mod:`ctypes` is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python. @@ -16,9 +16,9 @@ ctypes tutorial --------------- -Note: The code samples in this tutorial use :mod:`doctest` to make sure that they -actually work. Since some code samples behave differently under Linux, Windows, -or Mac OS X, they contain doctest directives in comments. +Note: The code samples in this tutorial use :mod:`doctest` to make sure that +they actually work. Since some code samples behave differently under Linux, +Windows, or Mac OS X, they contain doctest directives in comments. Note: Some code samples reference the ctypes :class:`c_int` type. This type is an alias for the :class:`c_long` type on 32-bit systems. So, you should not be @@ -38,9 +38,9 @@ loads libraries which export functions using the standard ``cdecl`` calling convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and -assumes the functions return a Windows :class:`HRESULT` error code. The error -code is used to automatically raise a :class:`WindowsError` exception when -the function call fails. +assumes the functions return a Windows :ctype:`HRESULT` error code. The error +code is used to automatically raise a :class:`WindowsError` exception when the +function call fails. Here are some examples for Windows. Note that ``msvcrt`` is the MS standard C library containing most standard C functions, and uses the cdecl calling @@ -109,8 +109,8 @@ explicitly, and then call it with bytes or string objects respectively. Sometimes, dlls export functions with names which aren't valid Python -identifiers, like ``"??2 at YAPAXI@Z"``. In this case you have to use ``getattr`` -to retrieve the function:: +identifiers, like ``"??2 at YAPAXI@Z"``. In this case you have to use +:func:`getattr` to retrieve the function:: >>> getattr(cdll.msvcrt, "??2 at YAPAXI@Z") # doctest: +WINDOWS <_FuncPtr object at 0x...> @@ -149,8 +149,8 @@ 0x1d000000 >>> -:mod:`ctypes` tries to protect you from calling functions with the wrong number of -arguments or the wrong calling convention. Unfortunately this only works on +:mod:`ctypes` tries to protect you from calling functions with the wrong number +of arguments or the wrong calling convention. Unfortunately this only works on Windows. It does this by examining the stack after the function returns, so although an error is raised the function *has* been called:: @@ -192,15 +192,15 @@ WindowsError: exception: access violation reading 0x00000020 >>> -There are, however, enough ways to crash Python with :mod:`ctypes`, so you should -be careful anyway. +There are, however, enough ways to crash Python with :mod:`ctypes`, so you +should be careful anyway. ``None``, integers, bytes objects and (unicode) strings are the only native Python objects that can directly be used as parameters in these function calls. -``None`` is passed as a C ``NULL`` pointer, bytes objects and strings are -passed as pointer to the memory block that contains their data (``char *`` or -``wchar_t *``). Python integers are passed as the platforms -default C ``int`` type, their value is masked to fit into the C type. +``None`` is passed as a C ``NULL`` pointer, bytes objects and strings are passed +as pointer to the memory block that contains their data (:ctype:`char *` or +:ctype:`wchar_t *`). Python integers are passed as the platforms default C +:ctype:`int` type, their value is masked to fit into the C type. Before we move on calling functions with other parameter types, we have to learn more about :mod:`ctypes` data types. @@ -213,47 +213,46 @@ :mod:`ctypes` defines a number of primitive C compatible data types : - +----------------------+--------------------------------+----------------------------+ - | ctypes type | C type | Python type | - +======================+================================+============================+ - | :class:`c_char` | ``char`` | 1-character bytes object | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_wchar` | ``wchar_t`` | 1-character string | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_byte` | ``char`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ubyte` | ``unsigned char`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_short` | ``short`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ushort` | ``unsigned short`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_int` | ``int`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_uint` | ``unsigned int`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_long` | ``long`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ulong` | ``unsigned long`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_longlong` | ``__int64`` or ``long long`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ulonglong` | ``unsigned __int64`` or | int | - | | ``unsigned long long`` | | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_float` | ``float`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_double` | ``double`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_longdouble`| ``long double`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_char_p` | ``char *`` (NUL terminated) | bytes object or ``None`` | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_wchar_p` | ``wchar_t *`` (NUL terminated) | string or ``None`` | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_void_p` | ``void *`` | int or ``None`` | - +----------------------+--------------------------------+----------------------------+ - ++----------------------+----------------------------------------+----------------------------+ +| ctypes type | C type | Python type | ++======================+========================================+============================+ +| :class:`c_char` | :ctype:`char` | 1-character bytes object | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_wchar` | :ctype:`wchar_t` | 1-character string | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_byte` | :ctype:`char` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ubyte` | :ctype:`unsigned char` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_short` | :ctype:`short` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ushort` | :ctype:`unsigned short` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_int` | :ctype:`int` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_uint` | :ctype:`unsigned int` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_long` | :ctype:`long` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ulong` | :ctype:`unsigned long` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_longlong` | :ctype:`__int64` or :ctype:`long long` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ulonglong` | :ctype:`unsigned __int64` or | int | +| | :ctype:`unsigned long long` | | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_float` | :ctype:`float` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_double` | :ctype:`double` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_longdouble`| :ctype:`long double` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_char_p` | :ctype:`char *` (NUL terminated) | bytes object or ``None`` | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_wchar_p` | :ctype:`wchar_t *` (NUL terminated) | string or ``None`` | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_void_p` | :ctype:`void *` | int or ``None`` | ++----------------------+----------------------------------------+----------------------------+ All these types can be created by calling them with an optional initializer of the correct type and value:: @@ -318,10 +317,10 @@ 10 b'Hi\x00lo\x00\x00\x00\x00\x00' >>> -The :func:`create_string_buffer` function replaces the ``c_buffer`` function -(which is still available as an alias), as well as the ``c_string`` function +The :func:`create_string_buffer` function replaces the :func:`c_buffer` function +(which is still available as an alias), as well as the :func:`c_string` function from earlier ctypes releases. To create a mutable memory block containing -unicode characters of the C type ``wchar_t`` use the +unicode characters of the C type :ctype:`wchar_t` use the :func:`create_unicode_buffer` function. @@ -365,9 +364,9 @@ Calling functions with your own custom data types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can also customize :mod:`ctypes` argument conversion to allow instances of your -own classes be used as function arguments. :mod:`ctypes` looks for an -:attr:`_as_parameter_` attribute and uses this as the function argument. Of +You can also customize :mod:`ctypes` argument conversion to allow instances of +your own classes be used as function arguments. :mod:`ctypes` looks for an +:attr:`_as_parameter_` attribute and uses this as the function argument. Of course, it must be one of integer, string, or bytes:: >>> class Bottles(object): @@ -432,9 +431,9 @@ Return types ^^^^^^^^^^^^ -By default functions are assumed to return the C ``int`` type. Other return -types can be specified by setting the :attr:`restype` attribute of the function -object. +By default functions are assumed to return the C :ctype:`int` type. Other +return types can be specified by setting the :attr:`restype` attribute of the +function object. Here is a more advanced example, it uses the ``strchr`` function, which expects a string pointer and a char, and returns a pointer to a string:: @@ -469,7 +468,7 @@ You can also use a callable Python object (a function or a class for example) as the :attr:`restype` attribute, if the foreign function returns an integer. The -callable will be called with the ``integer`` the C function returns, and the +callable will be called with the *integer* the C function returns, and the result of this call will be used as the result of your function call. This is useful to check for error return values and automatically raise an exception:: @@ -563,8 +562,8 @@ You can, however, build much more complicated structures. Structures can itself contain other structures by using a structure as a field type. -Here is a RECT structure which contains two POINTs named ``upperleft`` and -``lowerright`` :: +Here is a RECT structure which contains two POINTs named *upperleft* and +*lowerright*:: >>> class RECT(Structure): ... _fields_ = [("upperleft", POINT), @@ -605,8 +604,9 @@ :mod:`ctypes` uses the native byte order for Structures and Unions. To build structures with non-native byte order, you can use one of the -BigEndianStructure, LittleEndianStructure, BigEndianUnion, and LittleEndianUnion -base classes. These classes cannot contain pointer fields. +:class:`BigEndianStructure`, :class:`LittleEndianStructure`, +:class:`BigEndianUnion`, and :class:`LittleEndianUnion` base classes. These +classes cannot contain pointer fields. .. _ctypes-bit-fields-in-structures-unions: @@ -692,7 +692,7 @@ >>> pi = pointer(i) >>> -Pointer instances have a ``contents`` attribute which returns the object to +Pointer instances have a :attr:`contents` attribute which returns the object to which the pointer points, the ``i`` object above:: >>> pi.contents @@ -717,7 +717,8 @@ c_long(99) >>> -.. XXX Document dereferencing pointers, and that it is preferred over the .contents attribute. +.. XXX Document dereferencing pointers, and that it is preferred over the + .contents attribute. Pointer instances can also be indexed with integers:: @@ -1280,9 +1281,9 @@ The exact functionality is system dependent. -On Linux, :func:`find_library` tries to run external programs (/sbin/ldconfig, -gcc, and objdump) to find the library file. It returns the filename of the -library file. Here are some examples:: +On Linux, :func:`find_library` tries to run external programs +(``/sbin/ldconfig``, ``gcc``, and ``objdump``) to find the library file. It +returns the filename of the library file. Here are some examples:: >>> from ctypes.util import find_library >>> find_library("m") @@ -1329,7 +1330,7 @@ Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return - ``int``. + :ctype:`int`. .. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False) @@ -1346,7 +1347,7 @@ Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the ``stdcall`` calling convention, and are - assumed to return ``int`` by default. + assumed to return :ctype:`int` by default. On Windows CE only the standard calling convention is used, for convenience the :class:`WinDLL` and :class:`OleDLL` use the standard calling convention on this @@ -1368,12 +1369,13 @@ All these classes can be instantiated by calling them with at least one argument, the pathname of the shared library. If you have an existing handle to an already loaded shared library, it can be passed as the ``handle`` named -parameter, otherwise the underlying platforms ``dlopen`` or :meth:`LoadLibrary` +parameter, otherwise the underlying platforms ``dlopen`` or ``LoadLibrary`` function is used to load the library into the process, and to get a handle to it. The *mode* parameter can be used to specify how the library is loaded. For -details, consult the :manpage:`dlopen(3)` manpage, on Windows, *mode* is ignored. +details, consult the :manpage:`dlopen(3)` manpage, on Windows, *mode* is +ignored. The *use_errno* parameter, when set to True, enables a ctypes mechanism that allows to access the system :data:`errno` error number in a safe way. @@ -1439,7 +1441,7 @@ .. class:: LibraryLoader(dlltype) - Class which loads shared libraries. ``dlltype`` should be one of the + Class which loads shared libraries. *dlltype* should be one of the :class:`CDLL`, :class:`PyDLL`, :class:`WinDLL`, or :class:`OleDLL` types. :meth:`__getattr__` has special behavior: It allows to load a shared library by @@ -1484,10 +1486,10 @@ .. data:: pythonapi :noindex: - An instance of :class:`PyDLL` that exposes Python C api functions as attributes. - Note that all these functions are assumed to return C ``int``, which is of - course not always the truth, so you have to assign the correct :attr:`restype` - attribute to use these functions. + An instance of :class:`PyDLL` that exposes Python C API functions as + attributes. Note that all these functions are assumed to return C + :ctype:`int`, which is of course not always the truth, so you have to assign + the correct :attr:`restype` attribute to use these functions. .. _ctypes-foreign-functions: @@ -1515,11 +1517,11 @@ .. attribute:: restype Assign a ctypes type to specify the result type of the foreign function. - Use ``None`` for ``void`` a function not returning anything. + Use ``None`` for :ctype:`void`, a function not returning anything. It is possible to assign a callable Python object that is not a ctypes - type, in this case the function is assumed to return a C ``int``, and the - callable will be called with this integer, allowing to do further + type, in this case the function is assumed to return a C :ctype:`int`, and + the callable will be called with this integer, allowing to do further processing or error checking. Using this is deprecated, for more flexible post processing or error checking use a ctypes data type as :attr:`restype` and assign a callable to the :attr:`errcheck` attribute. @@ -1553,16 +1555,16 @@ :noindex: :module: - *result* is what the foreign function returns, as specified - by the :attr:`restype` attribute. + *result* is what the foreign function returns, as specified by the + :attr:`restype` attribute. - *func* is the foreign function object itself, this allows - to reuse the same callable object to check or post process - the results of several functions. - - *arguments* is a tuple containing the parameters originally - passed to the function call, this allows to specialize the - behavior on the arguments used. + *func* is the foreign function object itself, this allows to reuse the + same callable object to check or post process the results of several + functions. + + *arguments* is a tuple containing the parameters originally passed to + the function call, this allows to specialize the behavior on the + arguments used. The object that this function returns will be returned from the foreign function call, but it can also check the result value @@ -1633,11 +1635,10 @@ :noindex: :module: - Returns a foreign function exported by a shared library. *func_spec* - must be a 2-tuple ``(name_or_ordinal, library)``. The first item is the - name of the exported function as string, or the ordinal of the exported - function as small integer. The second item is the shared library - instance. + Returns a foreign function exported by a shared library. *func_spec* must + be a 2-tuple ``(name_or_ordinal, library)``. The first item is the name of + the exported function as string, or the ordinal of the exported function + as small integer. The second item is the shared library instance. .. function:: prototype(vtbl_index, name[, paramflags[, iid]]) @@ -1776,23 +1777,22 @@ .. function:: byref(obj[, offset]) - Returns a light-weight pointer to *obj*, which must be an - instance of a ctypes type. *offset* defaults to zero, and must be - an integer that will be added to the internal pointer value. + Returns a light-weight pointer to *obj*, which must be an instance of a + ctypes type. *offset* defaults to zero, and must be an integer that will be + added to the internal pointer value. ``byref(obj, offset)`` corresponds to this C code:: (((char *)&obj) + offset) - The returned object can only be used as a foreign function call - parameter. It behaves similar to ``pointer(obj)``, but the - construction is a lot faster. + The returned object can only be used as a foreign function call parameter. + It behaves similar to ``pointer(obj)``, but the construction is a lot faster. .. function:: cast(obj, type) This function is similar to the cast operator in C. It returns a new instance - of *type* which points to the same memory block as *obj*. *type* must be a + of *type* which points to the same memory block as *obj*. *type* must be a pointer type, and *obj* must be an object that can be interpreted as a pointer. @@ -1834,16 +1834,17 @@ .. function:: DllCanUnloadNow() - Windows only: This function is a hook which allows to implement in-process COM - servers with ctypes. It is called from the DllCanUnloadNow function that the - _ctypes extension dll exports. + Windows only: This function is a hook which allows to implement in-process + COM servers with ctypes. It is called from the DllCanUnloadNow function that + the _ctypes extension dll exports. .. function:: DllGetClassObject() - Windows only: This function is a hook which allows to implement in-process COM - servers with ctypes. It is called from the DllGetClassObject function that the - ``_ctypes`` extension dll exports. + Windows only: This function is a hook which allows to implement in-process + COM servers with ctypes. It is called from the DllGetClassObject function + that the ``_ctypes`` extension dll exports. + .. function:: find_library(name) :module: ctypes.util @@ -1859,19 +1860,20 @@ .. function:: find_msvcrt() :module: ctypes.util - Windows only: return the filename of the VC runtype library used - by Python, and by the extension modules. If the name of the - library cannot be determined, ``None`` is returned. - - If you need to free memory, for example, allocated by an extension - module with a call to the ``free(void *)``, it is important that you - use the function in the same library that allocated the memory. + Windows only: return the filename of the VC runtype library used by Python, + and by the extension modules. If the name of the library cannot be + determined, ``None`` is returned. + + If you need to free memory, for example, allocated by an extension module + with a call to the ``free(void *)``, it is important that you use the + function in the same library that allocated the memory. + .. function:: FormatError([code]) - Windows only: Returns a textual description of the error code. If no error code - is specified, the last error code is used by calling the Windows api function - GetLastError. + Windows only: Returns a textual description of the error code *code*. If no + error code is specified, the last error code is used by calling the Windows + api function GetLastError. .. function:: GetLastError() @@ -1893,8 +1895,8 @@ .. function:: memmove(dst, src, count) Same as the standard C memmove library function: copies *count* bytes from - *src* to *dst*. *dst* and *src* must be integers or ctypes instances that - can be converted to pointers. + *src* to *dst*. *dst* and *src* must be integers or ctypes instances that can + be converted to pointers. .. function:: memset(dst, c, count) @@ -1908,13 +1910,13 @@ This factory function creates and returns a new ctypes pointer type. Pointer types are cached an reused internally, so calling this function repeatedly is - cheap. type must be a ctypes type. + cheap. *type* must be a ctypes type. .. function:: pointer(obj) This function creates a new pointer instance, pointing to *obj*. The returned - object is of the type POINTER(type(obj)). + object is of the type ``POINTER(type(obj))``. Note: If you just want to pass a pointer to an object to a foreign function call, you should use ``byref(obj)`` which is much faster. @@ -1922,10 +1924,10 @@ .. function:: resize(obj, size) - This function resizes the internal memory buffer of obj, which must be an - instance of a ctypes type. It is not possible to make the buffer smaller than - the native size of the objects type, as given by ``sizeof(type(obj))``, but - it is possible to enlarge the buffer. + This function resizes the internal memory buffer of *obj*, which must be an + instance of a ctypes type. It is not possible to make the buffer smaller + than the native size of the objects type, as given by ``sizeof(type(obj))``, + but it is possible to enlarge the buffer. .. function:: set_conversion_mode(encoding, errors) @@ -1936,9 +1938,9 @@ the error handling on encoding/decoding errors. Examples of possible values are ``'strict'``, ``'replace'``, or ``'ignore'``. - :func:`set_conversion_mode` returns a 2-tuple containing the previous conversion - rules. On windows, the initial conversion rules are ``('mbcs', 'ignore')``, on - other systems ``('ascii', 'strict')``. + :func:`set_conversion_mode` returns a 2-tuple containing the previous + conversion rules. On windows, the initial conversion rules are ``('mbcs', + 'ignore')``, on other systems ``('ascii', 'strict')``. You can set the *encoding* to ``'undefined'`` to completely disable automatic conversions. @@ -1950,6 +1952,7 @@ variable in the calling thread to *value* and return the previous value. + .. function:: set_last_error(value) Windows only: set the current value of the ctypes-private copy of the system @@ -1957,6 +1960,7 @@ previous value. + .. function:: sizeof(obj_or_type) Returns the size in bytes of a ctypes type or instance memory buffer. Does the @@ -1974,7 +1978,7 @@ Windows only: this function is probably the worst-named thing in ctypes. It creates an instance of WindowsError. If *code* is not specified, - ``GetLastError`` is called to determine the error code. If ``descr`` is not + ``GetLastError`` is called to determine the error code. If *descr* is not specified, :func:`FormatError` is called to get a textual description of the error. @@ -1982,8 +1986,8 @@ .. function:: wstring_at(address, size=-1) This function returns the wide character string starting at memory address - *address* as a string. If ``size`` is specified, it is used as the - number of characters of the string, otherwise the string is assumed to be + *address* as a string. If *size* is specified, it is used as the number of + characters of the string, otherwise the string is assumed to be zero-terminated. @@ -1995,37 +1999,37 @@ .. class:: _CData - This non-public class is the common base class of all ctypes data types. Among - other things, all ctypes type instances contain a memory block that hold C - compatible data; the address of the memory block is returned by the + This non-public class is the common base class of all ctypes data types. + Among other things, all ctypes type instances contain a memory block that + hold C compatible data; the address of the memory block is returned by the :func:`addressof` helper function. Another instance variable is exposed as - :attr:`_objects`; this contains other Python objects that need to be kept alive - in case the memory block contains pointers. + :attr:`_objects`; this contains other Python objects that need to be kept + alive in case the memory block contains pointers. Common methods of ctypes data types, these are all class methods (to be exact, they are methods of the :term:`metaclass`): .. method:: _CData.from_buffer(source[, offset]) - This method returns a ctypes instance that shares the buffer of - the ``source`` object. The ``source`` object must support the - writeable buffer interface. The optional ``offset`` parameter - specifies an offset into the source buffer in bytes; the default - is zero. If the source buffer is not large enough a ValueError - is raised. + This method returns a ctypes instance that shares the buffer of the + *source* object. The *source* object must support the writeable buffer + interface. The optional *offset* parameter specifies an offset into the + source buffer in bytes; the default is zero. If the source buffer is not + large enough a :exc:`ValueError` is raised. + .. method:: _CData.from_buffer_copy(source[, offset]) - This method creates a ctypes instance, copying the buffer from - the source object buffer which must be readable. The optional - *offset* parameter specifies an offset into the source buffer - in bytes; the default is zero. If the source buffer is not - large enough a ValueError is raised. + This method creates a ctypes instance, copying the buffer from the + *source* object buffer which must be readable. The optional *offset* + parameter specifies an offset into the source buffer in bytes; the default + is zero. If the source buffer is not large enough a :exc:`ValueError` is + raised. .. method:: from_address(address) This method returns a ctypes type instance using the memory specified by - address which must be an integer. + *address* which must be an integer. .. method:: from_param(obj) @@ -2111,193 +2115,195 @@ .. class:: c_byte - Represents the C signed char datatype, and interprets the value as small - integer. The constructor accepts an optional integer initializer; no overflow - checking is done. + Represents the C :ctype:`signed char` datatype, and interprets the value as + small integer. The constructor accepts an optional integer initializer; no + overflow checking is done. .. class:: c_char - Represents the C char datatype, and interprets the value as a single character. - The constructor accepts an optional string initializer, the length of the string - must be exactly one character. + Represents the C :ctype:`char` datatype, and interprets the value as a single + character. The constructor accepts an optional string initializer, the + length of the string must be exactly one character. .. class:: c_char_p - Represents the C char \* datatype, which must be a pointer to a zero-terminated - string. The constructor accepts an integer address, or a bytes object. + Represents the C :ctype:`char *` datatype when it points to a zero-terminated + string. For a general character pointer that may also point to binary data, + ``POINTER(c_char)`` must be used. The constructor accepts an integer + address, or a bytes object. .. class:: c_double - Represents the C double datatype. The constructor accepts an optional float - initializer. + Represents the C :ctype:`double` datatype. The constructor accepts an + optional float initializer. .. class:: c_longdouble - Represents the C long double datatype. The constructor accepts an - optional float initializer. On platforms where ``sizeof(long - double) == sizeof(double)`` it is an alias to :class:`c_double`. + Represents the C :ctype:`long double` datatype. The constructor accepts an + optional float initializer. On platforms where ``sizeof(long double) == + sizeof(double)`` it is an alias to :class:`c_double`. .. class:: c_float - Represents the C float datatype. The constructor accepts an optional float - initializer. + Represents the C :ctype:`float` datatype. The constructor accepts an + optional float initializer. .. class:: c_int - Represents the C signed int datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. On platforms where - ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`. + Represents the C :ctype:`signed int` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. On platforms + where ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`. .. class:: c_int8 - Represents the C 8-bit ``signed int`` datatype. Usually an alias for + Represents the C 8-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_byte`. .. class:: c_int16 - Represents the C 16-bit signed int datatype. Usually an alias for + Represents the C 16-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_short`. .. class:: c_int32 - Represents the C 32-bit signed int datatype. Usually an alias for + Represents the C 32-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_int`. .. class:: c_int64 - Represents the C 64-bit ``signed int`` datatype. Usually an alias for + Represents the C 64-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_longlong`. .. class:: c_long - Represents the C ``signed long`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`signed long` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_longlong - Represents the C ``signed long long`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`signed long long` datatype. The constructor accepts + an optional integer initializer; no overflow checking is done. .. class:: c_short - Represents the C ``signed short`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`signed short` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_size_t - Represents the C ``size_t`` datatype. + Represents the C :ctype:`size_t` datatype. .. class:: c_ubyte - Represents the C ``unsigned char`` datatype, it interprets the value as small - integer. The constructor accepts an optional integer initializer; no overflow - checking is done. + Represents the C :ctype:`unsigned char` datatype, it interprets the value as + small integer. The constructor accepts an optional integer initializer; no + overflow checking is done. .. class:: c_uint - Represents the C ``unsigned int`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. On platforms where - ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`. + Represents the C :ctype:`unsigned int` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. On platforms + where ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`. .. class:: c_uint8 - Represents the C 8-bit unsigned int datatype. Usually an alias for + Represents the C 8-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ubyte`. .. class:: c_uint16 - Represents the C 16-bit unsigned int datatype. Usually an alias for + Represents the C 16-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ushort`. .. class:: c_uint32 - Represents the C 32-bit unsigned int datatype. Usually an alias for + Represents the C 32-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_uint`. .. class:: c_uint64 - Represents the C 64-bit unsigned int datatype. Usually an alias for + Represents the C 64-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ulonglong`. .. class:: c_ulong - Represents the C ``unsigned long`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned long` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_ulonglong - Represents the C ``unsigned long long`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned long long` datatype. The constructor + accepts an optional integer initializer; no overflow checking is done. .. class:: c_ushort - Represents the C ``unsigned short`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned short` datatype. The constructor accepts + an optional integer initializer; no overflow checking is done. .. class:: c_void_p - Represents the C ``void *`` type. The value is represented as integer. The - constructor accepts an optional integer initializer. + Represents the C :ctype:`void *` type. The value is represented as integer. + The constructor accepts an optional integer initializer. .. class:: c_wchar - Represents the C ``wchar_t`` datatype, and interprets the value as a single - character unicode string. The constructor accepts an optional string + Represents the C :ctype:`wchar_t` datatype, and interprets the value as a + single character unicode string. The constructor accepts an optional string initializer, the length of the string must be exactly one character. .. class:: c_wchar_p - Represents the C ``wchar_t *`` datatype, which must be a pointer to a - zero-terminated wide character string. The constructor accepts an integer + Represents the C :ctype:`wchar_t *` datatype, which must be a pointer to a + zero-terminated wide character string. The constructor accepts an integer address, or a string. .. class:: c_bool - Represent the C ``bool`` datatype (more accurately, _Bool from C99). Its value - can be True or False, and the constructor accepts any object that has a truth - value. + Represent the C :ctype:`bool` datatype (more accurately, :ctype:`_Bool` from + C99). Its value can be True or False, and the constructor accepts any object + that has a truth value. .. class:: HRESULT - Windows only: Represents a :class:`HRESULT` value, which contains success or + Windows only: Represents a :ctype:`HRESULT` value, which contains success or error information for a function or method call. .. class:: py_object - Represents the C ``PyObject *`` datatype. Calling this without an argument - creates a ``NULL`` ``PyObject *`` pointer. + Represents the C :ctype:`PyObject *` datatype. Calling this without an + argument creates a ``NULL`` :ctype:`PyObject *` pointer. -The ``ctypes.wintypes`` module provides quite some other Windows specific data -types, for example ``HWND``, ``WPARAM``, or ``DWORD``. Some useful structures -like ``MSG`` or ``RECT`` are also defined. +The :mod:`ctypes.wintypes` module provides quite some other Windows specific +data types, for example :ctype:`HWND`, :ctype:`WPARAM`, or :ctype:`DWORD`. Some +useful structures like :ctype:`MSG` or :ctype:`RECT` are also defined. .. _ctypes-structured-data-types: @@ -2382,8 +2388,8 @@ .. attribute:: _anonymous_ An optional sequence that lists the names of unnamed (anonymous) fields. - ``_anonymous_`` must be already defined when :attr:`_fields_` is assigned, - otherwise it will have no effect. + :attr:`_anonymous_` must be already defined when :attr:`_fields_` is + assigned, otherwise it will have no effect. The fields listed in this variable must be structure or union type fields. :mod:`ctypes` will create descriptors in the structure type that allows to @@ -2415,17 +2421,17 @@ td.lptdesc = POINTER(some_type) td.u.lptdesc = POINTER(some_type) -It is possible to defined sub-subclasses of structures, they inherit the fields -of the base class. If the subclass definition has a separate :attr:`_fields_` -variable, the fields specified in this are appended to the fields of the base -class. - -Structure and union constructors accept both positional and keyword arguments. -Positional arguments are used to initialize member fields in the same order as -they are appear in :attr:`_fields_`. Keyword arguments in the constructor are -interpreted as attribute assignments, so they will initialize :attr:`_fields_` -with the same name, or create new attributes for names not present in -:attr:`_fields_`. + It is possible to defined sub-subclasses of structures, they inherit the + fields of the base class. If the subclass definition has a separate + :attr:`_fields_` variable, the fields specified in this are appended to the + fields of the base class. + + Structure and union constructors accept both positional and keyword + arguments. Positional arguments are used to initialize member fields in the + same order as they are appear in :attr:`_fields_`. Keyword arguments in the + constructor are interpreted as attribute assignments, so they will initialize + :attr:`_fields_` with the same name, or create new attributes for names not + present in :attr:`_fields_`. .. _ctypes-arrays-pointers: @@ -2433,6 +2439,6 @@ Arrays and pointers ^^^^^^^^^^^^^^^^^^^ -Not yet written - please see the sections :ref:`ctypes-pointers` and -section :ref:`ctypes-arrays` in the tutorial. +Not yet written - please see the sections :ref:`ctypes-pointers` and section +:ref:`ctypes-arrays` in the tutorial. From python-checkins at python.org Tue Dec 29 12:25:38 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 29 Dec 2009 11:25:38 -0000 Subject: [Python-checkins] r77111 - python/trunk/Doc/library/ctypes.rst Message-ID: Author: georg.brandl Date: Tue Dec 29 12:25:38 2009 New Revision: 77111 Log: Fix wrong markup. Modified: python/trunk/Doc/library/ctypes.rst Modified: python/trunk/Doc/library/ctypes.rst ============================================================================== --- python/trunk/Doc/library/ctypes.rst (original) +++ python/trunk/Doc/library/ctypes.rst Tue Dec 29 12:25:38 2009 @@ -513,8 +513,8 @@ :mod:`ctypes` exports the :func:`byref` function which is used to pass parameters by reference. The same effect can be achieved with the -:cfunc:`pointer` function, although :cfunc:`pointer` does a lot more work since -it constructs a real pointer object, so it is faster to use :func:`byref` if you +:func:`pointer` function, although :func:`pointer` does a lot more work since it +constructs a real pointer object, so it is faster to use :func:`byref` if you don't need the pointer object in Python itself:: >>> i = c_int() From python-checkins at python.org Tue Dec 29 12:26:07 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 29 Dec 2009 11:26:07 -0000 Subject: [Python-checkins] r77112 - in python/branches/release31-maint: Doc/library/ctypes.rst Message-ID: Author: georg.brandl Date: Tue Dec 29 12:26:06 2009 New Revision: 77112 Log: Merged revisions 77110 via svnmerge from svn+ssh://svn.python.org/python/branches/py3k ................ r77110 | georg.brandl | 2009-12-29 12:24:00 +0100 (Di, 29 Dez 2009) | 13 lines Merged revisions 77108-77109 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77108 | georg.brandl | 2009-12-29 11:34:34 +0100 (Di, 29 Dez 2009) | 1 line #7569: clarification about c_char_p. ........ r77109 | georg.brandl | 2009-12-29 12:06:31 +0100 (Di, 29 Dez 2009) | 1 line Improve markup of ctypes docs. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/ctypes.rst Modified: python/branches/release31-maint/Doc/library/ctypes.rst ============================================================================== --- python/branches/release31-maint/Doc/library/ctypes.rst (original) +++ python/branches/release31-maint/Doc/library/ctypes.rst Tue Dec 29 12:26:06 2009 @@ -6,7 +6,7 @@ .. moduleauthor:: Thomas Heller -``ctypes`` is a foreign function library for Python. It provides C compatible +:mod:`ctypes` is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python. @@ -16,9 +16,9 @@ ctypes tutorial --------------- -Note: The code samples in this tutorial use :mod:`doctest` to make sure that they -actually work. Since some code samples behave differently under Linux, Windows, -or Mac OS X, they contain doctest directives in comments. +Note: The code samples in this tutorial use :mod:`doctest` to make sure that +they actually work. Since some code samples behave differently under Linux, +Windows, or Mac OS X, they contain doctest directives in comments. Note: Some code samples reference the ctypes :class:`c_int` type. This type is an alias for the :class:`c_long` type on 32-bit systems. So, you should not be @@ -38,9 +38,9 @@ loads libraries which export functions using the standard ``cdecl`` calling convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and -assumes the functions return a Windows :class:`HRESULT` error code. The error -code is used to automatically raise a :class:`WindowsError` exception when -the function call fails. +assumes the functions return a Windows :ctype:`HRESULT` error code. The error +code is used to automatically raise a :class:`WindowsError` exception when the +function call fails. Here are some examples for Windows. Note that ``msvcrt`` is the MS standard C library containing most standard C functions, and uses the cdecl calling @@ -109,8 +109,8 @@ explicitly, and then call it with bytes or string objects respectively. Sometimes, dlls export functions with names which aren't valid Python -identifiers, like ``"??2 at YAPAXI@Z"``. In this case you have to use ``getattr`` -to retrieve the function:: +identifiers, like ``"??2 at YAPAXI@Z"``. In this case you have to use +:func:`getattr` to retrieve the function:: >>> getattr(cdll.msvcrt, "??2 at YAPAXI@Z") # doctest: +WINDOWS <_FuncPtr object at 0x...> @@ -149,8 +149,8 @@ 0x1d000000 >>> -:mod:`ctypes` tries to protect you from calling functions with the wrong number of -arguments or the wrong calling convention. Unfortunately this only works on +:mod:`ctypes` tries to protect you from calling functions with the wrong number +of arguments or the wrong calling convention. Unfortunately this only works on Windows. It does this by examining the stack after the function returns, so although an error is raised the function *has* been called:: @@ -192,15 +192,15 @@ WindowsError: exception: access violation reading 0x00000020 >>> -There are, however, enough ways to crash Python with :mod:`ctypes`, so you should -be careful anyway. +There are, however, enough ways to crash Python with :mod:`ctypes`, so you +should be careful anyway. ``None``, integers, bytes objects and (unicode) strings are the only native Python objects that can directly be used as parameters in these function calls. -``None`` is passed as a C ``NULL`` pointer, bytes objects and strings are -passed as pointer to the memory block that contains their data (``char *`` or -``wchar_t *``). Python integers are passed as the platforms -default C ``int`` type, their value is masked to fit into the C type. +``None`` is passed as a C ``NULL`` pointer, bytes objects and strings are passed +as pointer to the memory block that contains their data (:ctype:`char *` or +:ctype:`wchar_t *`). Python integers are passed as the platforms default C +:ctype:`int` type, their value is masked to fit into the C type. Before we move on calling functions with other parameter types, we have to learn more about :mod:`ctypes` data types. @@ -213,47 +213,46 @@ :mod:`ctypes` defines a number of primitive C compatible data types : - +----------------------+--------------------------------+----------------------------+ - | ctypes type | C type | Python type | - +======================+================================+============================+ - | :class:`c_char` | ``char`` | 1-character bytes object | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_wchar` | ``wchar_t`` | 1-character string | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_byte` | ``char`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ubyte` | ``unsigned char`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_short` | ``short`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ushort` | ``unsigned short`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_int` | ``int`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_uint` | ``unsigned int`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_long` | ``long`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ulong` | ``unsigned long`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_longlong` | ``__int64`` or ``long long`` | int | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ulonglong` | ``unsigned __int64`` or | int | - | | ``unsigned long long`` | | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_float` | ``float`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_double` | ``double`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_longdouble`| ``long double`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_char_p` | ``char *`` (NUL terminated) | bytes object or ``None`` | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_wchar_p` | ``wchar_t *`` (NUL terminated) | string or ``None`` | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_void_p` | ``void *`` | int or ``None`` | - +----------------------+--------------------------------+----------------------------+ - ++----------------------+----------------------------------------+----------------------------+ +| ctypes type | C type | Python type | ++======================+========================================+============================+ +| :class:`c_char` | :ctype:`char` | 1-character bytes object | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_wchar` | :ctype:`wchar_t` | 1-character string | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_byte` | :ctype:`char` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ubyte` | :ctype:`unsigned char` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_short` | :ctype:`short` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ushort` | :ctype:`unsigned short` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_int` | :ctype:`int` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_uint` | :ctype:`unsigned int` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_long` | :ctype:`long` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ulong` | :ctype:`unsigned long` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_longlong` | :ctype:`__int64` or :ctype:`long long` | int | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ulonglong` | :ctype:`unsigned __int64` or | int | +| | :ctype:`unsigned long long` | | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_float` | :ctype:`float` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_double` | :ctype:`double` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_longdouble`| :ctype:`long double` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_char_p` | :ctype:`char *` (NUL terminated) | bytes object or ``None`` | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_wchar_p` | :ctype:`wchar_t *` (NUL terminated) | string or ``None`` | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_void_p` | :ctype:`void *` | int or ``None`` | ++----------------------+----------------------------------------+----------------------------+ All these types can be created by calling them with an optional initializer of the correct type and value:: @@ -318,10 +317,10 @@ 10 b'Hi\x00lo\x00\x00\x00\x00\x00' >>> -The :func:`create_string_buffer` function replaces the ``c_buffer`` function -(which is still available as an alias), as well as the ``c_string`` function +The :func:`create_string_buffer` function replaces the :func:`c_buffer` function +(which is still available as an alias), as well as the :func:`c_string` function from earlier ctypes releases. To create a mutable memory block containing -unicode characters of the C type ``wchar_t`` use the +unicode characters of the C type :ctype:`wchar_t` use the :func:`create_unicode_buffer` function. @@ -365,9 +364,9 @@ Calling functions with your own custom data types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can also customize :mod:`ctypes` argument conversion to allow instances of your -own classes be used as function arguments. :mod:`ctypes` looks for an -:attr:`_as_parameter_` attribute and uses this as the function argument. Of +You can also customize :mod:`ctypes` argument conversion to allow instances of +your own classes be used as function arguments. :mod:`ctypes` looks for an +:attr:`_as_parameter_` attribute and uses this as the function argument. Of course, it must be one of integer, string, or bytes:: >>> class Bottles(object): @@ -432,9 +431,9 @@ Return types ^^^^^^^^^^^^ -By default functions are assumed to return the C ``int`` type. Other return -types can be specified by setting the :attr:`restype` attribute of the function -object. +By default functions are assumed to return the C :ctype:`int` type. Other +return types can be specified by setting the :attr:`restype` attribute of the +function object. Here is a more advanced example, it uses the ``strchr`` function, which expects a string pointer and a char, and returns a pointer to a string:: @@ -469,7 +468,7 @@ You can also use a callable Python object (a function or a class for example) as the :attr:`restype` attribute, if the foreign function returns an integer. The -callable will be called with the ``integer`` the C function returns, and the +callable will be called with the *integer* the C function returns, and the result of this call will be used as the result of your function call. This is useful to check for error return values and automatically raise an exception:: @@ -563,8 +562,8 @@ You can, however, build much more complicated structures. Structures can itself contain other structures by using a structure as a field type. -Here is a RECT structure which contains two POINTs named ``upperleft`` and -``lowerright`` :: +Here is a RECT structure which contains two POINTs named *upperleft* and +*lowerright*:: >>> class RECT(Structure): ... _fields_ = [("upperleft", POINT), @@ -605,8 +604,9 @@ :mod:`ctypes` uses the native byte order for Structures and Unions. To build structures with non-native byte order, you can use one of the -BigEndianStructure, LittleEndianStructure, BigEndianUnion, and LittleEndianUnion -base classes. These classes cannot contain pointer fields. +:class:`BigEndianStructure`, :class:`LittleEndianStructure`, +:class:`BigEndianUnion`, and :class:`LittleEndianUnion` base classes. These +classes cannot contain pointer fields. .. _ctypes-bit-fields-in-structures-unions: @@ -692,7 +692,7 @@ >>> pi = pointer(i) >>> -Pointer instances have a ``contents`` attribute which returns the object to +Pointer instances have a :attr:`contents` attribute which returns the object to which the pointer points, the ``i`` object above:: >>> pi.contents @@ -717,7 +717,8 @@ c_long(99) >>> -.. XXX Document dereferencing pointers, and that it is preferred over the .contents attribute. +.. XXX Document dereferencing pointers, and that it is preferred over the + .contents attribute. Pointer instances can also be indexed with integers:: @@ -1280,9 +1281,9 @@ The exact functionality is system dependent. -On Linux, :func:`find_library` tries to run external programs (/sbin/ldconfig, -gcc, and objdump) to find the library file. It returns the filename of the -library file. Here are some examples:: +On Linux, :func:`find_library` tries to run external programs +(``/sbin/ldconfig``, ``gcc``, and ``objdump``) to find the library file. It +returns the filename of the library file. Here are some examples:: >>> from ctypes.util import find_library >>> find_library("m") @@ -1329,7 +1330,7 @@ Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return - ``int``. + :ctype:`int`. .. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False) @@ -1346,7 +1347,7 @@ Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the ``stdcall`` calling convention, and are - assumed to return ``int`` by default. + assumed to return :ctype:`int` by default. On Windows CE only the standard calling convention is used, for convenience the :class:`WinDLL` and :class:`OleDLL` use the standard calling convention on this @@ -1368,12 +1369,13 @@ All these classes can be instantiated by calling them with at least one argument, the pathname of the shared library. If you have an existing handle to an already loaded shared library, it can be passed as the ``handle`` named -parameter, otherwise the underlying platforms ``dlopen`` or :meth:`LoadLibrary` +parameter, otherwise the underlying platforms ``dlopen`` or ``LoadLibrary`` function is used to load the library into the process, and to get a handle to it. The *mode* parameter can be used to specify how the library is loaded. For -details, consult the :manpage:`dlopen(3)` manpage, on Windows, *mode* is ignored. +details, consult the :manpage:`dlopen(3)` manpage, on Windows, *mode* is +ignored. The *use_errno* parameter, when set to True, enables a ctypes mechanism that allows to access the system :data:`errno` error number in a safe way. @@ -1439,7 +1441,7 @@ .. class:: LibraryLoader(dlltype) - Class which loads shared libraries. ``dlltype`` should be one of the + Class which loads shared libraries. *dlltype* should be one of the :class:`CDLL`, :class:`PyDLL`, :class:`WinDLL`, or :class:`OleDLL` types. :meth:`__getattr__` has special behavior: It allows to load a shared library by @@ -1484,10 +1486,10 @@ .. data:: pythonapi :noindex: - An instance of :class:`PyDLL` that exposes Python C api functions as attributes. - Note that all these functions are assumed to return C ``int``, which is of - course not always the truth, so you have to assign the correct :attr:`restype` - attribute to use these functions. + An instance of :class:`PyDLL` that exposes Python C API functions as + attributes. Note that all these functions are assumed to return C + :ctype:`int`, which is of course not always the truth, so you have to assign + the correct :attr:`restype` attribute to use these functions. .. _ctypes-foreign-functions: @@ -1515,11 +1517,11 @@ .. attribute:: restype Assign a ctypes type to specify the result type of the foreign function. - Use ``None`` for ``void`` a function not returning anything. + Use ``None`` for :ctype:`void`, a function not returning anything. It is possible to assign a callable Python object that is not a ctypes - type, in this case the function is assumed to return a C ``int``, and the - callable will be called with this integer, allowing to do further + type, in this case the function is assumed to return a C :ctype:`int`, and + the callable will be called with this integer, allowing to do further processing or error checking. Using this is deprecated, for more flexible post processing or error checking use a ctypes data type as :attr:`restype` and assign a callable to the :attr:`errcheck` attribute. @@ -1553,16 +1555,16 @@ :noindex: :module: - *result* is what the foreign function returns, as specified - by the :attr:`restype` attribute. + *result* is what the foreign function returns, as specified by the + :attr:`restype` attribute. - *func* is the foreign function object itself, this allows - to reuse the same callable object to check or post process - the results of several functions. - - *arguments* is a tuple containing the parameters originally - passed to the function call, this allows to specialize the - behavior on the arguments used. + *func* is the foreign function object itself, this allows to reuse the + same callable object to check or post process the results of several + functions. + + *arguments* is a tuple containing the parameters originally passed to + the function call, this allows to specialize the behavior on the + arguments used. The object that this function returns will be returned from the foreign function call, but it can also check the result value @@ -1633,11 +1635,10 @@ :noindex: :module: - Returns a foreign function exported by a shared library. *func_spec* - must be a 2-tuple ``(name_or_ordinal, library)``. The first item is the - name of the exported function as string, or the ordinal of the exported - function as small integer. The second item is the shared library - instance. + Returns a foreign function exported by a shared library. *func_spec* must + be a 2-tuple ``(name_or_ordinal, library)``. The first item is the name of + the exported function as string, or the ordinal of the exported function + as small integer. The second item is the shared library instance. .. function:: prototype(vtbl_index, name[, paramflags[, iid]]) @@ -1776,23 +1777,22 @@ .. function:: byref(obj[, offset]) - Returns a light-weight pointer to *obj*, which must be an - instance of a ctypes type. *offset* defaults to zero, and must be - an integer that will be added to the internal pointer value. + Returns a light-weight pointer to *obj*, which must be an instance of a + ctypes type. *offset* defaults to zero, and must be an integer that will be + added to the internal pointer value. ``byref(obj, offset)`` corresponds to this C code:: (((char *)&obj) + offset) - The returned object can only be used as a foreign function call - parameter. It behaves similar to ``pointer(obj)``, but the - construction is a lot faster. + The returned object can only be used as a foreign function call parameter. + It behaves similar to ``pointer(obj)``, but the construction is a lot faster. .. function:: cast(obj, type) This function is similar to the cast operator in C. It returns a new instance - of *type* which points to the same memory block as *obj*. *type* must be a + of *type* which points to the same memory block as *obj*. *type* must be a pointer type, and *obj* must be an object that can be interpreted as a pointer. @@ -1834,16 +1834,17 @@ .. function:: DllCanUnloadNow() - Windows only: This function is a hook which allows to implement in-process COM - servers with ctypes. It is called from the DllCanUnloadNow function that the - _ctypes extension dll exports. + Windows only: This function is a hook which allows to implement in-process + COM servers with ctypes. It is called from the DllCanUnloadNow function that + the _ctypes extension dll exports. .. function:: DllGetClassObject() - Windows only: This function is a hook which allows to implement in-process COM - servers with ctypes. It is called from the DllGetClassObject function that the - ``_ctypes`` extension dll exports. + Windows only: This function is a hook which allows to implement in-process + COM servers with ctypes. It is called from the DllGetClassObject function + that the ``_ctypes`` extension dll exports. + .. function:: find_library(name) :module: ctypes.util @@ -1859,19 +1860,20 @@ .. function:: find_msvcrt() :module: ctypes.util - Windows only: return the filename of the VC runtype library used - by Python, and by the extension modules. If the name of the - library cannot be determined, ``None`` is returned. - - If you need to free memory, for example, allocated by an extension - module with a call to the ``free(void *)``, it is important that you - use the function in the same library that allocated the memory. + Windows only: return the filename of the VC runtype library used by Python, + and by the extension modules. If the name of the library cannot be + determined, ``None`` is returned. + + If you need to free memory, for example, allocated by an extension module + with a call to the ``free(void *)``, it is important that you use the + function in the same library that allocated the memory. + .. function:: FormatError([code]) - Windows only: Returns a textual description of the error code. If no error code - is specified, the last error code is used by calling the Windows api function - GetLastError. + Windows only: Returns a textual description of the error code *code*. If no + error code is specified, the last error code is used by calling the Windows + api function GetLastError. .. function:: GetLastError() @@ -1893,8 +1895,8 @@ .. function:: memmove(dst, src, count) Same as the standard C memmove library function: copies *count* bytes from - *src* to *dst*. *dst* and *src* must be integers or ctypes instances that - can be converted to pointers. + *src* to *dst*. *dst* and *src* must be integers or ctypes instances that can + be converted to pointers. .. function:: memset(dst, c, count) @@ -1908,13 +1910,13 @@ This factory function creates and returns a new ctypes pointer type. Pointer types are cached an reused internally, so calling this function repeatedly is - cheap. type must be a ctypes type. + cheap. *type* must be a ctypes type. .. function:: pointer(obj) This function creates a new pointer instance, pointing to *obj*. The returned - object is of the type POINTER(type(obj)). + object is of the type ``POINTER(type(obj))``. Note: If you just want to pass a pointer to an object to a foreign function call, you should use ``byref(obj)`` which is much faster. @@ -1922,10 +1924,10 @@ .. function:: resize(obj, size) - This function resizes the internal memory buffer of obj, which must be an - instance of a ctypes type. It is not possible to make the buffer smaller than - the native size of the objects type, as given by ``sizeof(type(obj))``, but - it is possible to enlarge the buffer. + This function resizes the internal memory buffer of *obj*, which must be an + instance of a ctypes type. It is not possible to make the buffer smaller + than the native size of the objects type, as given by ``sizeof(type(obj))``, + but it is possible to enlarge the buffer. .. function:: set_conversion_mode(encoding, errors) @@ -1936,9 +1938,9 @@ the error handling on encoding/decoding errors. Examples of possible values are ``'strict'``, ``'replace'``, or ``'ignore'``. - :func:`set_conversion_mode` returns a 2-tuple containing the previous conversion - rules. On windows, the initial conversion rules are ``('mbcs', 'ignore')``, on - other systems ``('ascii', 'strict')``. + :func:`set_conversion_mode` returns a 2-tuple containing the previous + conversion rules. On windows, the initial conversion rules are ``('mbcs', + 'ignore')``, on other systems ``('ascii', 'strict')``. You can set the *encoding* to ``'undefined'`` to completely disable automatic conversions. @@ -1950,6 +1952,7 @@ variable in the calling thread to *value* and return the previous value. + .. function:: set_last_error(value) Windows only: set the current value of the ctypes-private copy of the system @@ -1957,6 +1960,7 @@ previous value. + .. function:: sizeof(obj_or_type) Returns the size in bytes of a ctypes type or instance memory buffer. Does the @@ -1974,7 +1978,7 @@ Windows only: this function is probably the worst-named thing in ctypes. It creates an instance of WindowsError. If *code* is not specified, - ``GetLastError`` is called to determine the error code. If ``descr`` is not + ``GetLastError`` is called to determine the error code. If *descr* is not specified, :func:`FormatError` is called to get a textual description of the error. @@ -1982,8 +1986,8 @@ .. function:: wstring_at(address, size=-1) This function returns the wide character string starting at memory address - *address* as a string. If ``size`` is specified, it is used as the - number of characters of the string, otherwise the string is assumed to be + *address* as a string. If *size* is specified, it is used as the number of + characters of the string, otherwise the string is assumed to be zero-terminated. @@ -1995,37 +1999,37 @@ .. class:: _CData - This non-public class is the common base class of all ctypes data types. Among - other things, all ctypes type instances contain a memory block that hold C - compatible data; the address of the memory block is returned by the + This non-public class is the common base class of all ctypes data types. + Among other things, all ctypes type instances contain a memory block that + hold C compatible data; the address of the memory block is returned by the :func:`addressof` helper function. Another instance variable is exposed as - :attr:`_objects`; this contains other Python objects that need to be kept alive - in case the memory block contains pointers. + :attr:`_objects`; this contains other Python objects that need to be kept + alive in case the memory block contains pointers. Common methods of ctypes data types, these are all class methods (to be exact, they are methods of the :term:`metaclass`): .. method:: _CData.from_buffer(source[, offset]) - This method returns a ctypes instance that shares the buffer of - the ``source`` object. The ``source`` object must support the - writeable buffer interface. The optional ``offset`` parameter - specifies an offset into the source buffer in bytes; the default - is zero. If the source buffer is not large enough a ValueError - is raised. + This method returns a ctypes instance that shares the buffer of the + *source* object. The *source* object must support the writeable buffer + interface. The optional *offset* parameter specifies an offset into the + source buffer in bytes; the default is zero. If the source buffer is not + large enough a :exc:`ValueError` is raised. + .. method:: _CData.from_buffer_copy(source[, offset]) - This method creates a ctypes instance, copying the buffer from - the source object buffer which must be readable. The optional - *offset* parameter specifies an offset into the source buffer - in bytes; the default is zero. If the source buffer is not - large enough a ValueError is raised. + This method creates a ctypes instance, copying the buffer from the + *source* object buffer which must be readable. The optional *offset* + parameter specifies an offset into the source buffer in bytes; the default + is zero. If the source buffer is not large enough a :exc:`ValueError` is + raised. .. method:: from_address(address) This method returns a ctypes type instance using the memory specified by - address which must be an integer. + *address* which must be an integer. .. method:: from_param(obj) @@ -2111,193 +2115,195 @@ .. class:: c_byte - Represents the C signed char datatype, and interprets the value as small - integer. The constructor accepts an optional integer initializer; no overflow - checking is done. + Represents the C :ctype:`signed char` datatype, and interprets the value as + small integer. The constructor accepts an optional integer initializer; no + overflow checking is done. .. class:: c_char - Represents the C char datatype, and interprets the value as a single character. - The constructor accepts an optional string initializer, the length of the string - must be exactly one character. + Represents the C :ctype:`char` datatype, and interprets the value as a single + character. The constructor accepts an optional string initializer, the + length of the string must be exactly one character. .. class:: c_char_p - Represents the C char \* datatype, which must be a pointer to a zero-terminated - string. The constructor accepts an integer address, or a bytes object. + Represents the C :ctype:`char *` datatype when it points to a zero-terminated + string. For a general character pointer that may also point to binary data, + ``POINTER(c_char)`` must be used. The constructor accepts an integer + address, or a bytes object. .. class:: c_double - Represents the C double datatype. The constructor accepts an optional float - initializer. + Represents the C :ctype:`double` datatype. The constructor accepts an + optional float initializer. .. class:: c_longdouble - Represents the C long double datatype. The constructor accepts an - optional float initializer. On platforms where ``sizeof(long - double) == sizeof(double)`` it is an alias to :class:`c_double`. + Represents the C :ctype:`long double` datatype. The constructor accepts an + optional float initializer. On platforms where ``sizeof(long double) == + sizeof(double)`` it is an alias to :class:`c_double`. .. class:: c_float - Represents the C float datatype. The constructor accepts an optional float - initializer. + Represents the C :ctype:`float` datatype. The constructor accepts an + optional float initializer. .. class:: c_int - Represents the C signed int datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. On platforms where - ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`. + Represents the C :ctype:`signed int` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. On platforms + where ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`. .. class:: c_int8 - Represents the C 8-bit ``signed int`` datatype. Usually an alias for + Represents the C 8-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_byte`. .. class:: c_int16 - Represents the C 16-bit signed int datatype. Usually an alias for + Represents the C 16-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_short`. .. class:: c_int32 - Represents the C 32-bit signed int datatype. Usually an alias for + Represents the C 32-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_int`. .. class:: c_int64 - Represents the C 64-bit ``signed int`` datatype. Usually an alias for + Represents the C 64-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_longlong`. .. class:: c_long - Represents the C ``signed long`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`signed long` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_longlong - Represents the C ``signed long long`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`signed long long` datatype. The constructor accepts + an optional integer initializer; no overflow checking is done. .. class:: c_short - Represents the C ``signed short`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`signed short` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_size_t - Represents the C ``size_t`` datatype. + Represents the C :ctype:`size_t` datatype. .. class:: c_ubyte - Represents the C ``unsigned char`` datatype, it interprets the value as small - integer. The constructor accepts an optional integer initializer; no overflow - checking is done. + Represents the C :ctype:`unsigned char` datatype, it interprets the value as + small integer. The constructor accepts an optional integer initializer; no + overflow checking is done. .. class:: c_uint - Represents the C ``unsigned int`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. On platforms where - ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`. + Represents the C :ctype:`unsigned int` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. On platforms + where ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`. .. class:: c_uint8 - Represents the C 8-bit unsigned int datatype. Usually an alias for + Represents the C 8-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ubyte`. .. class:: c_uint16 - Represents the C 16-bit unsigned int datatype. Usually an alias for + Represents the C 16-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ushort`. .. class:: c_uint32 - Represents the C 32-bit unsigned int datatype. Usually an alias for + Represents the C 32-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_uint`. .. class:: c_uint64 - Represents the C 64-bit unsigned int datatype. Usually an alias for + Represents the C 64-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ulonglong`. .. class:: c_ulong - Represents the C ``unsigned long`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned long` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_ulonglong - Represents the C ``unsigned long long`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned long long` datatype. The constructor + accepts an optional integer initializer; no overflow checking is done. .. class:: c_ushort - Represents the C ``unsigned short`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned short` datatype. The constructor accepts + an optional integer initializer; no overflow checking is done. .. class:: c_void_p - Represents the C ``void *`` type. The value is represented as integer. The - constructor accepts an optional integer initializer. + Represents the C :ctype:`void *` type. The value is represented as integer. + The constructor accepts an optional integer initializer. .. class:: c_wchar - Represents the C ``wchar_t`` datatype, and interprets the value as a single - character unicode string. The constructor accepts an optional string + Represents the C :ctype:`wchar_t` datatype, and interprets the value as a + single character unicode string. The constructor accepts an optional string initializer, the length of the string must be exactly one character. .. class:: c_wchar_p - Represents the C ``wchar_t *`` datatype, which must be a pointer to a - zero-terminated wide character string. The constructor accepts an integer + Represents the C :ctype:`wchar_t *` datatype, which must be a pointer to a + zero-terminated wide character string. The constructor accepts an integer address, or a string. .. class:: c_bool - Represent the C ``bool`` datatype (more accurately, _Bool from C99). Its value - can be True or False, and the constructor accepts any object that has a truth - value. + Represent the C :ctype:`bool` datatype (more accurately, :ctype:`_Bool` from + C99). Its value can be True or False, and the constructor accepts any object + that has a truth value. .. class:: HRESULT - Windows only: Represents a :class:`HRESULT` value, which contains success or + Windows only: Represents a :ctype:`HRESULT` value, which contains success or error information for a function or method call. .. class:: py_object - Represents the C ``PyObject *`` datatype. Calling this without an argument - creates a ``NULL`` ``PyObject *`` pointer. + Represents the C :ctype:`PyObject *` datatype. Calling this without an + argument creates a ``NULL`` :ctype:`PyObject *` pointer. -The ``ctypes.wintypes`` module provides quite some other Windows specific data -types, for example ``HWND``, ``WPARAM``, or ``DWORD``. Some useful structures -like ``MSG`` or ``RECT`` are also defined. +The :mod:`ctypes.wintypes` module provides quite some other Windows specific +data types, for example :ctype:`HWND`, :ctype:`WPARAM`, or :ctype:`DWORD`. Some +useful structures like :ctype:`MSG` or :ctype:`RECT` are also defined. .. _ctypes-structured-data-types: @@ -2382,8 +2388,8 @@ .. attribute:: _anonymous_ An optional sequence that lists the names of unnamed (anonymous) fields. - ``_anonymous_`` must be already defined when :attr:`_fields_` is assigned, - otherwise it will have no effect. + :attr:`_anonymous_` must be already defined when :attr:`_fields_` is + assigned, otherwise it will have no effect. The fields listed in this variable must be structure or union type fields. :mod:`ctypes` will create descriptors in the structure type that allows to @@ -2415,17 +2421,17 @@ td.lptdesc = POINTER(some_type) td.u.lptdesc = POINTER(some_type) -It is possible to defined sub-subclasses of structures, they inherit the fields -of the base class. If the subclass definition has a separate :attr:`_fields_` -variable, the fields specified in this are appended to the fields of the base -class. - -Structure and union constructors accept both positional and keyword arguments. -Positional arguments are used to initialize member fields in the same order as -they are appear in :attr:`_fields_`. Keyword arguments in the constructor are -interpreted as attribute assignments, so they will initialize :attr:`_fields_` -with the same name, or create new attributes for names not present in -:attr:`_fields_`. + It is possible to defined sub-subclasses of structures, they inherit the + fields of the base class. If the subclass definition has a separate + :attr:`_fields_` variable, the fields specified in this are appended to the + fields of the base class. + + Structure and union constructors accept both positional and keyword + arguments. Positional arguments are used to initialize member fields in the + same order as they are appear in :attr:`_fields_`. Keyword arguments in the + constructor are interpreted as attribute assignments, so they will initialize + :attr:`_fields_` with the same name, or create new attributes for names not + present in :attr:`_fields_`. .. _ctypes-arrays-pointers: @@ -2433,6 +2439,6 @@ Arrays and pointers ^^^^^^^^^^^^^^^^^^^ -Not yet written - please see the sections :ref:`ctypes-pointers` and -section :ref:`ctypes-arrays` in the tutorial. +Not yet written - please see the sections :ref:`ctypes-pointers` and section +:ref:`ctypes-arrays` in the tutorial. From python-checkins at python.org Tue Dec 29 12:26:31 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 29 Dec 2009 11:26:31 -0000 Subject: [Python-checkins] r77113 - python/branches/py3k Message-ID: Author: georg.brandl Date: Tue Dec 29 12:26:30 2009 New Revision: 77113 Log: Blocked revisions 77111 via svnmerge ........ r77111 | georg.brandl | 2009-12-29 12:25:38 +0100 (Di, 29 Dez 2009) | 1 line Fix wrong markup. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Dec 29 12:26:40 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 29 Dec 2009 11:26:40 -0000 Subject: [Python-checkins] r77114 - in python/branches/release26-maint: Doc/library/ctypes.rst Message-ID: Author: georg.brandl Date: Tue Dec 29 12:26:39 2009 New Revision: 77114 Log: Merged revisions 77108-77109,77111 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77108 | georg.brandl | 2009-12-29 11:34:34 +0100 (Di, 29 Dez 2009) | 1 line #7569: clarification about c_char_p. ........ r77109 | georg.brandl | 2009-12-29 12:06:31 +0100 (Di, 29 Dez 2009) | 1 line Improve markup of ctypes docs. ........ r77111 | georg.brandl | 2009-12-29 12:25:38 +0100 (Di, 29 Dez 2009) | 1 line Fix wrong markup. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/ctypes.rst Modified: python/branches/release26-maint/Doc/library/ctypes.rst ============================================================================== --- python/branches/release26-maint/Doc/library/ctypes.rst (original) +++ python/branches/release26-maint/Doc/library/ctypes.rst Tue Dec 29 12:26:39 2009 @@ -8,7 +8,7 @@ .. versionadded:: 2.5 -``ctypes`` is a foreign function library for Python. It provides C compatible +:mod:`ctypes` is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python. @@ -18,9 +18,9 @@ ctypes tutorial --------------- -Note: The code samples in this tutorial use ``doctest`` to make sure that they -actually work. Since some code samples behave differently under Linux, Windows, -or Mac OS X, they contain doctest directives in comments. +Note: The code samples in this tutorial use :mod:`doctest` to make sure that +they actually work. Since some code samples behave differently under Linux, +Windows, or Mac OS X, they contain doctest directives in comments. Note: Some code samples reference the ctypes :class:`c_int` type. This type is an alias for the :class:`c_long` type on 32-bit systems. So, you should not be @@ -33,16 +33,16 @@ Loading dynamic link libraries ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``ctypes`` exports the *cdll*, and on Windows *windll* and *oledll* +:mod:`ctypes` exports the *cdll*, and on Windows *windll* and *oledll* objects, for loading dynamic link libraries. You load libraries by accessing them as attributes of these objects. *cdll* loads libraries which export functions using the standard ``cdecl`` calling convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and -assumes the functions return a Windows :class:`HRESULT` error code. The error -code is used to automatically raise a :class:`WindowsError` exception when -the function call fails. +assumes the functions return a Windows :ctype:`HRESULT` error code. The error +code is used to automatically raise a :class:`WindowsError` exception when the +function call fails. Here are some examples for Windows. Note that ``msvcrt`` is the MS standard C library containing most standard C functions, and uses the cdecl calling @@ -112,8 +112,8 @@ respectively. Sometimes, dlls export functions with names which aren't valid Python -identifiers, like ``"??2 at YAPAXI@Z"``. In this case you have to use ``getattr`` -to retrieve the function:: +identifiers, like ``"??2 at YAPAXI@Z"``. In this case you have to use +:func:`getattr` to retrieve the function:: >>> getattr(cdll.msvcrt, "??2 at YAPAXI@Z") # doctest: +WINDOWS <_FuncPtr object at 0x...> @@ -152,8 +152,8 @@ 0x1d000000 >>> -``ctypes`` tries to protect you from calling functions with the wrong number of -arguments or the wrong calling convention. Unfortunately this only works on +:mod:`ctypes` tries to protect you from calling functions with the wrong number +of arguments or the wrong calling convention. Unfortunately this only works on Windows. It does this by examining the stack after the function returns, so although an error is raised the function *has* been called:: @@ -185,7 +185,7 @@ To find out the correct calling convention you have to look into the C header file or the documentation for the function you want to call. -On Windows, ``ctypes`` uses win32 structured exception handling to prevent +On Windows, :mod:`ctypes` uses win32 structured exception handling to prevent crashes from general protection faults when functions are called with invalid argument values:: @@ -195,18 +195,19 @@ WindowsError: exception: access violation reading 0x00000020 >>> -There are, however, enough ways to crash Python with ``ctypes``, so you should -be careful anyway. +There are, however, enough ways to crash Python with :mod:`ctypes`, so you +should be careful anyway. ``None``, integers, longs, byte strings and unicode strings are the only native Python objects that can directly be used as parameters in these function calls. ``None`` is passed as a C ``NULL`` pointer, byte strings and unicode strings are -passed as pointer to the memory block that contains their data (``char *`` or -``wchar_t *``). Python integers and Python longs are passed as the platforms -default C ``int`` type, their value is masked to fit into the C type. +passed as pointer to the memory block that contains their data (:ctype:`char *` +or :ctype:`wchar_t *`). Python integers and Python longs are passed as the +platforms default C :ctype:`int` type, their value is masked to fit into the C +type. Before we move on calling functions with other parameter types, we have to learn -more about ``ctypes`` data types. +more about :mod:`ctypes` data types. .. _ctypes-fundamental-data-types: @@ -214,49 +215,48 @@ Fundamental data types ^^^^^^^^^^^^^^^^^^^^^^ -``ctypes`` defines a number of primitive C compatible data types : - - +----------------------+--------------------------------+----------------------------+ - | ctypes type | C type | Python type | - +======================+================================+============================+ - | :class:`c_char` | ``char`` | 1-character string | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_wchar` | ``wchar_t`` | 1-character unicode string | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_byte` | ``char`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ubyte` | ``unsigned char`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_short` | ``short`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ushort` | ``unsigned short`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_int` | ``int`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_uint` | ``unsigned int`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_long` | ``long`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ulong` | ``unsigned long`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_longlong` | ``__int64`` or ``long long`` | int/long | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_ulonglong` | ``unsigned __int64`` or | int/long | - | | ``unsigned long long`` | | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_float` | ``float`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_double` | ``double`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_longdouble`| ``long double`` | float | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_char_p` | ``char *`` (NUL terminated) | string or ``None`` | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_wchar_p` | ``wchar_t *`` (NUL terminated) | unicode or ``None`` | - +----------------------+--------------------------------+----------------------------+ - | :class:`c_void_p` | ``void *`` | int/long or ``None`` | - +----------------------+--------------------------------+----------------------------+ +:mod:`ctypes` defines a number of primitive C compatible data types : ++----------------------+----------------------------------------+----------------------------+ +| ctypes type | C type | Python type | ++======================+========================================+============================+ +| :class:`c_char` | :ctype:`char` | 1-character string | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_wchar` | :ctype:`wchar_t` | 1-character unicode string | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_byte` | :ctype:`char` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ubyte` | :ctype:`unsigned char` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_short` | :ctype:`short` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ushort` | :ctype:`unsigned short` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_int` | :ctype:`int` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_uint` | :ctype:`unsigned int` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_long` | :ctype:`long` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ulong` | :ctype:`unsigned long` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_longlong` | :ctype:`__int64` or :ctype:`long long` | int/long | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_ulonglong` | :ctype:`unsigned __int64` or | int/long | +| | :ctype:`unsigned long long` | | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_float` | :ctype:`float` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_double` | :ctype:`double` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_longdouble`| :ctype:`long double` | float | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_char_p` | :ctype:`char *` (NUL terminated) | string or ``None`` | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_wchar_p` | :ctype:`wchar_t *` (NUL terminated) | unicode or ``None`` | ++----------------------+----------------------------------------+----------------------------+ +| :class:`c_void_p` | :ctype:`void *` | int/long or ``None`` | ++----------------------+----------------------------------------+----------------------------+ All these types can be created by calling them with an optional initializer of the correct type and value:: @@ -299,7 +299,7 @@ You should be careful, however, not to pass them to functions expecting pointers to mutable memory. If you need mutable memory blocks, ctypes has a -``create_string_buffer`` function which creates these in various ways. The +:func:`create_string_buffer` function which creates these in various ways. The current memory block contents can be accessed (or changed) with the ``raw`` property; if you want to access it as NUL terminated string, use the ``value`` property:: @@ -321,10 +321,11 @@ 10 'Hi\x00lo\x00\x00\x00\x00\x00' >>> -The ``create_string_buffer`` function replaces the ``c_buffer`` function (which -is still available as an alias), as well as the ``c_string`` function from -earlier ctypes releases. To create a mutable memory block containing unicode -characters of the C type ``wchar_t`` use the ``create_unicode_buffer`` function. +The :func:`create_string_buffer` function replaces the :func:`c_buffer` function +(which is still available as an alias), as well as the :func:`c_string` function +from earlier ctypes releases. To create a mutable memory block containing +unicode characters of the C type :ctype:`wchar_t` use the +:func:`create_unicode_buffer` function. .. _ctypes-calling-functions-continued: @@ -333,8 +334,8 @@ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Note that printf prints to the real standard output channel, *not* to -``sys.stdout``, so these examples will only work at the console prompt, not from -within *IDLE* or *PythonWin*:: +:data:`sys.stdout`, so these examples will only work at the console prompt, not +from within *IDLE* or *PythonWin*:: >>> printf = libc.printf >>> printf("Hello, %s\n", "World!") @@ -353,7 +354,7 @@ >>> As has been mentioned before, all Python types except integers, strings, and -unicode strings have to be wrapped in their corresponding ``ctypes`` type, so +unicode strings have to be wrapped in their corresponding :mod:`ctypes` type, so that they can be converted to the required C data type:: >>> printf("An int %d, a double %f\n", 1234, c_double(3.14)) @@ -367,9 +368,9 @@ Calling functions with your own custom data types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can also customize ``ctypes`` argument conversion to allow instances of your -own classes be used as function arguments. ``ctypes`` looks for an -:attr:`_as_parameter_` attribute and uses this as the function argument. Of +You can also customize :mod:`ctypes` argument conversion to allow instances of +your own classes be used as function arguments. :mod:`ctypes` looks for an +:attr:`_as_parameter_` attribute and uses this as the function argument. Of course, it must be one of integer, string, or unicode:: >>> class Bottles(object): @@ -383,7 +384,7 @@ >>> If you don't want to store the instance's data in the :attr:`_as_parameter_` -instance variable, you could define a ``property`` which makes the data +instance variable, you could define a :func:`property` which makes the data available. @@ -425,7 +426,7 @@ whatever is needed to make sure this object is acceptable, and then return the object itself, its :attr:`_as_parameter_` attribute, or whatever you want to pass as the C function argument in this case. Again, the result should be an -integer, string, unicode, a ``ctypes`` instance, or an object with an +integer, string, unicode, a :mod:`ctypes` instance, or an object with an :attr:`_as_parameter_` attribute. @@ -434,9 +435,9 @@ Return types ^^^^^^^^^^^^ -By default functions are assumed to return the C ``int`` type. Other return -types can be specified by setting the :attr:`restype` attribute of the function -object. +By default functions are assumed to return the C :ctype:`int` type. Other +return types can be specified by setting the :attr:`restype` attribute of the +function object. Here is a more advanced example, it uses the ``strchr`` function, which expects a string pointer and a char, and returns a pointer to a string:: @@ -471,7 +472,7 @@ You can also use a callable Python object (a function or a class for example) as the :attr:`restype` attribute, if the foreign function returns an integer. The -callable will be called with the ``integer`` the C function returns, and the +callable will be called with the *integer* the C function returns, and the result of this call will be used as the result of your function call. This is useful to check for error return values and automatically raise an exception:: @@ -510,11 +511,11 @@ probably to write into the corresponding location, or if the data is too large to be passed by value. This is also known as *passing parameters by reference*. -``ctypes`` exports the :func:`byref` function which is used to pass parameters -by reference. The same effect can be achieved with the ``pointer`` function, -although ``pointer`` does a lot more work since it constructs a real pointer -object, so it is faster to use :func:`byref` if you don't need the pointer -object in Python itself:: +:mod:`ctypes` exports the :func:`byref` function which is used to pass +parameters by reference. The same effect can be achieved with the +:func:`pointer` function, although :func:`pointer` does a lot more work since it +constructs a real pointer object, so it is faster to use :func:`byref` if you +don't need the pointer object in Python itself:: >>> i = c_int() >>> f = c_float() @@ -535,16 +536,15 @@ ^^^^^^^^^^^^^^^^^^^^^ Structures and unions must derive from the :class:`Structure` and :class:`Union` -base classes which are defined in the ``ctypes`` module. Each subclass must +base classes which are defined in the :mod:`ctypes` module. Each subclass must define a :attr:`_fields_` attribute. :attr:`_fields_` must be a list of *2-tuples*, containing a *field name* and a *field type*. -The field type must be a ``ctypes`` type like :class:`c_int`, or any other -derived ``ctypes`` type: structure, union, array, pointer. +The field type must be a :mod:`ctypes` type like :class:`c_int`, or any other +derived :mod:`ctypes` type: structure, union, array, pointer. Here is a simple example of a POINT structure, which contains two integers named -``x`` and ``y``, and also shows how to initialize a structure in the -constructor:: +*x* and *y*, and also shows how to initialize a structure in the constructor:: >>> from ctypes import * >>> class POINT(Structure): @@ -566,8 +566,8 @@ You can, however, build much more complicated structures. Structures can itself contain other structures by using a structure as a field type. -Here is a RECT structure which contains two POINTs named ``upperleft`` and -``lowerright`` :: +Here is a RECT structure which contains two POINTs named *upperleft* and +*lowerright*:: >>> class RECT(Structure): ... _fields_ = [("upperleft", POINT), @@ -606,10 +606,11 @@ positive integer and specifies the maximum alignment for the fields. This is what ``#pragma pack(n)`` also does in MSVC. -``ctypes`` uses the native byte order for Structures and Unions. To build +:mod:`ctypes` uses the native byte order for Structures and Unions. To build structures with non-native byte order, you can use one of the -BigEndianStructure, LittleEndianStructure, BigEndianUnion, and LittleEndianUnion -base classes. These classes cannot contain pointer fields. +:class:`BigEndianStructure`, :class:`LittleEndianStructure`, +:class:`BigEndianUnion`, and :class:`LittleEndianUnion` base classes. These +classes cannot contain pointer fields. .. _ctypes-bit-fields-in-structures-unions: @@ -687,22 +688,22 @@ Pointers ^^^^^^^^ -Pointer instances are created by calling the ``pointer`` function on a -``ctypes`` type:: +Pointer instances are created by calling the :func:`pointer` function on a +:mod:`ctypes` type:: >>> from ctypes import * >>> i = c_int(42) >>> pi = pointer(i) >>> -Pointer instances have a ``contents`` attribute which returns the object to +Pointer instances have a :attr:`contents` attribute which returns the object to which the pointer points, the ``i`` object above:: >>> pi.contents c_long(42) >>> -Note that ``ctypes`` does not have OOR (original object return), it constructs a +Note that :mod:`ctypes` does not have OOR (original object return), it constructs a new, equivalent object each time you retrieve an attribute:: >>> pi.contents is i @@ -720,7 +721,8 @@ c_long(99) >>> -.. XXX Document dereferencing pointers, and that it is preferred over the .contents attribute. +.. XXX Document dereferencing pointers, and that it is preferred over the + .contents attribute. Pointer instances can also be indexed with integers:: @@ -743,10 +745,10 @@ and you *know* that the pointer actually points to an array instead of a single item. -Behind the scenes, the ``pointer`` function does more than simply create pointer -instances, it has to create pointer *types* first. This is done with the -``POINTER`` function, which accepts any ``ctypes`` type, and returns a new -type:: +Behind the scenes, the :func:`pointer` function does more than simply create +pointer instances, it has to create pointer *types* first. This is done with +the :func:`POINTER` function, which accepts any :mod:`ctypes` type, and returns +a new type:: >>> PI = POINTER(c_int) >>> PI @@ -767,7 +769,7 @@ False >>> -``ctypes`` checks for ``NULL`` when dereferencing pointers (but dereferencing +:mod:`ctypes` checks for ``NULL`` when dereferencing pointers (but dereferencing invalid non-\ ``NULL`` pointers would crash Python):: >>> null_ptr[0] @@ -816,8 +818,8 @@ .. XXX list other conversions... -Sometimes you have instances of incompatible types. In C, you can cast one -type into another type. ``ctypes`` provides a ``cast`` function which can be +Sometimes you have instances of incompatible types. In C, you can cast one type +into another type. :mod:`ctypes` provides a :func:`cast` function which can be used in the same way. The ``Bar`` structure defined above accepts ``POINTER(c_int)`` pointers or :class:`c_int` arrays for its ``values`` field, but not instances of other types:: @@ -828,20 +830,20 @@ TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance >>> -For these cases, the ``cast`` function is handy. +For these cases, the :func:`cast` function is handy. -The ``cast`` function can be used to cast a ctypes instance into a pointer to a -different ctypes data type. ``cast`` takes two parameters, a ctypes object that -is or can be converted to a pointer of some kind, and a ctypes pointer type. It -returns an instance of the second argument, which references the same memory -block as the first argument:: +The :func:`cast` function can be used to cast a ctypes instance into a pointer +to a different ctypes data type. :func:`cast` takes two parameters, a ctypes +object that is or can be converted to a pointer of some kind, and a ctypes +pointer type. It returns an instance of the second argument, which references +the same memory block as the first argument:: >>> a = (c_byte * 4)() >>> cast(a, POINTER(c_int)) >>> -So, ``cast`` can be used to assign to the ``values`` field of ``Bar`` the +So, :func:`cast` can be used to assign to the ``values`` field of ``Bar`` the structure:: >>> bar = Bar() @@ -881,7 +883,7 @@ >>> because the new ``class cell`` is not available in the class statement itself. -In ``ctypes``, we can define the ``cell`` class and set the :attr:`_fields_` +In :mod:`ctypes`, we can define the ``cell`` class and set the :attr:`_fields_` attribute later, after the class statement:: >>> from ctypes import * @@ -915,7 +917,7 @@ Callback functions ^^^^^^^^^^^^^^^^^^ -``ctypes`` allows to create C callable function pointers from Python callables. +:mod:`ctypes` allows to create C callable function pointers from Python callables. These are sometimes called *callback functions*. First, you must create a class for the callback function, the class knows the @@ -1064,7 +1066,7 @@ **Important note for callback functions:** Make sure you keep references to CFUNCTYPE objects as long as they are used from -C code. ``ctypes`` doesn't, and if you don't, they may be garbage collected, +C code. :mod:`ctypes` doesn't, and if you don't, they may be garbage collected, crashing your program when a callback is made. @@ -1078,7 +1080,7 @@ to 0, 1, or 2, depending on the :option:`-O` or :option:`-OO` flag given on startup. -``ctypes`` can access values like this with the :meth:`in_dll` class methods of +:mod:`ctypes` can access values like this with the :meth:`in_dll` class methods of the type. *pythonapi* is a predefined symbol giving access to the Python C api:: @@ -1101,7 +1103,7 @@ frozen modules.* So manipulating this pointer could even prove useful. To restrict the example -size, we show only how this table can be read with ``ctypes``:: +size, we show only how this table can be read with :mod:`ctypes`:: >>> from ctypes import * >>> @@ -1146,7 +1148,7 @@ Surprises ^^^^^^^^^ -There are some edges in ``ctypes`` where you may be expect something else than +There are some edges in :mod:`ctypes` where you may be expect something else than what actually happens. Consider the following example:: @@ -1209,13 +1211,13 @@ Variable-sized data types ^^^^^^^^^^^^^^^^^^^^^^^^^ -``ctypes`` provides some support for variable-sized arrays and structures. +:mod:`ctypes` provides some support for variable-sized arrays and structures. -The ``resize`` function can be used to resize the memory buffer of an existing -ctypes object. The function takes the object as first argument, and the -requested size in bytes as the second argument. The memory block cannot be made -smaller than the natural memory block specified by the objects type, a -``ValueError`` is raised if this is tried:: +The :func:`resize` function can be used to resize the memory buffer of an +existing ctypes object. The function takes the object as first argument, and +the requested size in bytes as the second argument. The memory block cannot be +made smaller than the natural memory block specified by the objects type, a +:exc:`ValueError` is raised if this is tried:: >>> short_array = (c_short * 4)() >>> print sizeof(short_array) @@ -1243,7 +1245,7 @@ IndexError: invalid index >>> -Another way to use variable-sized data types with ``ctypes`` is to use the +Another way to use variable-sized data types with :mod:`ctypes` is to use the dynamic nature of Python, and (re-)define the data type after the required size is already known, on a case by case basis. @@ -1262,12 +1264,12 @@ When programming in a compiled language, shared libraries are accessed when compiling/linking a program, and when the program is run. -The purpose of the ``find_library`` function is to locate a library in a way +The purpose of the :func:`find_library` function is to locate a library in a way similar to what the compiler does (on platforms with several versions of a shared library the most recent should be loaded), while the ctypes library loaders act like when a program is run, and call the runtime loader directly. -The ``ctypes.util`` module provides a function which can help to determine the +The :mod:`ctypes.util` module provides a function which can help to determine the library to load. @@ -1282,9 +1284,9 @@ The exact functionality is system dependent. -On Linux, ``find_library`` tries to run external programs (/sbin/ldconfig, gcc, -and objdump) to find the library file. It returns the filename of the library -file. Here are some examples:: +On Linux, :func:`find_library` tries to run external programs +(``/sbin/ldconfig``, ``gcc``, and ``objdump``) to find the library file. It +returns the filename of the library file. Here are some examples:: >>> from ctypes.util import find_library >>> find_library("m") @@ -1295,8 +1297,8 @@ 'libbz2.so.1.0' >>> -On OS X, ``find_library`` tries several predefined naming schemes and paths to -locate the library, and returns a full pathname if successful:: +On OS X, :func:`find_library` tries several predefined naming schemes and paths +to locate the library, and returns a full pathname if successful:: >>> from ctypes.util import find_library >>> find_library("c") @@ -1309,13 +1311,13 @@ '/System/Library/Frameworks/AGL.framework/AGL' >>> -On Windows, ``find_library`` searches along the system search path, and returns -the full pathname, but since there is no predefined naming scheme a call like -``find_library("c")`` will fail and return ``None``. +On Windows, :func:`find_library` searches along the system search path, and +returns the full pathname, but since there is no predefined naming scheme a call +like ``find_library("c")`` will fail and return ``None``. -If wrapping a shared library with ``ctypes``, it *may* be better to determine +If wrapping a shared library with :mod:`ctypes`, it *may* be better to determine the shared library name at development type, and hardcode that into the wrapper -module instead of using ``find_library`` to locate the library at runtime. +module instead of using :func:`find_library` to locate the library at runtime. .. _ctypes-loading-shared-libraries: @@ -1331,7 +1333,7 @@ Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return - ``int``. + :ctype:`int`. .. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False) @@ -1348,7 +1350,7 @@ Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the ``stdcall`` calling convention, and are - assumed to return ``int`` by default. + assumed to return :ctype:`int` by default. On Windows CE only the standard calling convention is used, for convenience the :class:`WinDLL` and :class:`OleDLL` use the standard calling convention on this @@ -1370,12 +1372,13 @@ All these classes can be instantiated by calling them with at least one argument, the pathname of the shared library. If you have an existing handle to an already loaded shared library, it can be passed as the ``handle`` named -parameter, otherwise the underlying platforms ``dlopen`` or :meth:`LoadLibrary` +parameter, otherwise the underlying platforms ``dlopen`` or ``LoadLibrary`` function is used to load the library into the process, and to get a handle to it. The *mode* parameter can be used to specify how the library is loaded. For -details, consult the ``dlopen(3)`` manpage, on Windows, *mode* is ignored. +details, consult the :manpage:`dlopen(3)` manpage, on Windows, *mode* is +ignored. The *use_errno* parameter, when set to True, enables a ctypes mechanism that allows to access the system :data:`errno` error number in a safe way. @@ -1395,8 +1398,7 @@ copy of the windows error code. .. versionadded:: 2.6 - The ``use_last_error`` and ``use_errno`` optional parameters - were added. + The *use_last_error* and *use_errno* optional parameters were added. .. data:: RTLD_GLOBAL :noindex: @@ -1445,7 +1447,7 @@ .. class:: LibraryLoader(dlltype) - Class which loads shared libraries. ``dlltype`` should be one of the + Class which loads shared libraries. *dlltype* should be one of the :class:`CDLL`, :class:`PyDLL`, :class:`WinDLL`, or :class:`OleDLL` types. :meth:`__getattr__` has special behavior: It allows to load a shared library by @@ -1491,10 +1493,10 @@ .. data:: pythonapi :noindex: - An instance of :class:`PyDLL` that exposes Python C api functions as attributes. - Note that all these functions are assumed to return C ``int``, which is of - course not always the truth, so you have to assign the correct :attr:`restype` - attribute to use these functions. + An instance of :class:`PyDLL` that exposes Python C API functions as + attributes. Note that all these functions are assumed to return C + :ctype:`int`, which is of course not always the truth, so you have to assign + the correct :attr:`restype` attribute to use these functions. .. _ctypes-foreign-functions: @@ -1523,11 +1525,11 @@ .. attribute:: restype Assign a ctypes type to specify the result type of the foreign function. - Use ``None`` for ``void`` a function not returning anything. + Use ``None`` for :ctype:`void`, a function not returning anything. It is possible to assign a callable Python object that is not a ctypes - type, in this case the function is assumed to return a C ``int``, and the - callable will be called with this integer, allowing to do further + type, in this case the function is assumed to return a C :ctype:`int`, and + the callable will be called with this integer, allowing to do further processing or error checking. Using this is deprecated, for more flexible post processing or error checking use a ctypes data type as :attr:`restype` and assign a callable to the :attr:`errcheck` attribute. @@ -1562,16 +1564,16 @@ .. function:: callable(result, func, arguments) :noindex: - ``result`` is what the foreign function returns, as specified - by the :attr:`restype` attribute. + *result* is what the foreign function returns, as specified by the + :attr:`restype` attribute. - ``func`` is the foreign function object itself, this allows - to reuse the same callable object to check or post process - the results of several functions. - - ``arguments`` is a tuple containing the parameters originally - passed to the function call, this allows to specialize the - behavior on the arguments used. + *func* is the foreign function object itself, this allows to reuse the + same callable object to check or post process the results of several + functions. + + *arguments* is a tuple containing the parameters originally passed to + the function call, this allows to specialize the behavior on the + arguments used. The object that this function returns will be returned from the foreign function call, but it can also check the result value @@ -1638,14 +1640,14 @@ :noindex: :module: - Create a C callable function (a callback function) from a Python ``callable``. + Create a C callable function (a callback function) from a Python *callable*. .. function:: prototype(func_spec[, paramflags]) :noindex: :module: - Returns a foreign function exported by a shared library. ``func_spec`` must be a + Returns a foreign function exported by a shared library. *func_spec* must be a 2-tuple ``(name_or_ordinal, library)``. The first item is the name of the exported function as string, or the ordinal of the exported function as small integer. The second item is the shared library instance. @@ -1655,7 +1657,7 @@ :noindex: :module: - Returns a foreign function that will call a COM method. ``vtbl_index`` is the + Returns a foreign function that will call a COM method. *vtbl_index* is the index into the virtual function table, a small non-negative integer. *name* is name of the COM method. *iid* is an optional pointer to the interface identifier which is used in extended error reporting. @@ -1700,7 +1702,7 @@ LPCSTR lpCaption, UINT uType); -Here is the wrapping with ``ctypes``:: +Here is the wrapping with :mod:`ctypes`:: >>> from ctypes import c_int, WINFUNCTYPE, windll >>> from ctypes.wintypes import HWND, LPCSTR, UINT @@ -1725,7 +1727,7 @@ HWND hWnd, LPRECT lpRect); -Here is the wrapping with ``ctypes``:: +Here is the wrapping with :mod:`ctypes`:: >>> from ctypes import POINTER, WINFUNCTYPE, windll, WinError >>> from ctypes.wintypes import BOOL, HWND, RECT @@ -1753,7 +1755,7 @@ >>> If the :attr:`errcheck` function returns the argument tuple it receives -unchanged, ``ctypes`` continues the normal processing it does on the output +unchanged, :mod:`ctypes` continues the normal processing it does on the output parameters. If you want to return a tuple of window coordinates instead of a ``RECT`` instance, you can retrieve the fields in the function and return them instead, the normal processing will no longer take place:: @@ -1776,21 +1778,21 @@ .. function:: addressof(obj) - Returns the address of the memory buffer as integer. ``obj`` must be an + Returns the address of the memory buffer as integer. *obj* must be an instance of a ctypes type. .. function:: alignment(obj_or_type) - Returns the alignment requirements of a ctypes type. ``obj_or_type`` must be a + Returns the alignment requirements of a ctypes type. *obj_or_type* must be a ctypes type or instance. .. function:: byref(obj[, offset]) - Returns a light-weight pointer to ``obj``, which must be an - instance of a ctypes type. ``offset`` defaults to zero, and must be - an integer that will be added to the internal pointer value. + Returns a light-weight pointer to *obj*, which must be an instance of a + ctypes type. *offset* defaults to zero, and must be an integer that will be + added to the internal pointer value. ``byref(obj, offset)`` corresponds to this C code:: @@ -1801,14 +1803,15 @@ construction is a lot faster. .. versionadded:: 2.6 - The ``offset`` optional argument was added. + The *offset* optional argument was added. + .. function:: cast(obj, type) - This function is similar to the cast operator in C. It returns a new instance of - ``type`` which points to the same memory block as ``obj``. ``type`` must be a - pointer type, and ``obj`` must be an object that can be interpreted as a - pointer. + This function is similar to the cast operator in C. It returns a new + instance of *type* which points to the same memory block as *obj*. *type* + must be a pointer type, and *obj* must be an object that can be interpreted + as a pointer. .. function:: create_string_buffer(init_or_size[, size]) @@ -1816,7 +1819,7 @@ This function creates a mutable character buffer. The returned object is a ctypes array of :class:`c_char`. - ``init_or_size`` must be an integer which specifies the size of the array, or a + *init_or_size* must be an integer which specifies the size of the array, or a string which will be used to initialize the array items. If a string is specified as first argument, the buffer is made one item larger @@ -1833,7 +1836,7 @@ This function creates a mutable unicode character buffer. The returned object is a ctypes array of :class:`c_wchar`. - ``init_or_size`` must be an integer which specifies the size of the array, or a + *init_or_size* must be an integer which specifies the size of the array, or a unicode string which will be used to initialize the array items. If a unicode string is specified as first argument, the buffer is made one item @@ -1848,16 +1851,17 @@ .. function:: DllCanUnloadNow() - Windows only: This function is a hook which allows to implement in-process COM - servers with ctypes. It is called from the DllCanUnloadNow function that the - _ctypes extension dll exports. + Windows only: This function is a hook which allows to implement in-process + COM servers with ctypes. It is called from the DllCanUnloadNow function that + the _ctypes extension dll exports. .. function:: DllGetClassObject() - Windows only: This function is a hook which allows to implement in-process COM - servers with ctypes. It is called from the DllGetClassObject function that the - ``_ctypes`` extension dll exports. + Windows only: This function is a hook which allows to implement in-process + COM servers with ctypes. It is called from the DllGetClassObject function + that the ``_ctypes`` extension dll exports. + .. function:: find_library(name) :module: ctypes.util @@ -1870,28 +1874,29 @@ The exact functionality is system dependent. .. versionchanged:: 2.6 - Windows only: ``find_library("m")`` or - ``find_library("c")`` return the result of a call to - ``find_msvcrt()``. + Windows only: ``find_library("m")`` or ``find_library("c")`` return the + result of a call to ``find_msvcrt()``. + .. function:: find_msvcrt() :module: ctypes.util - Windows only: return the filename of the VC runtype library used - by Python, and by the extension modules. If the name of the - library cannot be determined, ``None`` is returned. - - If you need to free memory, for example, allocated by an extension - module with a call to the ``free(void *)``, it is important that you - use the function in the same library that allocated the memory. + Windows only: return the filename of the VC runtype library used by Python, + and by the extension modules. If the name of the library cannot be + determined, ``None`` is returned. + + If you need to free memory, for example, allocated by an extension module + with a call to the ``free(void *)``, it is important that you use the + function in the same library that allocated the memory. .. versionadded:: 2.6 + .. function:: FormatError([code]) - Windows only: Returns a textual description of the error code. If no error code - is specified, the last error code is used by calling the Windows api function - GetLastError. + Windows only: Returns a textual description of the error code *code*. If no + error code is specified, the last error code is used by calling the Windows + api function GetLastError. .. function:: GetLastError() @@ -1917,8 +1922,8 @@ .. function:: memmove(dst, src, count) Same as the standard C memmove library function: copies *count* bytes from - ``src`` to *dst*. *dst* and ``src`` must be integers or ctypes instances that - can be converted to pointers. + *src* to *dst*. *dst* and *src* must be integers or ctypes instances that can + be converted to pointers. .. function:: memset(dst, c, count) @@ -1932,13 +1937,13 @@ This factory function creates and returns a new ctypes pointer type. Pointer types are cached an reused internally, so calling this function repeatedly is - cheap. type must be a ctypes type. + cheap. *type* must be a ctypes type. .. function:: pointer(obj) - This function creates a new pointer instance, pointing to ``obj``. The returned - object is of the type POINTER(type(obj)). + This function creates a new pointer instance, pointing to *obj*. The returned + object is of the type ``POINTER(type(obj))``. Note: If you just want to pass a pointer to an object to a foreign function call, you should use ``byref(obj)`` which is much faster. @@ -1946,23 +1951,23 @@ .. function:: resize(obj, size) - This function resizes the internal memory buffer of obj, which must be an - instance of a ctypes type. It is not possible to make the buffer smaller than - the native size of the objects type, as given by sizeof(type(obj)), but it is - possible to enlarge the buffer. + This function resizes the internal memory buffer of *obj*, which must be an + instance of a ctypes type. It is not possible to make the buffer smaller + than the native size of the objects type, as given by ``sizeof(type(obj))``, + but it is possible to enlarge the buffer. .. function:: set_conversion_mode(encoding, errors) This function sets the rules that ctypes objects use when converting between - 8-bit strings and unicode strings. encoding must be a string specifying an - encoding, like ``'utf-8'`` or ``'mbcs'``, errors must be a string specifying the - error handling on encoding/decoding errors. Examples of possible values are - ``"strict"``, ``"replace"``, or ``"ignore"``. - - ``set_conversion_mode`` returns a 2-tuple containing the previous conversion - rules. On windows, the initial conversion rules are ``('mbcs', 'ignore')``, on - other systems ``('ascii', 'strict')``. + 8-bit strings and unicode strings. *encoding* must be a string specifying an + encoding, like ``'utf-8'`` or ``'mbcs'``, *errors* must be a string + specifying the error handling on encoding/decoding errors. Examples of + possible values are ``"strict"``, ``"replace"``, or ``"ignore"``. + + :func:`set_conversion_mode` returns a 2-tuple containing the previous + conversion rules. On windows, the initial conversion rules are ``('mbcs', + 'ignore')``, on other systems ``('ascii', 'strict')``. .. function:: set_errno(value) @@ -1972,6 +1977,7 @@ .. versionadded:: 2.6 + .. function:: set_last_error(value) Windows only: set the current value of the ctypes-private copy of the system @@ -1980,6 +1986,7 @@ .. versionadded:: 2.6 + .. function:: sizeof(obj_or_type) Returns the size in bytes of a ctypes type or instance memory buffer. Does the @@ -1995,17 +2002,17 @@ .. function:: WinError(code=None, descr=None) - Windows only: this function is probably the worst-named thing in ctypes. It - creates an instance of WindowsError. If *code* is not specified, - ``GetLastError`` is called to determine the error code. If ``descr`` is not + Windows only: this function is probably the worst-named thing in ctypes. It + creates an instance of WindowsError. If *code* is not specified, + ``GetLastError`` is called to determine the error code. If ``descr`` is not specified, :func:`FormatError` is called to get a textual description of the error. -.. function:: wstring_at(address) +.. function:: wstring_at(address[, size]) This function returns the wide character string starting at memory address - ``address`` as unicode string. If ``size`` is specified, it is used as the + *address* as unicode string. If *size* is specified, it is used as the number of characters of the string, otherwise the string is assumed to be zero-terminated. @@ -2018,12 +2025,12 @@ .. class:: _CData - This non-public class is the common base class of all ctypes data types. Among - other things, all ctypes type instances contain a memory block that hold C - compatible data; the address of the memory block is returned by the - ``addressof()`` helper function. Another instance variable is exposed as - :attr:`_objects`; this contains other Python objects that need to be kept alive - in case the memory block contains pointers. + This non-public class is the common base class of all ctypes data types. + Among other things, all ctypes type instances contain a memory block that + hold C compatible data; the address of the memory block is returned by the + :func:`addressof` helper function. Another instance variable is exposed as + :attr:`_objects`; this contains other Python objects that need to be kept + alive in case the memory block contains pointers. Common methods of ctypes data types, these are all class methods (to be exact, they are methods of the :term:`metaclass`): @@ -2031,22 +2038,22 @@ .. method:: _CData.from_buffer(source[, offset]) - This method returns a ctypes instance that shares the buffer of - the ``source`` object. The ``source`` object must support the - writeable buffer interface. The optional ``offset`` parameter - specifies an offset into the source buffer in bytes; the default - is zero. If the source buffer is not large enough a ValueError - is raised. + This method returns a ctypes instance that shares the buffer of the + *source* object. The *source* object must support the writeable buffer + interface. The optional *offset* parameter specifies an offset into the + source buffer in bytes; the default is zero. If the source buffer is not + large enough a :exc:`ValueError` is raised. .. versionadded:: 2.6 + .. method:: _CData.from_buffer_copy(source[, offset]) - This method creates a ctypes instance, copying the buffer from - the source object buffer which must be readable. The optional - ``offset`` parameter specifies an offset into the source buffer - in bytes; the default is zero. If the source buffer is not - large enough a ValueError is raised. + This method creates a ctypes instance, copying the buffer from the + *source* object buffer which must be readable. The optional *offset* + parameter specifies an offset into the source buffer in bytes; the default + is zero. If the source buffer is not large enough a :exc:`ValueError` is + raised. .. versionadded:: 2.6 @@ -2054,7 +2061,7 @@ .. method:: from_address(address) This method returns a ctypes type instance using the memory specified by - address which must be an integer. + *address* which must be an integer. .. method:: from_param(obj) @@ -2065,7 +2072,7 @@ can be used as a function call parameter. All ctypes data types have a default implementation of this classmethod - that normally returns ``obj`` if that is an instance of the type. Some + that normally returns *obj* if that is an instance of the type. Some types accept other objects as well. @@ -2078,7 +2085,6 @@ Common instance variables of ctypes data types: - .. attribute:: _b_base_ Sometimes ctypes data instances do not own the memory block they contain, @@ -2109,18 +2115,17 @@ .. class:: _SimpleCData - This non-public class is the base class of all fundamental ctypes data types. It - is mentioned here because it contains the common attributes of the fundamental - ctypes data types. ``_SimpleCData`` is a subclass of ``_CData``, so it inherits - their methods and attributes. + This non-public class is the base class of all fundamental ctypes data + types. It is mentioned here because it contains the common attributes of the + fundamental ctypes data types. :class:`_SimpleCData` is a subclass of + :class:`_CData`, so it inherits their methods and attributes. .. versionchanged:: 2.6 - ctypes data types that are not and do not contain pointers can - now be pickled. + ctypes data types that are not and do not contain pointers can now be + pickled. Instances have a single attribute: - .. attribute:: value This attribute contains the actual value of the instance. For integer and @@ -2129,10 +2134,11 @@ unicode string. When the ``value`` attribute is retrieved from a ctypes instance, usually - a new object is returned each time. ``ctypes`` does *not* implement + a new object is returned each time. :mod:`ctypes` does *not* implement original object return, always a new object is constructed. The same is true for all other ctypes object instances. + Fundamental data types, when returned as foreign function call results, or, for example, by retrieving structure field members or array items, are transparently converted to native Python types. In other words, if a foreign function has a @@ -2146,200 +2152,201 @@ These are the fundamental ctypes data types: - .. class:: c_byte - Represents the C signed char datatype, and interprets the value as small - integer. The constructor accepts an optional integer initializer; no overflow - checking is done. + Represents the C :ctype:`signed char` datatype, and interprets the value as + small integer. The constructor accepts an optional integer initializer; no + overflow checking is done. .. class:: c_char - Represents the C char datatype, and interprets the value as a single character. - The constructor accepts an optional string initializer, the length of the string - must be exactly one character. + Represents the C :ctype:`char` datatype, and interprets the value as a single + character. The constructor accepts an optional string initializer, the + length of the string must be exactly one character. .. class:: c_char_p - Represents the C char \* datatype, which must be a pointer to a zero-terminated - string. The constructor accepts an integer address, or a string. + Represents the C :ctype:`char *` datatype when it points to a zero-terminated + string. For a general character pointer that may also point to binary data, + ``POINTER(c_char)`` must be used. The constructor accepts an integer + address, or a string. .. class:: c_double - Represents the C double datatype. The constructor accepts an optional float - initializer. + Represents the C :ctype:`double` datatype. The constructor accepts an + optional float initializer. .. class:: c_longdouble - Represents the C long double datatype. The constructor accepts an - optional float initializer. On platforms where ``sizeof(long - double) == sizeof(double)`` it is an alias to :class:`c_double`. + Represents the C :ctype:`long double` datatype. The constructor accepts an + optional float initializer. On platforms where ``sizeof(long double) == + sizeof(double)`` it is an alias to :class:`c_double`. .. versionadded:: 2.6 .. class:: c_float - Represents the C float datatype. The constructor accepts an optional float - initializer. + Represents the C :ctype:`float` datatype. The constructor accepts an + optional float initializer. .. class:: c_int - Represents the C signed int datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. On platforms where - ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`. + Represents the C :ctype:`signed int` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. On platforms + where ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`. .. class:: c_int8 - Represents the C 8-bit ``signed int`` datatype. Usually an alias for + Represents the C 8-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_byte`. .. class:: c_int16 - Represents the C 16-bit signed int datatype. Usually an alias for + Represents the C 16-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_short`. .. class:: c_int32 - Represents the C 32-bit signed int datatype. Usually an alias for + Represents the C 32-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_int`. .. class:: c_int64 - Represents the C 64-bit ``signed int`` datatype. Usually an alias for + Represents the C 64-bit :ctype:`signed int` datatype. Usually an alias for :class:`c_longlong`. .. class:: c_long - Represents the C ``signed long`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`signed long` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_longlong - Represents the C ``signed long long`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`signed long long` datatype. The constructor accepts + an optional integer initializer; no overflow checking is done. .. class:: c_short - Represents the C ``signed short`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`signed short` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_size_t - Represents the C ``size_t`` datatype. + Represents the C :ctype:`size_t` datatype. .. class:: c_ubyte - Represents the C ``unsigned char`` datatype, it interprets the value as small - integer. The constructor accepts an optional integer initializer; no overflow - checking is done. + Represents the C :ctype:`unsigned char` datatype, it interprets the value as + small integer. The constructor accepts an optional integer initializer; no + overflow checking is done. .. class:: c_uint - Represents the C ``unsigned int`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. On platforms where - ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`. + Represents the C :ctype:`unsigned int` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. On platforms + where ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`. .. class:: c_uint8 - Represents the C 8-bit unsigned int datatype. Usually an alias for + Represents the C 8-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ubyte`. .. class:: c_uint16 - Represents the C 16-bit unsigned int datatype. Usually an alias for + Represents the C 16-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ushort`. .. class:: c_uint32 - Represents the C 32-bit unsigned int datatype. Usually an alias for + Represents the C 32-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_uint`. .. class:: c_uint64 - Represents the C 64-bit unsigned int datatype. Usually an alias for + Represents the C 64-bit :ctype:`unsigned int` datatype. Usually an alias for :class:`c_ulonglong`. .. class:: c_ulong - Represents the C ``unsigned long`` datatype. The constructor accepts an optional - integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned long` datatype. The constructor accepts an + optional integer initializer; no overflow checking is done. .. class:: c_ulonglong - Represents the C ``unsigned long long`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned long long` datatype. The constructor + accepts an optional integer initializer; no overflow checking is done. .. class:: c_ushort - Represents the C ``unsigned short`` datatype. The constructor accepts an - optional integer initializer; no overflow checking is done. + Represents the C :ctype:`unsigned short` datatype. The constructor accepts + an optional integer initializer; no overflow checking is done. .. class:: c_void_p - Represents the C ``void *`` type. The value is represented as integer. The - constructor accepts an optional integer initializer. + Represents the C :ctype:`void *` type. The value is represented as integer. + The constructor accepts an optional integer initializer. .. class:: c_wchar - Represents the C ``wchar_t`` datatype, and interprets the value as a single - character unicode string. The constructor accepts an optional string + Represents the C :ctype:`wchar_t` datatype, and interprets the value as a + single character unicode string. The constructor accepts an optional string initializer, the length of the string must be exactly one character. .. class:: c_wchar_p - Represents the C ``wchar_t *`` datatype, which must be a pointer to a - zero-terminated wide character string. The constructor accepts an integer + Represents the C :ctype:`wchar_t *` datatype, which must be a pointer to a + zero-terminated wide character string. The constructor accepts an integer address, or a string. .. class:: c_bool - Represent the C ``bool`` datatype (more accurately, _Bool from C99). Its value - can be True or False, and the constructor accepts any object that has a truth - value. + Represent the C :ctype:`bool` datatype (more accurately, :ctype:`_Bool` from + C99). Its value can be True or False, and the constructor accepts any object + that has a truth value. .. versionadded:: 2.6 .. class:: HRESULT - Windows only: Represents a :class:`HRESULT` value, which contains success or + Windows only: Represents a :ctype:`HRESULT` value, which contains success or error information for a function or method call. .. class:: py_object - Represents the C ``PyObject *`` datatype. Calling this without an argument - creates a ``NULL`` ``PyObject *`` pointer. + Represents the C :ctype:`PyObject *` datatype. Calling this without an + argument creates a ``NULL`` :ctype:`PyObject *` pointer. -The ``ctypes.wintypes`` module provides quite some other Windows specific data -types, for example ``HWND``, ``WPARAM``, or ``DWORD``. Some useful structures -like ``MSG`` or ``RECT`` are also defined. +The :mod:`ctypes.wintypes` module provides quite some other Windows specific +data types, for example :ctype:`HWND`, :ctype:`WPARAM`, or :ctype:`DWORD`. Some +useful structures like :ctype:`MSG` or :ctype:`RECT` are also defined. .. _ctypes-structured-data-types: @@ -2371,7 +2378,7 @@ Abstract base class for structures in *native* byte order. Concrete structure and union types must be created by subclassing one of these - types, and at least define a :attr:`_fields_` class variable. ``ctypes`` will + types, and at least define a :attr:`_fields_` class variable. :mod:`ctypes` will create :term:`descriptor`\s which allow reading and writing the fields by direct attribute accesses. These are the @@ -2424,11 +2431,11 @@ .. attribute:: _anonymous_ An optional sequence that lists the names of unnamed (anonymous) fields. - ``_anonymous_`` must be already defined when :attr:`_fields_` is assigned, - otherwise it will have no effect. + :attr:`_anonymous_` must be already defined when :attr:`_fields_` is + assigned, otherwise it will have no effect. The fields listed in this variable must be structure or union type fields. - ``ctypes`` will create descriptors in the structure type that allows to + :mod:`ctypes` will create descriptors in the structure type that allows to access the nested fields directly, without the need to create the structure or union field. @@ -2457,17 +2464,17 @@ td.lptdesc = POINTER(some_type) td.u.lptdesc = POINTER(some_type) -It is possible to defined sub-subclasses of structures, they inherit the fields -of the base class. If the subclass definition has a separate :attr:`_fields_` -variable, the fields specified in this are appended to the fields of the base -class. - -Structure and union constructors accept both positional and keyword arguments. -Positional arguments are used to initialize member fields in the same order as -they are appear in :attr:`_fields_`. Keyword arguments in the constructor are -interpreted as attribute assignments, so they will initialize :attr:`_fields_` -with the same name, or create new attributes for names not present in -:attr:`_fields_`. + It is possible to defined sub-subclasses of structures, they inherit the + fields of the base class. If the subclass definition has a separate + :attr:`_fields_` variable, the fields specified in this are appended to the + fields of the base class. + + Structure and union constructors accept both positional and keyword + arguments. Positional arguments are used to initialize member fields in the + same order as they are appear in :attr:`_fields_`. Keyword arguments in the + constructor are interpreted as attribute assignments, so they will initialize + :attr:`_fields_` with the same name, or create new attributes for names not + present in :attr:`_fields_`. .. _ctypes-arrays-pointers: @@ -2475,6 +2482,6 @@ Arrays and pointers ^^^^^^^^^^^^^^^^^^^ -Not yet written - please see the sections :ref:`ctypes-pointers` and -section :ref:`ctypes-arrays` in the tutorial. +Not yet written - please see the sections :ref:`ctypes-pointers` and section +:ref:`ctypes-arrays` in the tutorial. From rdmurray at bitdance.com Tue Dec 29 15:30:14 2009 From: rdmurray at bitdance.com (R. David Murray) Date: Tue, 29 Dec 2009 09:30:14 -0500 Subject: [Python-checkins] r77056 - peps/trunk/pep-0345.txt In-Reply-To: <20091225132922.99DF91FA647@kimball.webabinitio.net> References: <20091225132922.99DF91FA647@kimball.webabinitio.net> Message-ID: <20091229143015.02BBF1FA329@kimball.webabinitio.net> On Fri, 25 Dec 2009 08:29:22 -0500, tarek.ziade wrote: tarek.ziade wrote: > +To support empty lines and lines with indentation with respect to > +the RFC 822 format, any new line has to be suffixed by 7 spaces > +followed by a pipe (`|`) char. As a result, the Description field is > +encoded into a folded field that can be interpreted by RFC822 > +parser [2]_. > + > Example:: > [...] > + Description: This project provides powerful math functions > + |For example, you can use `sum()` to sum numbers: > + | > + |Example:: > + | > + | >>> sum(1, 2) > + | 3 > + | > + > +This encoding implies that any occurences of ``\n |`` have to be replaced > +by ``\n`` when the field is unfolded using a RFC822 reader. Actually, a properly operating RFC[2]822 parser will unfold the header by removing the CFLF. So the correct method of restoring the line breaks would be to replace the seven-spaces-plus-'|' with a \n. (See RFC2822, section 2.2.3). Unfortunately, Python's email package's parser is not (currently) an example of a standards conformant parser in that it does not have a mode that returns the 'unfolded' header. So if you are using Python's email package to parse one of these headers, you would need to access the raw header data (that has the line ends in it) and replace the seven spaces plus '|' with the null string to recover your original data. It is also not clear that you can use the current email package to produce headers in the format you specify, though that may not be an issue. -- R. David Murray www.bitdance.com Business Process Automation - Network/Server Management - Routers/Firewalls From python-checkins at python.org Tue Dec 29 21:10:16 2009 From: python-checkins at python.org (andrew.kuchling) Date: Tue, 29 Dec 2009 20:10:16 -0000 Subject: [Python-checkins] r77115 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: andrew.kuchling Date: Tue Dec 29 21:10:16 2009 New Revision: 77115 Log: Various additions 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 Tue Dec 29 21:10:16 2009 @@ -49,9 +49,9 @@ This saves the maintainer some effort going through the SVN logs when researching a change. -This article explains the new features in Python 2.7. No release -schedule has been decided yet for 2.7; the schedule will eventually be -described in :pep:`373`. +This article explains the new features in Python 2.7. The final +release of 2.7 is currently scheduled for June 2010; the detailed +schedule is described in :pep:`373`. .. Compare with previous release in 2 - 3 sentences here. add hyperlink when the documentation becomes available online. @@ -301,6 +301,9 @@ (Implemented by Mark Dickinson; :issue:`3166`.) + Integer division is also more accurate in its rounding behaviours. (Also + implemented by Mark Dickinson; :issue:`1811`.) + * The :class:`bytearray` type's :meth:`translate` method now accepts ``None`` as its first argument. (Fixed by Georg Brandl; :issue:`4759`.) @@ -315,6 +318,11 @@ supported. (Contributed by Alexander Belchenko and Amaury Forgeot d'Arc; :issue:`1616979`.) +* Extra parentheses in function definitions are illegal in Python 3.x, + meaning that you get a syntax error from ``def f((x)): pass``. In + Python3-warning mode, Python 2.7 will now warn about this odd usage. + (Noted by James Lingard; :issue:`7362`.) + .. ====================================================================== @@ -333,16 +341,16 @@ :keyword:`with` statements, looking up the :meth:`__enter__` and :meth:`__exit__` methods. (Contributed by Benjamin Peterson.) -* 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 now performs better for one common usage + pattern: when many objects are being allocated without deallocating + any of them. This would previously take quadratic + time for garbage collection, but now the number of full garbage collections + is reduced as the number of objects on the heap grows. + The new logic is to only perform a full garbage collection pass 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. (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 @@ -410,7 +418,6 @@ conversion function that supports arbitrary bases. (Patch by Gawain Bolton; :issue:`6713`.) - .. ====================================================================== New and Improved Modules @@ -488,7 +495,9 @@ (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.) + read-only :attr:`maxlen` attribute, and has a + :meth:`reverse` method that reverses the elements of the deque in-place. + (Added by Raymond Hettinger.) * The :mod:`ctypes` module now always converts ``None`` to a C NULL pointer for arguments declared as pointers. (Changed by Thomas @@ -539,14 +548,24 @@ process, but instead simply not install the failing extension. (Contributed by Georg Brandl; :issue:`5583`.) - Issue #7457: added a read_pkg_file method to.distutils.dist.DistributionMetadata - see file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata - (:issue:`7457`, added by Tarek). + The :class:`distutils.dist.DistributionMetadata` class' + :meth:`read_pkg_file` method will read the contents of a package's + metadata file. For an example of its use, + XXX link to file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata + (Contributed by Tarek Ziade; :issue:`7457`.) * The :class:`Fraction` class now accepts two rational numbers as arguments to its constructor. (Implemented by Mark Dickinson; :issue:`5812`.) +* The :mod:`ftplib` module gained the ability to establish secure FTP + connections using TLS encapsulation of authentication as well as + subsequent control and data transfers. This is provided by the new + :class:`ftplib.FTP_TLS` class. + (Contributed by Giampaolo Rodola', :issue:`2054`.) The :meth:`storbinary` + method for binary uploads can now restart uploads thanks to an added + *rest* parameter (patch by Pablo Mouzo; :issue:`6845`.) + * 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`.) @@ -627,8 +646,12 @@ with any object literal that decodes to a list of pairs. (Contributed by Raymond Hettinger; :issue:`5381`.) -* New functions: the :mod:`math` module now has - a :func:`gamma` function. +* New functions: the :mod:`math` module gained + :func:`erf` and :func:`erfc` for the error function and the complementary error function, + :func:`expm1` which computes ``e**x - 1`` with more precision than + using :func:`exp` and subtracting 1, + :func:`gamma` for the Gamma function, and + :func:`lgamma` for the natural log of the Gamma function. (Contributed by Mark Dickinson and nirinA raseliarison; :issue:`3366`.) * The :mod:`multiprocessing` module's :class:`Manager*` classes @@ -640,6 +663,13 @@ * The :mod:`nntplib` module now supports IPv6 addresses. (Contributed by Derek Morr; :issue:`1664`.) +* New functions: the :mod:`os` module wraps the following POSIX system + calls: :func:`getresgid` and :func:`getresuid`, which return the + real, effective, and saved GIDs and UIDs; + :func:`setresgid` and :func:`setresuid`, which set + real, effective, and saved GIDs and UIDs to new values. (Contributed + by Travis H.; :issue:`6508`.) + * 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`.) @@ -728,12 +758,6 @@ :mod:`zipfile` now supports archiving empty directories and extracts them correctly. (Fixed by Kuba Wieczorek; :issue:`4710`.) -* The :mod:`ftplib` module gains the ability to establish secure FTP - connections using TLS encapsulation of authentication as well as - subsequent control and data transfers. This is provided by the new - :class:`ftplib.FTP_TLS` class. - (Contributed by Giampaolo Rodola', :issue:`2054`.) - .. ====================================================================== .. whole new modules get described in subsections here @@ -934,6 +958,12 @@ extensions needed to call :cfunc:`PyCode_New`, which had many more arguments. (Added by Jeffrey Yasskin.) +* New function: :cfunc:`PyErr_NewExceptionWithDoc` creates a new + exception class, just as the existing :cfunc:`PyErr_NewException` does, + but takes an extra ``char *`` argument containing the docstring for the + new exception class. (Added by the 'lekma' user on the Python bug tracker; + :issue:`7033`.) + * New function: :cfunc:`PyFrame_GetLineNumber` takes a frame object and returns the line number that the frame is currently executing. Previously code would need to get the index of the bytecode @@ -992,6 +1022,12 @@ * The build process now supports Subversion 1.7. (Contributed by Arfrever Frehtes Taifersar Arahesis; :issue:`6094`.) +* Compiling Python with the :option:`--with-valgrind` option will now + disable the pymalloc allocator, which is difficult for the Valgrind to + analyze correctly. Valgrind will therefore be better at detecting + memory leaks and overruns. (Contributed by James Henstridge; :issue:`2422`.) + + .. ====================================================================== Port-Specific Changes: Windows @@ -1070,6 +1106,10 @@ affects new-style classes (derived from :class:`object`) and C extension types. (:issue:`6101`.) +* The :meth:`readline` method of :class:`StringIO` objects now does + nothing when a negative length is requested, as other file-like + objects do. (:issue:`7348`). + .. ====================================================================== From python-checkins at python.org Tue Dec 29 21:51:25 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 29 Dec 2009 20:51:25 -0000 Subject: [Python-checkins] r77116 - python/trunk/Lib/test/math_testcases.txt Message-ID: Author: mark.dickinson Date: Tue Dec 29 21:51:24 2009 New Revision: 77116 Log: Issue #7575: An overflow test for math.expm1 was failing on OS X 10.4/Intel, due to a defect in the platform's implementation of expm1. Since the issue is of low severity, and appears to be fixed in OS X 10.5 and 10.6, it doesn't seem worth working around, so I'm just weakening the relevant test so that it passes on 10.4. Modified: python/trunk/Lib/test/math_testcases.txt Modified: python/trunk/Lib/test/math_testcases.txt ============================================================================== --- python/trunk/Lib/test/math_testcases.txt (original) +++ python/trunk/Lib/test/math_testcases.txt Tue Dec 29 21:51:24 2009 @@ -396,8 +396,14 @@ -- extreme positive values expm10300 expm1 300 -> 1.9424263952412558e+130 expm10301 expm1 700 -> 1.0142320547350045e+304 -expm10302 expm1 709.78271289328393 -> 1.7976931346824240e+308 +-- the next test (expm10302) is disabled because it causes failure on +-- OS X 10.4/Intel: apparently all values over 709.78 produce an +-- overflow on that platform. See issue #7575. +-- expm10302 expm1 709.78271289328393 -> 1.7976931346824240e+308 expm10303 expm1 709.78271289348402 -> inf overflow expm10304 expm1 1000 -> inf overflow expm10305 expm1 1e50 -> inf overflow expm10306 expm1 1.79e308 -> inf overflow + +-- weaker version of expm10302 +expm10307 expm1 709.5 -> 1.3549863193146328e+308 From python-checkins at python.org Tue Dec 29 21:52:27 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 29 Dec 2009 20:52:27 -0000 Subject: [Python-checkins] r77117 - in python/branches/py3k: Lib/test/math_testcases.txt Message-ID: Author: mark.dickinson Date: Tue Dec 29 21:52:27 2009 New Revision: 77117 Log: Merged revisions 77116 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77116 | mark.dickinson | 2009-12-29 20:51:24 +0000 (Tue, 29 Dec 2009) | 6 lines Issue #7575: An overflow test for math.expm1 was failing on OS X 10.4/Intel, due to a defect in the platform's implementation of expm1. Since the issue is of low severity, and appears to be fixed in OS X 10.5 and 10.6, it doesn't seem worth working around, so I'm just weakening the relevant test so that it passes on 10.4. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/math_testcases.txt Modified: python/branches/py3k/Lib/test/math_testcases.txt ============================================================================== --- python/branches/py3k/Lib/test/math_testcases.txt (original) +++ python/branches/py3k/Lib/test/math_testcases.txt Tue Dec 29 21:52:27 2009 @@ -396,8 +396,14 @@ -- extreme positive values expm10300 expm1 300 -> 1.9424263952412558e+130 expm10301 expm1 700 -> 1.0142320547350045e+304 -expm10302 expm1 709.78271289328393 -> 1.7976931346824240e+308 +-- the next test (expm10302) is disabled because it causes failure on +-- OS X 10.4/Intel: apparently all values over 709.78 produce an +-- overflow on that platform. See issue #7575. +-- expm10302 expm1 709.78271289328393 -> 1.7976931346824240e+308 expm10303 expm1 709.78271289348402 -> inf overflow expm10304 expm1 1000 -> inf overflow expm10305 expm1 1e50 -> inf overflow expm10306 expm1 1.79e308 -> inf overflow + +-- weaker version of expm10302 +expm10307 expm1 709.5 -> 1.3549863193146328e+308 From python-checkins at python.org Tue Dec 29 21:52:50 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 29 Dec 2009 20:52:50 -0000 Subject: [Python-checkins] r77118 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Tue Dec 29 21:52:50 2009 New Revision: 77118 Log: Blocked revisions 77116 via svnmerge ........ r77116 | mark.dickinson | 2009-12-29 20:51:24 +0000 (Tue, 29 Dec 2009) | 6 lines Issue #7575: An overflow test for math.expm1 was failing on OS X 10.4/Intel, due to a defect in the platform's implementation of expm1. Since the issue is of low severity, and appears to be fixed in OS X 10.5 and 10.6, it doesn't seem worth working around, so I'm just weakening the relevant test so that it passes on 10.4. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Dec 29 21:53:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 29 Dec 2009 20:53:23 -0000 Subject: [Python-checkins] r77119 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Tue Dec 29 21:53:23 2009 New Revision: 77119 Log: Blocked revisions 77117 via svnmerge ................ r77117 | mark.dickinson | 2009-12-29 20:52:27 +0000 (Tue, 29 Dec 2009) | 13 lines Merged revisions 77116 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77116 | mark.dickinson | 2009-12-29 20:51:24 +0000 (Tue, 29 Dec 2009) | 6 lines Issue #7575: An overflow test for math.expm1 was failing on OS X 10.4/Intel, due to a defect in the platform's implementation of expm1. Since the issue is of low severity, and appears to be fixed in OS X 10.5 and 10.6, it doesn't seem worth working around, so I'm just weakening the relevant test so that it passes on 10.4. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Tue Dec 29 22:09:18 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 29 Dec 2009 21:09:18 -0000 Subject: [Python-checkins] r77120 - in python/trunk: Doc/library/select.rst Modules/selectmodule.c Message-ID: Author: georg.brandl Date: Tue Dec 29 22:09:17 2009 New Revision: 77120 Log: #7595: fix typo in argument default constant. Modified: python/trunk/Doc/library/select.rst python/trunk/Modules/selectmodule.c Modified: python/trunk/Doc/library/select.rst ============================================================================== --- python/trunk/Doc/library/select.rst (original) +++ python/trunk/Doc/library/select.rst Tue Dec 29 22:09:17 2009 @@ -50,7 +50,7 @@ .. versionadded:: 2.6 -.. function:: kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ADD, fflags=0, data=0, udata=0) +.. function:: kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0) (Only supported on BSD.) Returns a kernel event object object; see section :ref:`kevent-objects` below for the methods supported by kqueue objects. Modified: python/trunk/Modules/selectmodule.c ============================================================================== --- python/trunk/Modules/selectmodule.c (original) +++ python/trunk/Modules/selectmodule.c Tue Dec 29 22:09:17 2009 @@ -1161,7 +1161,7 @@ #endif PyDoc_STRVAR(kqueue_event_doc, -"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ADD, fflags=0, data=0, udata=0)\n\ +"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\ \n\ This object is the equivalent of the struct kevent for the C API.\n\ \n\ From python-checkins at python.org Tue Dec 29 22:38:35 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 29 Dec 2009 21:38:35 -0000 Subject: [Python-checkins] r77121 - python/branches/py3k/Doc/library/exceptions.rst Message-ID: Author: georg.brandl Date: Tue Dec 29 22:38:35 2009 New Revision: 77121 Log: #7590: exception classes no longer are in the "exceptions" module. Also clean up text that was written with string exceptions in mind. Modified: python/branches/py3k/Doc/library/exceptions.rst Modified: python/branches/py3k/Doc/library/exceptions.rst ============================================================================== --- python/branches/py3k/Doc/library/exceptions.rst (original) +++ python/branches/py3k/Doc/library/exceptions.rst Tue Dec 29 22:38:35 2009 @@ -3,20 +3,12 @@ Built-in Exceptions =================== -.. module:: exceptions - :synopsis: Standard exception classes. - - -Exceptions should be class objects. The exceptions are defined in the module -:mod:`exceptions`. This module never needs to be imported explicitly: the -exceptions are provided in the built-in namespace as well as the -:mod:`exceptions` module. - .. index:: statement: try statement: except -For class exceptions, in a :keyword:`try` statement with an :keyword:`except` +In Python, all exceptions must be instances of a class that derives from +:class:`BaseException`. In a :keyword:`try` statement with an :keyword:`except` clause that mentions a particular class, that clause also handles any exception classes derived from that class (but not exception classes from which *it* is derived). Two exception classes that are not related via subclassing are never @@ -44,7 +36,7 @@ defining exceptions is available in the Python Tutorial under :ref:`tut-userexceptions`. -The following exceptions are only used as base classes for other exceptions. +The following exceptions are used mostly as base classes for other exceptions. .. XXX document with_traceback() @@ -99,8 +91,8 @@ In this last case, :attr:`args` contains the verbatim constructor arguments as a tuple. -The following exceptions are the exceptions that are actually raised. +The following exceptions are the exceptions that are usually raised. .. exception:: AssertionError @@ -369,10 +361,10 @@ associated value is a string indicating the type of the operands and the operation. + The following exceptions are used as warning categories; see the :mod:`warnings` module for more information. - .. exception:: Warning Base class for warning categories. From python-checkins at python.org Tue Dec 29 23:03:38 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Tue, 29 Dec 2009 22:03:38 -0000 Subject: [Python-checkins] r77122 - in python/trunk: Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c Message-ID: Author: amaury.forgeotdarc Date: Tue Dec 29 23:03:38 2009 New Revision: 77122 Log: #7413: Passing '\0' as the separator to datetime.datetime.isoformat() used to drop the time part of the result. Modified: python/trunk/Lib/test/test_datetime.py python/trunk/Misc/NEWS python/trunk/Modules/datetimemodule.c Modified: python/trunk/Lib/test/test_datetime.py ============================================================================== --- python/trunk/Lib/test/test_datetime.py (original) +++ python/trunk/Lib/test/test_datetime.py Tue Dec 29 23:03:38 2009 @@ -1180,6 +1180,7 @@ self.assertEqual(t.isoformat(), "0002-03-02T04:05:01.000123") self.assertEqual(t.isoformat('T'), "0002-03-02T04:05:01.000123") self.assertEqual(t.isoformat(' '), "0002-03-02 04:05:01.000123") + self.assertEqual(t.isoformat('\x00'), "0002-03-02\x0004:05:01.000123") # str is ISO format with the separator forced to a blank. self.assertEqual(str(t), "0002-03-02 04:05:01.000123") Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Dec 29 23:03:38 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7413: Passing '\0' as the separator to datetime.datetime.isoformat() + used to drop the time part of the result. + - Issue #1811: improve accuracy and cross-platform consistency for true division of integers: the result of a/b is now correctly rounded for ints a and b (at least on IEEE 754 platforms), and in Modified: python/trunk/Modules/datetimemodule.c ============================================================================== --- python/trunk/Modules/datetimemodule.c (original) +++ python/trunk/Modules/datetimemodule.c Tue Dec 29 23:03:38 2009 @@ -1362,21 +1362,26 @@ x = PyOS_snprintf(buffer, bufflen, "%04d-%02d-%02d", GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt)); + assert(bufflen >= x); return buffer + x; } -static void +static char * isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen) { + int x; int us = DATE_GET_MICROSECOND(dt); - PyOS_snprintf(buffer, bufflen, - "%02d:%02d:%02d", /* 8 characters */ - DATE_GET_HOUR(dt), - DATE_GET_MINUTE(dt), - DATE_GET_SECOND(dt)); + x = PyOS_snprintf(buffer, bufflen, + "%02d:%02d:%02d", + DATE_GET_HOUR(dt), + DATE_GET_MINUTE(dt), + DATE_GET_SECOND(dt)); + assert(bufflen >= x); if (us) - PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us); + x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us); + assert(bufflen >= x); + return buffer + x; } /* --------------------------------------------------------------------------- @@ -4211,8 +4216,8 @@ cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer)); assert(cp != NULL); *cp++ = sep; - isoformat_time(self, cp, sizeof(buffer) - (cp - buffer)); - result = PyString_FromString(buffer); + cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer)); + result = PyString_FromStringAndSize(buffer, cp - buffer); if (result == NULL || ! HASTZINFO(self)) return result; From ziade.tarek at gmail.com Tue Dec 29 23:08:28 2009 From: ziade.tarek at gmail.com (=?ISO-8859-1?Q?Tarek_Ziad=E9?=) Date: Tue, 29 Dec 2009 23:08:28 +0100 Subject: [Python-checkins] r77056 - peps/trunk/pep-0345.txt In-Reply-To: <20091229143015.02BBF1FA329@kimball.webabinitio.net> References: <20091225132922.99DF91FA647@kimball.webabinitio.net> <20091229143015.02BBF1FA329@kimball.webabinitio.net> Message-ID: <94bdd2610912291408v4ad02f3dna9408c3ffb3f60e6@mail.gmail.com> On Tue, Dec 29, 2009 at 3:30 PM, R. David Murray wrote: > On Fri, 25 Dec 2009 08:29:22 -0500, tarek.ziade wrote: > > tarek.ziade wrote: >> +To support empty lines and lines with indentation with respect to >> +the RFC 822 format, any new line has to be suffixed by 7 spaces >> +followed by a pipe (`|`) char. As a result, the Description field is >> +encoded into a folded field that can be interpreted by RFC822 >> +parser [2]_. >> + >> ?Example:: >> > [...] >> + ? ?Description: This project provides powerful math functions >> + ? ? ? ? ? ?|For example, you can use `sum()` to sum numbers: >> + ? ? ? ? ? ?| >> + ? ? ? ? ? ?|Example:: >> + ? ? ? ? ? ?| >> + ? ? ? ? ? ?| ? ?>>> sum(1, 2) >> + ? ? ? ? ? ?| ? ?3 >> + ? ? ? ? ? ?| >> + >> +This encoding implies that any occurences of ``\n |`` have to be replaced >> +by ``\n`` when the field is unfolded using a RFC822 reader. > > Actually, a properly operating RFC[2]822 parser will unfold the header > by removing the CFLF. ?So the correct method of restoring the line > breaks would be to replace the seven-spaces-plus-'|' with a \n. > (See RFC2822, section 2.2.3). > > Unfortunately, Python's email package's parser is not (currently) an > example of a standards conformant parser in that it does not have a mode > that returns the 'unfolded' header. ?So if you are using Python's email > package to parse one of these headers, you would need to access the raw > header data (that has the line ends in it) and replace the seven spaces > plus '|' with the null string to recover your original data. > > It is also not clear that you can use the current email package to produce > headers in the format you specify, though that may not be an issue. Yes, at first this issue was unclear to me, because I used the rfc822 module from the stdlib and this will translate any numbers of spaces used as the WSP into *one? single space, meaning that to decode the header, I couldn't use a bijective transformation. Then I realized that the rfc822 was to be removed, and that the email package behaves correcty. Here's how Distutils will do: >>> import email >>> WSP = ' '*7+'|' >>> def encode(str): ... return str.replace('\n', '\n'+WSP) ... >>> def decode(str): ... return str.replace('\n'+WSP, '\n') ... >>> description = """Description: here is ... ... some example:: ... ... >>> 1 + 1 ... 2 ... """ >>> msg = email.message_from_string(encode(description)) >>> print msg['description'] here is | |some example:: | | >>> 1 + 1 | 2 | >>> print decode(msg['description']) here is some example:: >>> 1 + 1 2 I'll fix the PEP accordingly, Thanks for the feedback Regards, Tarek -- Tarek Ziad? | http://ziade.org From python-checkins at python.org Tue Dec 29 23:16:50 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 29 Dec 2009 22:16:50 -0000 Subject: [Python-checkins] r77123 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Tue Dec 29 23:16:50 2009 New Revision: 77123 Log: fixed the folding/unfolding story for the Description field Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Tue Dec 29 23:16:50 2009 @@ -127,7 +127,7 @@ the markup they use. To support empty lines and lines with indentation with respect to -the RFC 822 format, any new line has to be suffixed by 7 spaces +the RFC 822 format, any CRLF character has to be suffixed by 7 spaces followed by a pipe ("|") char. As a result, the Description field is encoded into a folded field that can be interpreted by RFC822 parser [2]_. @@ -143,8 +143,9 @@ | 3 | -This encoding implies that any occurences of "``\n |``" have to be replaced -by "``\n``" when the field is unfolded using a RFC822 reader. +This encoding implies that any occurences of a CRLF followed by 7 spaces +and a pipe char have to be replaced by a single CRLF when the field is unfolded +using a RFC822 reader. Keywords (optional) From python-checkins at python.org Tue Dec 29 23:24:40 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Tue, 29 Dec 2009 22:24:40 -0000 Subject: [Python-checkins] r77124 - in python/branches/py3k: Lib/test/test_datetime.py Message-ID: Author: amaury.forgeotdarc Date: Tue Dec 29 23:24:40 2009 New Revision: 77124 Log: (issue 7413 does not concern py3k, I merge the test nonetheless) Merged revisions 77122 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77122 | amaury.forgeotdarc | 2009-12-29 23:03:38 +0100 (mar., 29 d?c. 2009) | 3 lines #7413: Passing '\0' as the separator to datetime.datetime.isoformat() used to drop the time part of the result. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_datetime.py Modified: python/branches/py3k/Lib/test/test_datetime.py ============================================================================== --- python/branches/py3k/Lib/test/test_datetime.py (original) +++ python/branches/py3k/Lib/test/test_datetime.py Tue Dec 29 23:24:40 2009 @@ -1178,6 +1178,7 @@ self.assertEqual(t.isoformat(), "0002-03-02T04:05:01.000123") self.assertEqual(t.isoformat('T'), "0002-03-02T04:05:01.000123") self.assertEqual(t.isoformat(' '), "0002-03-02 04:05:01.000123") + self.assertEqual(t.isoformat('\x00'), "0002-03-02\x0004:05:01.000123") # str is ISO format with the separator forced to a blank. self.assertEqual(str(t), "0002-03-02 04:05:01.000123") From python-checkins at python.org Tue Dec 29 23:39:49 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Tue, 29 Dec 2009 22:39:49 -0000 Subject: [Python-checkins] r77125 - in python/branches/release26-maint: Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c Message-ID: Author: amaury.forgeotdarc Date: Tue Dec 29 23:39:49 2009 New Revision: 77125 Log: Merged revisions 77122 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77122 | amaury.forgeotdarc | 2009-12-29 23:03:38 +0100 (mar., 29 d?c. 2009) | 3 lines #7413: Passing '\0' as the separator to datetime.datetime.isoformat() used to drop the time part of the result. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_datetime.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/datetimemodule.c Modified: python/branches/release26-maint/Lib/test/test_datetime.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_datetime.py (original) +++ python/branches/release26-maint/Lib/test/test_datetime.py Tue Dec 29 23:39:49 2009 @@ -1173,6 +1173,7 @@ self.assertEqual(t.isoformat(), "0002-03-02T04:05:01.000123") self.assertEqual(t.isoformat('T'), "0002-03-02T04:05:01.000123") self.assertEqual(t.isoformat(' '), "0002-03-02 04:05:01.000123") + self.assertEqual(t.isoformat('\x00'), "0002-03-02\x0004:05:01.000123") # str is ISO format with the separator forced to a blank. self.assertEqual(str(t), "0002-03-02 04:05:01.000123") Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Tue Dec 29 23:39:49 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7413: Passing '\0' as the separator to datetime.datetime.isoformat() + used to drop the time part of the result. + - Issue #6108: unicode(exception) and str(exception) should return the same message when only __str__ (and not __unicode__) is overridden in the subclass. Modified: python/branches/release26-maint/Modules/datetimemodule.c ============================================================================== --- python/branches/release26-maint/Modules/datetimemodule.c (original) +++ python/branches/release26-maint/Modules/datetimemodule.c Tue Dec 29 23:39:49 2009 @@ -1362,21 +1362,26 @@ x = PyOS_snprintf(buffer, bufflen, "%04d-%02d-%02d", GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt)); + assert(bufflen >= x); return buffer + x; } -static void +static char * isoformat_time(PyDateTime_DateTime *dt, char buffer[], int bufflen) { + int x; int us = DATE_GET_MICROSECOND(dt); - PyOS_snprintf(buffer, bufflen, - "%02d:%02d:%02d", /* 8 characters */ - DATE_GET_HOUR(dt), - DATE_GET_MINUTE(dt), - DATE_GET_SECOND(dt)); + x = PyOS_snprintf(buffer, bufflen, + "%02d:%02d:%02d", + DATE_GET_HOUR(dt), + DATE_GET_MINUTE(dt), + DATE_GET_SECOND(dt)); + assert(bufflen >= x); if (us) - PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us); + x += PyOS_snprintf(buffer + x, bufflen - x, ".%06d", us); + assert(bufflen >= x); + return buffer + x; } /* --------------------------------------------------------------------------- @@ -4200,8 +4205,8 @@ cp = isoformat_date((PyDateTime_Date *)self, buffer, sizeof(buffer)); assert(cp != NULL); *cp++ = sep; - isoformat_time(self, cp, sizeof(buffer) - (cp - buffer)); - result = PyString_FromString(buffer); + cp = isoformat_time(self, cp, sizeof(buffer) - (cp - buffer)); + result = PyString_FromStringAndSize(buffer, cp - buffer); if (result == NULL || ! HASTZINFO(self)) return result; From python-checkins at python.org Wed Dec 30 00:06:18 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Tue, 29 Dec 2009 23:06:18 -0000 Subject: [Python-checkins] r77126 - in python/trunk: Misc/NEWS PC/msvcrtmodule.c Message-ID: Author: amaury.forgeotdarc Date: Wed Dec 30 00:06:17 2009 New Revision: 77126 Log: #7579: Add docstrings to the msvcrt module Modified: python/trunk/Misc/NEWS python/trunk/PC/msvcrtmodule.c Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Dec 30 00:06:17 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #7579: the msvcrt module now has docstrings for all its functions. + - Issue #7413: Passing '\0' as the separator to datetime.datetime.isoformat() used to drop the time part of the result. Modified: python/trunk/PC/msvcrtmodule.c ============================================================================== --- python/trunk/PC/msvcrtmodule.c (original) +++ python/trunk/PC/msvcrtmodule.c Wed Dec 30 00:06:17 2009 @@ -43,6 +43,13 @@ return Py_None; } +PyDoc_STRVAR(heapmin_doc, +"heapmin() -> None\n\ +\n\ +Force the malloc() heap to clean itself up and return unused blocks\n\ +to the operating system. This only works on Windows NT. On failure,\n\ +this raises IOError."); + // Perform locking operations on a C runtime file descriptor. static PyObject * msvcrt_locking(PyObject *self, PyObject *args) @@ -65,6 +72,17 @@ return Py_None; } +PyDoc_STRVAR(locking_doc, +"locking(fd, mode, nbytes) -> None\n\ +\n\ +Lock part of a file based on file descriptor fd from the C runtime.\n\ +Raises IOError on failure. The locked region of the file extends from\n\ +the current file position for nbytes bytes, and may continue beyond\n\ +the end of the file. mode must be one of the LK_* constants listed\n\ +below. Multiple regions in a file may be locked at the same time, but\n\ +may not overlap. Adjacent regions are not merged; they must be unlocked\n\ +individually."); + // Set the file translation mode for a C runtime file descriptor. static PyObject * msvcrt_setmode(PyObject *self, PyObject *args) @@ -81,6 +99,13 @@ return PyInt_FromLong(flags); } +PyDoc_STRVAR(setmode_doc, +"setmode(fd, mode) -> Previous mode\n\ +\n\ +Set the line-end translation mode for the file descriptor fd. To set\n\ +it to text mode, flags should be os.O_TEXT; for binary, it should be\n\ +os.O_BINARY."); + // Convert an OS file handle to a C runtime file descriptor. static PyObject * msvcrt_open_osfhandle(PyObject *self, PyObject *args) @@ -99,6 +124,14 @@ return PyInt_FromLong(fd); } +PyDoc_STRVAR(open_osfhandle_doc, +"open_osfhandle(handle, flags) -> file descriptor\n\ +\n\ +Create a C runtime file descriptor from the file handle handle. The\n\ +flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY,\n\ +and os.O_TEXT. The returned file descriptor may be used as a parameter\n\ +to os.fdopen() to create a file object."); + // Convert a C runtime file descriptor to an OS file handle. static PyObject * msvcrt_get_osfhandle(PyObject *self, PyObject *args) @@ -119,6 +152,12 @@ return PyLong_FromVoidPtr((void*)handle); } +PyDoc_STRVAR(get_osfhandle_doc, +"get_osfhandle(fd) -> file handle\n\ +\n\ +Return the file handle for the file descriptor fd. Raises IOError\n\ +if fd is not recognized."); + /* Console I/O */ static PyObject * @@ -133,6 +172,11 @@ return PyInt_FromLong(ok); } +PyDoc_STRVAR(kbhit_doc, +"kbhit() -> bool\n\ +\n\ +Return true if a keypress is waiting to be read."); + static PyObject * msvcrt_getch(PyObject *self, PyObject *args) { @@ -149,6 +193,16 @@ return PyString_FromStringAndSize(s, 1); } +PyDoc_STRVAR(getch_doc, +"getch() -> key character\n\ +\n\ +Read a keypress and return the resulting character. Nothing is echoed to\n\ +the console. This call will block if a keypress is not already\n\ +available, but will not wait for Enter to be pressed. If the pressed key\n\ +was a special function key, this will return '\\000' or '\\xe0'; the next\n\ +call will return the keycode. The Control-C keypress cannot be read with\n\ +this function."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_getwch(PyObject *self, PyObject *args) @@ -165,6 +219,11 @@ u[0] = ch; return PyUnicode_FromUnicode(u, 1); } + +PyDoc_STRVAR(getwch_doc, +"getwch() -> Unicode key character\n\ +\n\ +Wide char variant of getch(), returning a Unicode value."); #endif static PyObject * @@ -183,6 +242,12 @@ return PyString_FromStringAndSize(s, 1); } +PyDoc_STRVAR(getche_doc, +"getche() -> key character\n\ +\n\ +Similar to getch(), but the keypress will be echoed if it represents\n\ +a printable character."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_getwche(PyObject *self, PyObject *args) @@ -199,6 +264,11 @@ s[0] = ch; return PyUnicode_FromUnicode(s, 1); } + +PyDoc_STRVAR(getwche_doc, +"getwche() -> Unicode key character\n\ +\n\ +Wide char variant of getche(), returning a Unicode value."); #endif static PyObject * @@ -214,6 +284,11 @@ return Py_None; } +PyDoc_STRVAR(putch_doc, +"putch(char) -> None\n\ +\n\ +Print the character char to the console without buffering."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_putwch(PyObject *self, PyObject *args) @@ -233,6 +308,11 @@ Py_RETURN_NONE; } + +PyDoc_STRVAR(putwch_doc, +"putwch(unicode_char) -> None\n\ +\n\ +Wide char variant of putch(), accepting a Unicode value."); #endif static PyObject * @@ -249,6 +329,12 @@ return Py_None; } +PyDoc_STRVAR(ungetch_doc, +"ungetch(char) -> None\n\ +\n\ +Cause the character char to be \"pushed back\" into the console buffer;\n\ +it will be the next character read by getch() or getche()."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_ungetwch(PyObject *self, PyObject *args) @@ -263,6 +349,11 @@ Py_INCREF(Py_None); return Py_None; } + +PyDoc_STRVAR(ungetwch_doc, +"ungetwch(unicode_char) -> None\n\ +\n\ +Wide char variant of ungetch(), accepting a Unicode value."); #endif static void @@ -282,21 +373,21 @@ /* List of functions exported by this module */ static struct PyMethodDef msvcrt_functions[] = { - {"heapmin", msvcrt_heapmin, METH_VARARGS}, - {"locking", msvcrt_locking, METH_VARARGS}, - {"setmode", msvcrt_setmode, METH_VARARGS}, - {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS}, - {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS}, - {"kbhit", msvcrt_kbhit, METH_VARARGS}, - {"getch", msvcrt_getch, METH_VARARGS}, - {"getche", msvcrt_getche, METH_VARARGS}, - {"putch", msvcrt_putch, METH_VARARGS}, - {"ungetch", msvcrt_ungetch, METH_VARARGS}, + {"heapmin", msvcrt_heapmin, METH_VARARGS, heapmin_doc}, + {"locking", msvcrt_locking, METH_VARARGS, locking_doc}, + {"setmode", msvcrt_setmode, METH_VARARGS, setmode_doc}, + {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS, open_osfhandle_doc}, + {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS, get_osfhandle_doc}, + {"kbhit", msvcrt_kbhit, METH_VARARGS, kbhit_doc}, + {"getch", msvcrt_getch, METH_VARARGS, getch_doc}, + {"getche", msvcrt_getche, METH_VARARGS, getche_doc}, + {"putch", msvcrt_putch, METH_VARARGS, putch_doc}, + {"ungetch", msvcrt_ungetch, METH_VARARGS, ungetch_doc}, #ifdef _WCONIO_DEFINED - {"getwch", msvcrt_getwch, METH_VARARGS}, - {"getwche", msvcrt_getwche, METH_VARARGS}, - {"putwch", msvcrt_putwch, METH_VARARGS}, - {"ungetwch", msvcrt_ungetwch, METH_VARARGS}, + {"getwch", msvcrt_getwch, METH_VARARGS, getwch_doc}, + {"getwche", msvcrt_getwche, METH_VARARGS, getwche_doc}, + {"putwch", msvcrt_putwch, METH_VARARGS, putwch_doc}, + {"ungetwch", msvcrt_ungetwch, METH_VARARGS, ungetwch_doc}, #endif {NULL, NULL} }; From python-checkins at python.org Wed Dec 30 00:41:05 2009 From: python-checkins at python.org (andrew.kuchling) Date: Tue, 29 Dec 2009 23:41:05 -0000 Subject: [Python-checkins] r77127 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: andrew.kuchling Date: Wed Dec 30 00:41:04 2009 New Revision: 77127 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 Wed Dec 30 00:41:04 2009 @@ -73,6 +73,11 @@ * The new format specifier described in :ref:`pep-0378`. * The :class:`memoryview` object. * A small subset of the :mod:`importlib` module `described below <#importlib-section>`__. +* Float-to-string and string-to-float conversions now round their + results more correctly. And :func:`repr` of a floating-point + number *x* returns a result that's guaranteed to round back to the + same number when converted back to a string. +* The :cfunc:`PyLong_AsLongAndOverflow` C API function. One porting change: the :option:`-3` switch now automatically enables the :option:`-Qwarn` switch that causes warnings @@ -237,6 +242,33 @@ (Proposed in http://codereview.appspot.com/53094; implemented by Georg Brandl.) +* Conversions between floating-point numbers and strings are + now correctly rounded on most platforms. These conversions occur + in many different places: :func:`str` on + floats and complex numbers; the :class:`float` and :class:`complex` + constructors; + numeric formatting; serialization and + deserialization of floats and complex numbers using the + :mod:`marshal`, :mod:`pickle` + and :mod:`json` modules; + parsing of float and imaginary literals in Python code; + and :class:`Decimal`-to-float conversion. + + Related to this, the :func:`repr` of a floating-point number *x* + now returns a result based on the shortest decimal string that's + guaranteed to round back to *x* under correct rounding (with + round-half-to-even rounding mode). Previously it gave a string + based on rounding x to 17 decimal digits. + + The rounding library responsible for this improvement works on + Windows, and on Unix platforms using the gcc, icc, or suncc + compilers. There may be a small number of platforms where correct + operation of this code cannot be guaranteed, so the code is not + used on such systems. + + Implemented by Mark Dickinson, using David Gay's :file:`dtoa.c` library; + :issue:`7117`. + * The :meth:`str.format` method now supports automatic numbering of the replacement fields. This makes using :meth:`str.format` more closely resemble using ``%s`` formatting:: @@ -259,6 +291,10 @@ alignment is applied to the whole of the resulting ``1.5+3j`` output. (Contributed by Eric Smith; :issue:`1588`.) + The 'F' format code now always formats its output using uppercase characters, + so it will now produce 'INF' and 'NAN'. + (Contributed by Eric Smith; :issue:`3382`.) + * 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:: @@ -318,6 +354,10 @@ supported. (Contributed by Alexander Belchenko and Amaury Forgeot d'Arc; :issue:`1616979`.) +* The :class:`file` object will now set the :attr:`filename` attribute + on the :exc:`IOError` exception when trying to open a directory + on POSIX platforms. (Noted by Jan Kaliszewski; :issue:`4764`.) + * Extra parentheses in function definitions are illegal in Python 3.x, meaning that you get a syntax error from ``def f((x)): pass``. In Python3-warning mode, Python 2.7 will now warn about this odd usage. @@ -499,10 +539,18 @@ :meth:`reverse` method that reverses the elements of the deque in-place. (Added by Raymond Hettinger.) +* The :mod:`copy` module's :func:`deepcopy` function will now + correctly copy bound instance methods. (Implemented by + Robert Collins; :issue:`1515`.) + * The :mod:`ctypes` module now always converts ``None`` to a C NULL pointer for arguments declared as pointers. (Changed by Thomas Heller; :issue:`4606`.) +* New method: the :mod:`datetime` module's :class:`timedelta` class + gained a :meth:`total_seconds` method that returns the number of seconds + in the duration. (Contributed by Brian Quinlan; :issue:`5788`.) + * 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`. @@ -550,7 +598,7 @@ The :class:`distutils.dist.DistributionMetadata` class' :meth:`read_pkg_file` method will read the contents of a package's - metadata file. For an example of its use, + :file:`PKG-INFO` metadata file. For an example of its use, XXX link to file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata (Contributed by Tarek Ziade; :issue:`7457`.) @@ -667,8 +715,10 @@ calls: :func:`getresgid` and :func:`getresuid`, which return the real, effective, and saved GIDs and UIDs; :func:`setresgid` and :func:`setresuid`, which set - real, effective, and saved GIDs and UIDs to new values. (Contributed - by Travis H.; :issue:`6508`.) + real, effective, and saved GIDs and UIDs to new values; + :func:`initgroups`. (GID/UID functions + contributed by Travis H.; :issue:`6508`. Support for initgroups added + by Jean-Paul Calderone; :issue:`7333`.) * The :mod:`pydoc` module now has help for the various symbols that Python uses. You can now do ``help('<<')`` or ``help('@')``, for example. @@ -970,6 +1020,11 @@ instruction currently executing, and then look up the line number corresponding to that address. (Added by Jeffrey Yasskin.) +* New function: :cfunc:`PyLong_AsLongAndOverflow` approximates a Python long + integer as a C :ctype:`long`. If the number is too large to fit into + a :ctype:`long`, an *overflow* flag is set and returned to the caller. + (Contributed by Case Van Horsen; :issue:`7528`.) + * New macros: the Python header files now define the following macros: :cmacro:`Py_ISALNUM`, :cmacro:`Py_ISALPHA`, @@ -988,6 +1043,12 @@ .. XXX these macros don't seem to be described in the c-api docs. +* New format codes: the :cfunc:`PyFormat_FromString`, + :cfunc:`PyFormat_FromStringV`, and :cfunc:`PyErr_Format` now + accepts ``%lld`` and ``%llu`` format codes for displaying values of + C's :ctype:`long long` types. + (Contributed by Mark Dickinson; :issue:`7228`.) + * The complicated interaction between threads and process forking has been changed. Previously, the child process created by :func:`os.fork` might fail because the child is created with only a @@ -1047,6 +1108,10 @@ * The :func:`os.listdir` function now correctly fails for an empty path. (Fixed by Hirokazu Yamamoto; :issue:`5913`.) +* The :mod:`mimelib` module will now read the MIME database from + the Windows registry when initializing. + (Patch by Gabriel Genellina; :issue:`4969`.) + .. ====================================================================== Port-Specific Changes: Mac OS X From solipsis at pitrou.net Wed Dec 30 00:49:21 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 30 Dec 2009 00:49:21 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r77121): sum=0 Message-ID: <20091229234921.52C911771C@ns6635.ovh.net> py3k results for svn r77121 (hg cset ba55a4916baa) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogc6ouae', '-x', 'test_httpservers'] From python-checkins at python.org Wed Dec 30 03:58:51 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 02:58:51 -0000 Subject: [Python-checkins] r77128 - in python/trunk: Misc/NEWS setup.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 03:58:50 2009 New Revision: 77128 Log: only build the nis module when the headers are found #7589 Modified: python/trunk/Misc/NEWS python/trunk/setup.py Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Dec 30 03:58:50 2009 @@ -83,6 +83,9 @@ Build ----- +- Issue #7589: Only build the nis module when the correct header files are + found. + - Switch to OpenSSL 0.9.8l on Windows. - Issue #7541: when using ``python-config`` with a framework install the compiler might Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Wed Dec 30 03:58:50 2009 @@ -1088,7 +1088,7 @@ missing.append('resource') # Sun yellow pages. Some systems have the functions in libc. - if platform not in ['cygwin', 'atheos', 'qnx6']: + if platform not in ['cygwin', 'atheos', 'qnx6'] and find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None: if (self.compiler_obj.find_library_file(lib_dirs, 'nsl')): libs = ['nsl'] else: From python-checkins at python.org Wed Dec 30 04:02:05 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 03:02:05 -0000 Subject: [Python-checkins] r77129 - in python/branches/py3k: Misc/NEWS setup.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 04:02:03 2009 New Revision: 77129 Log: Merged revisions 77128 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77128 | benjamin.peterson | 2009-12-29 20:58:50 -0600 (Tue, 29 Dec 2009) | 1 line only build the nis module when the headers are found #7589 ........ Modified: python/branches/py3k/ (props changed) 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 Wed Dec 30 04:02:03 2009 @@ -504,6 +504,9 @@ Build ----- +- Issue #7589: Only build the nis module when the correct header files are + found. + - Switch to OpenSSL 0.9.8l on Windows. - Issue #5792: Extend the short float repr support to x86 systems using Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Wed Dec 30 04:02:03 2009 @@ -972,7 +972,7 @@ exts.append( Extension('resource', ['resource.c']) ) # Sun yellow pages. Some systems have the functions in libc. - if platform not in ['cygwin', 'qnx6']: + if platform not in ['cygwin', 'qnx6'] and find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None: if (self.compiler_obj.find_library_file(lib_dirs, 'nsl')): libs = ['nsl'] else: From python-checkins at python.org Wed Dec 30 04:02:34 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 03:02:34 -0000 Subject: [Python-checkins] r77130 - python/trunk/setup.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 04:02:34 2009 New Revision: 77130 Log: wrap long line Modified: python/trunk/setup.py Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Wed Dec 30 04:02:34 2009 @@ -1088,7 +1088,8 @@ missing.append('resource') # Sun yellow pages. Some systems have the functions in libc. - if platform not in ['cygwin', 'atheos', 'qnx6'] and find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None: + if (platform not in ['cygwin', 'atheos', 'qnx6'] and + find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None): if (self.compiler_obj.find_library_file(lib_dirs, 'nsl')): libs = ['nsl'] else: From python-checkins at python.org Wed Dec 30 04:02:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 03:02:40 -0000 Subject: [Python-checkins] r77131 - in python/branches/release26-maint: Misc/NEWS setup.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 04:02:39 2009 New Revision: 77131 Log: Merged revisions 77128 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77128 | benjamin.peterson | 2009-12-29 20:58:50 -0600 (Tue, 29 Dec 2009) | 1 line only build the nis module when the headers are found #7589 ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/setup.py Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Dec 30 04:02:39 2009 @@ -124,6 +124,9 @@ Build ----- +- Issue #7589: Only build the nis module when the correct header files are + found. + - Switch to OpenSSL 0.9.8l on Windows. - Issue #6603: Change READ_TIMESTAMP macro in ceval.c so that it Modified: python/branches/release26-maint/setup.py ============================================================================== --- python/branches/release26-maint/setup.py (original) +++ python/branches/release26-maint/setup.py Wed Dec 30 04:02:39 2009 @@ -1065,7 +1065,7 @@ missing.append('resource') # Sun yellow pages. Some systems have the functions in libc. - if platform not in ['cygwin', 'atheos', 'qnx6']: + if platform not in ['cygwin', 'atheos', 'qnx6'] and find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None: if (self.compiler.find_library_file(lib_dirs, 'nsl')): libs = ['nsl'] else: From python-checkins at python.org Wed Dec 30 04:03:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 03:03:54 -0000 Subject: [Python-checkins] r77132 - in python/branches/py3k: setup.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 04:03:54 2009 New Revision: 77132 Log: Merged revisions 77130 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77130 | benjamin.peterson | 2009-12-29 21:02:34 -0600 (Tue, 29 Dec 2009) | 1 line wrap long line ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/setup.py Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Wed Dec 30 04:03:54 2009 @@ -972,7 +972,8 @@ exts.append( Extension('resource', ['resource.c']) ) # Sun yellow pages. Some systems have the functions in libc. - if platform not in ['cygwin', 'qnx6'] and find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None: + if (platform not in ['cygwin', 'qnx6'] and + find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None): if (self.compiler_obj.find_library_file(lib_dirs, 'nsl')): libs = ['nsl'] else: From python-checkins at python.org Wed Dec 30 04:04:04 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 03:04:04 -0000 Subject: [Python-checkins] r77133 - in python/branches/release26-maint: setup.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 04:04:02 2009 New Revision: 77133 Log: Merged revisions 77130 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77130 | benjamin.peterson | 2009-12-29 21:02:34 -0600 (Tue, 29 Dec 2009) | 1 line wrap long line ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/setup.py Modified: python/branches/release26-maint/setup.py ============================================================================== --- python/branches/release26-maint/setup.py (original) +++ python/branches/release26-maint/setup.py Wed Dec 30 04:04:02 2009 @@ -1065,7 +1065,8 @@ missing.append('resource') # Sun yellow pages. Some systems have the functions in libc. - if platform not in ['cygwin', 'atheos', 'qnx6'] and find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None: + if (platform not in ['cygwin', 'atheos', 'qnx6'] and + find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None): if (self.compiler.find_library_file(lib_dirs, 'nsl')): libs = ['nsl'] else: From python-checkins at python.org Wed Dec 30 04:06:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 03:06:54 -0000 Subject: [Python-checkins] r77134 - in python/branches/release31-maint: Misc/NEWS setup.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 04:06:54 2009 New Revision: 77134 Log: Merged revisions 77129,77132 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77129 | benjamin.peterson | 2009-12-29 21:02:03 -0600 (Tue, 29 Dec 2009) | 9 lines Merged revisions 77128 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77128 | benjamin.peterson | 2009-12-29 20:58:50 -0600 (Tue, 29 Dec 2009) | 1 line only build the nis module when the headers are found #7589 ........ ................ r77132 | benjamin.peterson | 2009-12-29 21:03:54 -0600 (Tue, 29 Dec 2009) | 9 lines Merged revisions 77130 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77130 | benjamin.peterson | 2009-12-29 21:02:34 -0600 (Tue, 29 Dec 2009) | 1 line wrap long line ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/setup.py Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Wed Dec 30 04:06:54 2009 @@ -403,6 +403,9 @@ Build ----- +- Issue #7589: Only build the nis module when the correct header files are + found. + - Issue 4601: 'make install' did not set the appropriate permissions on directories. Modified: python/branches/release31-maint/setup.py ============================================================================== --- python/branches/release31-maint/setup.py (original) +++ python/branches/release31-maint/setup.py Wed Dec 30 04:06:54 2009 @@ -979,8 +979,9 @@ missing.append('resource') # Sun yellow pages. Some systems have the functions in libc. - if platform not in ['cygwin', 'atheos', 'qnx6']: - if (self.compiler.find_library_file(lib_dirs, 'nsl')): + if (platform not in ['cygwin', 'qnx6'] and + find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None): + if (self.compiler_obj.find_library_file(lib_dirs, 'nsl')): libs = ['nsl'] else: libs = [] From python-checkins at python.org Wed Dec 30 04:40:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 03:40:09 -0000 Subject: [Python-checkins] r77135 - python/branches/release31-maint/setup.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 04:40:09 2009 New Revision: 77135 Log: compiler_obj -> compiler Modified: python/branches/release31-maint/setup.py Modified: python/branches/release31-maint/setup.py ============================================================================== --- python/branches/release31-maint/setup.py (original) +++ python/branches/release31-maint/setup.py Wed Dec 30 04:40:09 2009 @@ -981,7 +981,7 @@ # Sun yellow pages. Some systems have the functions in libc. if (platform not in ['cygwin', 'qnx6'] and find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None): - if (self.compiler_obj.find_library_file(lib_dirs, 'nsl')): + if (self.compiler.find_library_file(lib_dirs, 'nsl')): libs = ['nsl'] else: libs = [] From python-checkins at python.org Wed Dec 30 07:14:51 2009 From: python-checkins at python.org (ezio.melotti) Date: Wed, 30 Dec 2009 06:14:51 -0000 Subject: [Python-checkins] r77136 - in python/trunk: Doc/library/zipfile.rst Lib/test/test_zipfile.py Lib/zipfile.py Misc/NEWS Message-ID: Author: ezio.melotti Date: Wed Dec 30 07:14:51 2009 New Revision: 77136 Log: #5511: Added the ability to use ZipFile as a context manager. Patch by Brian Curtin. Modified: python/trunk/Doc/library/zipfile.rst python/trunk/Lib/test/test_zipfile.py python/trunk/Lib/zipfile.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/zipfile.rst ============================================================================== --- python/trunk/Doc/library/zipfile.rst (original) +++ python/trunk/Doc/library/zipfile.rst Wed Dec 30 07:14:51 2009 @@ -105,28 +105,35 @@ Open a ZIP file, where *file* can be either a path to a file (a string) or a file-like object. The *mode* parameter should be ``'r'`` to read an existing file, ``'w'`` to truncate and write a new file, or ``'a'`` to append to an - existing file. If *mode* is ``'a'`` and *file* refers to an existing ZIP file, - then additional files are added to it. If *file* does not refer to a ZIP file, - then a new ZIP archive is appended to the file. This is meant for adding a ZIP - archive to another file, such as :file:`python.exe`. Using :: - - cat myzip.zip >> python.exe - - also works, and at least :program:`WinZip` can read such files. If *mode* is - ``a`` and the file does not exist at all, it is created. *compression* is the - ZIP compression method to use when writing the archive, and should be - :const:`ZIP_STORED` or :const:`ZIP_DEFLATED`; unrecognized values will cause - :exc:`RuntimeError` to be raised. If :const:`ZIP_DEFLATED` is specified but the - :mod:`zlib` module is not available, :exc:`RuntimeError` is also raised. The - default is :const:`ZIP_STORED`. If *allowZip64* is ``True`` zipfile will create - ZIP files that use the ZIP64 extensions when the zipfile is larger than 2 GB. If - it is false (the default) :mod:`zipfile` will raise an exception when the ZIP - file would require ZIP64 extensions. ZIP64 extensions are disabled by default - because the default :program:`zip` and :program:`unzip` commands on Unix (the - InfoZIP utilities) don't support these extensions. + existing file. If *mode* is ``'a'`` and *file* refers to an existing ZIP + file, then additional files are added to it. If *file* does not refer to a + ZIP file, then a new ZIP archive is appended to the file. This is meant for + adding a ZIP archive to another file (such as :file:`python.exe`). .. versionchanged:: 2.6 - If the file does not exist, it is created if the mode is 'a'. + If *mode* is ``a`` and the file does not exist at all, it is created. + + *compression* is the ZIP compression method to use when writing the archive, + and should be :const:`ZIP_STORED` or :const:`ZIP_DEFLATED`; unrecognized + values will cause :exc:`RuntimeError` to be raised. If :const:`ZIP_DEFLATED` + is specified but the :mod:`zlib` module is not available, :exc:`RuntimeError` + is also raised. The default is :const:`ZIP_STORED`. If *allowZip64* is + ``True`` zipfile will create ZIP files that use the ZIP64 extensions when + the zipfile is larger than 2 GB. If it is false (the default) :mod:`zipfile` + will raise an exception when the ZIP file would require ZIP64 extensions. + ZIP64 extensions are disabled by default because the default :program:`zip` + and :program:`unzip` commands on Unix (the InfoZIP utilities) don't support + these extensions. + + ZipFile is also a context manager and therefore supports the + :keyword:`with` statement. In the example, *myzip* is closed after the + :keyword:`with` statement's suite is finished---even if an exception occurs:: + + with ZipFile('spam.zip', 'w') as myzip: + myzip.write('eggs.txt') + + .. versionadded:: 2.7 + Added the ability to use :class:`ZipFile` as a context manager. .. method:: ZipFile.close() Modified: python/trunk/Lib/test/test_zipfile.py ============================================================================== --- python/trunk/Lib/test/test_zipfile.py (original) +++ python/trunk/Lib/test/test_zipfile.py Wed Dec 30 07:14:51 2009 @@ -41,69 +41,67 @@ def make_test_archive(self, f, compression): # Create the ZIP archive - zipfp = zipfile.ZipFile(f, "w", compression) - zipfp.write(TESTFN, "another"+os.extsep+"name") - zipfp.write(TESTFN, TESTFN) - zipfp.writestr("strfile", self.data) - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + zipfp.write(TESTFN, "another"+os.extsep+"name") + zipfp.write(TESTFN, TESTFN) + zipfp.writestr("strfile", self.data) def zip_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - self.assertEqual(zipfp.read(TESTFN), self.data) - self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data) - self.assertEqual(zipfp.read("strfile"), self.data) + with zipfile.ZipFile(f, "r", compression) as zipfp: + self.assertEqual(zipfp.read(TESTFN), self.data) + self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data) + self.assertEqual(zipfp.read("strfile"), self.data) + + # Print the ZIP directory + fp = StringIO() + stdout = sys.stdout + try: + sys.stdout = fp + zipfp.printdir() + finally: + sys.stdout = stdout + + directory = fp.getvalue() + lines = directory.splitlines() + self.assertEquals(len(lines), 4) # Number of files + header + + self.assertTrue('File Name' in lines[0]) + self.assertTrue('Modified' in lines[0]) + self.assertTrue('Size' in lines[0]) + + fn, date, time, size = lines[1].split() + self.assertEquals(fn, 'another.name') + # XXX: timestamp is not tested + self.assertEquals(size, str(len(self.data))) - # Print the ZIP directory - fp = StringIO() - stdout = sys.stdout - try: - sys.stdout = fp - zipfp.printdir() - finally: - sys.stdout = stdout + # Check the namelist + names = zipfp.namelist() + self.assertEquals(len(names), 3) + self.assertTrue(TESTFN in names) + self.assertTrue("another"+os.extsep+"name" in names) + self.assertTrue("strfile" in names) + + # Check infolist + infos = zipfp.infolist() + names = [ i.filename for i in infos ] + self.assertEquals(len(names), 3) + self.assertTrue(TESTFN in names) + self.assertTrue("another"+os.extsep+"name" in names) + self.assertTrue("strfile" in names) + for i in infos: + self.assertEquals(i.file_size, len(self.data)) + + # check getinfo + for nm in (TESTFN, "another"+os.extsep+"name", "strfile"): + info = zipfp.getinfo(nm) + self.assertEquals(info.filename, nm) + self.assertEquals(info.file_size, len(self.data)) - directory = fp.getvalue() - lines = directory.splitlines() - self.assertEquals(len(lines), 4) # Number of files + header - - self.assertTrue('File Name' in lines[0]) - self.assertTrue('Modified' in lines[0]) - self.assertTrue('Size' in lines[0]) - - fn, date, time, size = lines[1].split() - self.assertEquals(fn, 'another.name') - # XXX: timestamp is not tested - self.assertEquals(size, str(len(self.data))) - - # Check the namelist - names = zipfp.namelist() - self.assertEquals(len(names), 3) - self.assertTrue(TESTFN in names) - self.assertTrue("another"+os.extsep+"name" in names) - self.assertTrue("strfile" in names) - - # Check infolist - infos = zipfp.infolist() - names = [ i.filename for i in infos ] - self.assertEquals(len(names), 3) - self.assertTrue(TESTFN in names) - self.assertTrue("another"+os.extsep+"name" in names) - self.assertTrue("strfile" in names) - for i in infos: - self.assertEquals(i.file_size, len(self.data)) - - # check getinfo - for nm in (TESTFN, "another"+os.extsep+"name", "strfile"): - info = zipfp.getinfo(nm) - self.assertEquals(info.filename, nm) - self.assertEquals(info.file_size, len(self.data)) - - # Check that testzip doesn't raise an exception - zipfp.testzip() - zipfp.close() + # Check that testzip doesn't raise an exception + zipfp.testzip() def test_stored(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -113,26 +111,25 @@ self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - zipdata1 = [] - zipopen1 = zipfp.open(TESTFN) - while 1: - read_data = zipopen1.read(256) - if not read_data: - break - zipdata1.append(read_data) - - zipdata2 = [] - zipopen2 = zipfp.open("another"+os.extsep+"name") - while 1: - read_data = zipopen2.read(256) - if not read_data: - break - zipdata2.append(read_data) - - self.assertEqual(''.join(zipdata1), self.data) - self.assertEqual(''.join(zipdata2), self.data) - zipfp.close() + with zipfile.ZipFile(f, "r", compression) as zipfp: + zipdata1 = [] + zipopen1 = zipfp.open(TESTFN) + while True: + read_data = zipopen1.read(256) + if not read_data: + break + zipdata1.append(read_data) + + zipdata2 = [] + zipopen2 = zipfp.open("another"+os.extsep+"name") + while True: + read_data = zipopen2.read(256) + if not read_data: + break + zipdata2.append(read_data) + + self.assertEqual(''.join(zipdata1), self.data) + self.assertEqual(''.join(zipdata2), self.data) def test_open_stored(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -140,38 +137,35 @@ def test_open_via_zip_info(self): # Create the ZIP archive - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - zipfp.writestr("name", "foo") - zipfp.writestr("name", "bar") - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r") - infos = zipfp.infolist() - data = "" - for info in infos: - data += zipfp.open(info).read() - self.assertTrue(data == "foobar" or data == "barfoo") - data = "" - for info in infos: - data += zipfp.read(info) - self.assertTrue(data == "foobar" or data == "barfoo") - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.writestr("name", "foo") + zipfp.writestr("name", "bar") + + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + infos = zipfp.infolist() + data = "" + for info in infos: + data += zipfp.open(info).read() + self.assertTrue(data == "foobar" or data == "barfoo") + data = "" + for info in infos: + data += zipfp.read(info) + self.assertTrue(data == "foobar" or data == "barfoo") def zip_random_open_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - zipdata1 = [] - zipopen1 = zipfp.open(TESTFN) - while 1: - read_data = zipopen1.read(randint(1, 1024)) - if not read_data: - break - zipdata1.append(read_data) + with zipfile.ZipFile(f, "r", compression) as zipfp: + zipdata1 = [] + zipopen1 = zipfp.open(TESTFN) + while True: + read_data = zipopen1.read(randint(1, 1024)) + if not read_data: + break + zipdata1.append(read_data) - self.assertEqual(''.join(zipdata1), self.data) - zipfp.close() + self.assertEqual(''.join(zipdata1), self.data) def test_random_open_stored(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -181,34 +175,28 @@ self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - zipopen = zipfp.open(TESTFN) - for line in self.line_gen: - linedata = zipopen.readline() - self.assertEqual(linedata, line + '\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + zipopen = zipfp.open(TESTFN) + for line in self.line_gen: + linedata = zipopen.readline() + self.assertEqual(linedata, line + '\n') def zip_readlines_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - ziplines = zipfp.open(TESTFN).readlines() - for line, zipline in zip(self.line_gen, ziplines): - self.assertEqual(zipline, line + '\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + ziplines = zipfp.open(TESTFN).readlines() + for line, zipline in zip(self.line_gen, ziplines): + self.assertEqual(zipline, line + '\n') def zip_iterlines_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for line, zipline in zip(self.line_gen, zipfp.open(TESTFN)): - self.assertEqual(zipline, line + '\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for line, zipline in zip(self.line_gen, zipfp.open(TESTFN)): + self.assertEqual(zipline, line + '\n') def test_readline_stored(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -256,34 +244,30 @@ def test_low_compression(self): # Checks for cases where compressed data is larger than original # Create the ZIP archive - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) - zipfp.writestr("strfile", '12') - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp: + zipfp.writestr("strfile", '12') # Get an open object for strfile - zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_DEFLATED) - openobj = zipfp.open("strfile") - self.assertEqual(openobj.read(1), '1') - self.assertEqual(openobj.read(1), '2') + with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_DEFLATED) as zipfp: + openobj = zipfp.open("strfile") + self.assertEqual(openobj.read(1), '1') + self.assertEqual(openobj.read(1), '2') def test_absolute_arcnames(self): - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - zipfp.write(TESTFN, "/absolute") - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) - self.assertEqual(zipfp.namelist(), ["absolute"]) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, "/absolute") + + with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp: + self.assertEqual(zipfp.namelist(), ["absolute"]) def test_append_to_zip_file(self): # Test appending to an existing zipfile - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - zipfp.write(TESTFN, TESTFN) - zipfp.close() - zipfp = zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) - zipfp.writestr("strfile", self.data) - self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"]) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) + + with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp: + zipfp.writestr("strfile", self.data) + self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"]) def test_append_to_non_zip_file(self): # Test appending to an existing file that is not a zipfile @@ -293,94 +277,83 @@ f = file(TESTFN2, 'wb') f.write(d) f.close() - zipfp = zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) - zipfp.write(TESTFN, TESTFN) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) f = file(TESTFN2, 'rb') f.seek(len(d)) - zipfp = zipfile.ZipFile(f, "r") - self.assertEqual(zipfp.namelist(), [TESTFN]) - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + self.assertEqual(zipfp.namelist(), [TESTFN]) f.close() def test_write_default_name(self): # Check that calling ZipFile.write without arcname specified produces the expected result - zipfp = zipfile.ZipFile(TESTFN2, "w") - zipfp.write(TESTFN) - self.assertEqual(zipfp.read(TESTFN), file(TESTFN).read()) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w") as zipfp: + zipfp.write(TESTFN) + self.assertEqual(zipfp.read(TESTFN), file(TESTFN).read()) @skipUnless(zlib, "requires zlib") def test_per_file_compression(self): # Check that files within a Zip archive can have different compression options - zipfp = zipfile.ZipFile(TESTFN2, "w") - zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED) - zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED) - sinfo = zipfp.getinfo('storeme') - dinfo = zipfp.getinfo('deflateme') - self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED) - self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w") as zipfp: + zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED) + zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED) + sinfo = zipfp.getinfo('storeme') + dinfo = zipfp.getinfo('deflateme') + self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED) + self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED) def test_write_to_readonly(self): # Check that trying to call write() on a readonly ZipFile object # raises a RuntimeError - zipf = zipfile.ZipFile(TESTFN2, mode="w") - zipf.writestr("somefile.txt", "bogus") - zipf.close() - zipf = zipfile.ZipFile(TESTFN2, mode="r") - self.assertRaises(RuntimeError, zipf.write, TESTFN) - zipf.close() + with zipfile.ZipFile(TESTFN2, mode="w") as zipfp: + zipfp.writestr("somefile.txt", "bogus") - def test_extract(self): - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - for fpath, fdata in SMALL_TEST_DATA: - zipfp.writestr(fpath, fdata) - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r") - for fpath, fdata in SMALL_TEST_DATA: - writtenfile = zipfp.extract(fpath) - - # make sure it was written to the right place - if os.path.isabs(fpath): - correctfile = os.path.join(os.getcwd(), fpath[1:]) - else: - correctfile = os.path.join(os.getcwd(), fpath) - correctfile = os.path.normpath(correctfile) + with zipfile.ZipFile(TESTFN2, mode="r") as zipfp: + self.assertRaises(RuntimeError, zipfp.write, TESTFN) - self.assertEqual(writtenfile, correctfile) + def test_extract(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + writtenfile = zipfp.extract(fpath) + + # make sure it was written to the right place + if os.path.isabs(fpath): + correctfile = os.path.join(os.getcwd(), fpath[1:]) + else: + correctfile = os.path.join(os.getcwd(), fpath) + correctfile = os.path.normpath(correctfile) - # make sure correct data is in correct file - self.assertEqual(fdata, file(writtenfile, "rb").read()) + self.assertEqual(writtenfile, correctfile) - os.remove(writtenfile) + # make sure correct data is in correct file + self.assertEqual(fdata, file(writtenfile, "rb").read()) - zipfp.close() + os.remove(writtenfile) # remove the test file subdirectories shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) def test_extract_all(self): - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - for fpath, fdata in SMALL_TEST_DATA: - zipfp.writestr(fpath, fdata) - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r") - zipfp.extractall() - for fpath, fdata in SMALL_TEST_DATA: - if os.path.isabs(fpath): - outfile = os.path.join(os.getcwd(), fpath[1:]) - else: - outfile = os.path.join(os.getcwd(), fpath) - - self.assertEqual(fdata, file(outfile, "rb").read()) + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + zipfp.extractall() + for fpath, fdata in SMALL_TEST_DATA: + if os.path.isabs(fpath): + outfile = os.path.join(os.getcwd(), fpath[1:]) + else: + outfile = os.path.join(os.getcwd(), fpath) - os.remove(outfile) + self.assertEqual(fdata, file(outfile, "rb").read()) - zipfp.close() + os.remove(outfile) # remove the test file subdirectories shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) @@ -390,14 +363,39 @@ # when it is passed a name rather than a ZipInfo instance. self.make_test_archive(f, compression) - zipfp = zipfile.ZipFile(f, "r") - zinfo = zipfp.getinfo('strfile') - self.assertEqual(zinfo.external_attr, 0600 << 16) + with zipfile.ZipFile(f, "r") as zipfp: + zinfo = zipfp.getinfo('strfile') + self.assertEqual(zinfo.external_attr, 0600 << 16) def test_writestr_permissions(self): for f in (TESTFN2, TemporaryFile(), StringIO()): self.zip_test_writestr_permissions(f, zipfile.ZIP_STORED) + def test_close(self): + """Check that the zipfile is closed after the 'with' block.""" + with zipfile.ZipFile(TESTFN2, "w") as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + self.assertTrue(zipfp.fp is not None, 'zipfp is not open') + self.assertTrue(zipfp.fp is None, 'zipfp is not closed') + + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertTrue(zipfp.fp is not None, 'zipfp is not open') + self.assertTrue(zipfp.fp is None, 'zipfp is not closed') + + def test_close_on_exception(self): + """Check that the zipfile is closed if an exception is raised in the + 'with' block.""" + with zipfile.ZipFile(TESTFN2, "w") as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + + try: + with zipfile.ZipFile(TESTFN2, "r") as zipfp2: + raise zipfile.BadZipfile() + except zipfile.BadZipfile: + self.assertTrue(zipfp2.fp is None, 'zipfp is not closed') + def tearDown(self): unlink(TESTFN) unlink(TESTFN2) @@ -420,16 +418,14 @@ fp.close() def large_file_exception_test(self, f, compression): - zipfp = zipfile.ZipFile(f, "w", compression) - self.assertRaises(zipfile.LargeZipFile, - zipfp.write, TESTFN, "another"+os.extsep+"name") - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + self.assertRaises(zipfile.LargeZipFile, + zipfp.write, TESTFN, "another"+os.extsep+"name") def large_file_exception_test2(self, f, compression): - zipfp = zipfile.ZipFile(f, "w", compression) - self.assertRaises(zipfile.LargeZipFile, - zipfp.writestr, "another"+os.extsep+"name", self.data) - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + self.assertRaises(zipfile.LargeZipFile, + zipfp.writestr, "another"+os.extsep+"name", self.data) def test_large_file_exception(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -438,68 +434,64 @@ def zip_test(self, f, compression): # Create the ZIP archive - zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True) - zipfp.write(TESTFN, "another"+os.extsep+"name") - zipfp.write(TESTFN, TESTFN) - zipfp.writestr("strfile", self.data) - zipfp.close() + with zipfile.ZipFile(f, "w", compression, allowZip64=True) as zipfp: + zipfp.write(TESTFN, "another"+os.extsep+"name") + zipfp.write(TESTFN, TESTFN) + zipfp.writestr("strfile", self.data) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - self.assertEqual(zipfp.read(TESTFN), self.data) - self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data) - self.assertEqual(zipfp.read("strfile"), self.data) + with zipfile.ZipFile(f, "r", compression) as zipfp: + self.assertEqual(zipfp.read(TESTFN), self.data) + self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data) + self.assertEqual(zipfp.read("strfile"), self.data) + + # Print the ZIP directory + fp = StringIO() + stdout = sys.stdout + try: + sys.stdout = fp + zipfp.printdir() + finally: + sys.stdout = stdout + + directory = fp.getvalue() + lines = directory.splitlines() + self.assertEquals(len(lines), 4) # Number of files + header + + self.assertTrue('File Name' in lines[0]) + self.assertTrue('Modified' in lines[0]) + self.assertTrue('Size' in lines[0]) + + fn, date, time, size = lines[1].split() + self.assertEquals(fn, 'another.name') + # XXX: timestamp is not tested + self.assertEquals(size, str(len(self.data))) - # Print the ZIP directory - fp = StringIO() - stdout = sys.stdout - try: - sys.stdout = fp - - zipfp.printdir() - finally: - sys.stdout = stdout - - directory = fp.getvalue() - lines = directory.splitlines() - self.assertEquals(len(lines), 4) # Number of files + header - - self.assertTrue('File Name' in lines[0]) - self.assertTrue('Modified' in lines[0]) - self.assertTrue('Size' in lines[0]) - - fn, date, time, size = lines[1].split() - self.assertEquals(fn, 'another.name') - # XXX: timestamp is not tested - self.assertEquals(size, str(len(self.data))) - - # Check the namelist - names = zipfp.namelist() - self.assertEquals(len(names), 3) - self.assertTrue(TESTFN in names) - self.assertTrue("another"+os.extsep+"name" in names) - self.assertTrue("strfile" in names) - - # Check infolist - infos = zipfp.infolist() - names = [ i.filename for i in infos ] - self.assertEquals(len(names), 3) - self.assertTrue(TESTFN in names) - self.assertTrue("another"+os.extsep+"name" in names) - self.assertTrue("strfile" in names) - for i in infos: - self.assertEquals(i.file_size, len(self.data)) - - # check getinfo - for nm in (TESTFN, "another"+os.extsep+"name", "strfile"): - info = zipfp.getinfo(nm) - self.assertEquals(info.filename, nm) - self.assertEquals(info.file_size, len(self.data)) - - # Check that testzip doesn't raise an exception - zipfp.testzip() + # Check the namelist + names = zipfp.namelist() + self.assertEquals(len(names), 3) + self.assertTrue(TESTFN in names) + self.assertTrue("another"+os.extsep+"name" in names) + self.assertTrue("strfile" in names) + + # Check infolist + infos = zipfp.infolist() + names = [ i.filename for i in infos ] + self.assertEquals(len(names), 3) + self.assertTrue(TESTFN in names) + self.assertTrue("another"+os.extsep+"name" in names) + self.assertTrue("strfile" in names) + for i in infos: + self.assertEquals(i.file_size, len(self.data)) + + # check getinfo + for nm in (TESTFN, "another"+os.extsep+"name", "strfile"): + info = zipfp.getinfo(nm) + self.assertEquals(info.filename, nm) + self.assertEquals(info.file_size, len(self.data)) - zipfp.close() + # Check that testzip doesn't raise an exception + zipfp.testzip() def test_stored(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -511,13 +503,12 @@ self.zip_test(f, zipfile.ZIP_DEFLATED) def test_absolute_arcnames(self): - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED, allowZip64=True) - zipfp.write(TESTFN, "/absolute") - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) - self.assertEqual(zipfp.namelist(), ["absolute"]) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED, + allowZip64=True) as zipfp: + zipfp.write(TESTFN, "/absolute") + + with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp: + self.assertEqual(zipfp.namelist(), ["absolute"]) def tearDown(self): zipfile.ZIP64_LIMIT = self._limit @@ -527,41 +518,43 @@ class PyZipFileTests(unittest.TestCase): def test_write_pyfile(self): - zipfp = zipfile.PyZipFile(TemporaryFile(), "w") - fn = __file__ - if fn.endswith('.pyc') or fn.endswith('.pyo'): - fn = fn[:-1] - - zipfp.writepy(fn) - - bn = os.path.basename(fn) - self.assertTrue(bn not in zipfp.namelist()) - self.assertTrue(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist()) - zipfp.close() - - zipfp = zipfile.PyZipFile(TemporaryFile(), "w") - fn = __file__ - if fn.endswith('.pyc') or fn.endswith('.pyo'): - fn = fn[:-1] - - zipfp.writepy(fn, "testpackage") - - bn = "%s/%s"%("testpackage", os.path.basename(fn)) - self.assertTrue(bn not in zipfp.namelist()) - self.assertTrue(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist()) - zipfp.close() + with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: + fn = __file__ + if fn.endswith('.pyc') or fn.endswith('.pyo'): + fn = fn[:-1] + + zipfp.writepy(fn) + + bn = os.path.basename(fn) + self.assertTrue(bn not in zipfp.namelist()) + self.assertTrue(bn + 'o' in zipfp.namelist() or + bn + 'c' in zipfp.namelist()) + + with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: + fn = __file__ + if fn.endswith('.pyc') or fn.endswith('.pyo'): + fn = fn[:-1] + + zipfp.writepy(fn, "testpackage") + + bn = "%s/%s"%("testpackage", os.path.basename(fn)) + self.assertTrue(bn not in zipfp.namelist()) + self.assertTrue(bn + 'o' in zipfp.namelist() or + bn + 'c' in zipfp.namelist()) def test_write_python_package(self): import email packagedir = os.path.dirname(email.__file__) - zipfp = zipfile.PyZipFile(TemporaryFile(), "w") - zipfp.writepy(packagedir) + with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: + zipfp.writepy(packagedir) - # Check for a couple of modules at different levels of the hieararchy - names = zipfp.namelist() - self.assertTrue('email/__init__.pyo' in names or 'email/__init__.pyc' in names) - self.assertTrue('email/mime/text.pyo' in names or 'email/mime/text.pyc' in names) + # Check for a couple of modules at different levels of the hieararchy + names = zipfp.namelist() + self.assertTrue('email/__init__.pyo' in names or + 'email/__init__.pyc' in names) + self.assertTrue('email/mime/text.pyo' in names or + 'email/mime/text.pyc' in names) def test_write_python_directory(self): os.mkdir(TESTFN2) @@ -590,23 +583,22 @@ shutil.rmtree(TESTFN2) def test_write_non_pyfile(self): - zipfp = zipfile.PyZipFile(TemporaryFile(), "w") - file(TESTFN, 'w').write('most definitely not a python file') - self.assertRaises(RuntimeError, zipfp.writepy, TESTFN) - os.remove(TESTFN) + with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: + file(TESTFN, 'w').write('most definitely not a python file') + self.assertRaises(RuntimeError, zipfp.writepy, TESTFN) + os.remove(TESTFN) class OtherTests(unittest.TestCase): def test_unicode_filenames(self): - zf = zipfile.ZipFile(TESTFN, "w") - zf.writestr(u"foo.txt", "Test for unicode filename") - zf.writestr(u"\xf6.txt", "Test for unicode filename") - self.assertTrue(isinstance(zf.infolist()[0].filename, unicode)) - zf.close() - zf = zipfile.ZipFile(TESTFN, "r") - self.assertEqual(zf.filelist[0].filename, "foo.txt") - self.assertEqual(zf.filelist[1].filename, u"\xf6.txt") - zf.close() + with zipfile.ZipFile(TESTFN, "w") as zf: + zf.writestr(u"foo.txt", "Test for unicode filename") + zf.writestr(u"\xf6.txt", "Test for unicode filename") + self.assertTrue(isinstance(zf.infolist()[0].filename, unicode)) + + with zipfile.ZipFile(TESTFN, "r") as zf: + self.assertEqual(zf.filelist[0].filename, "foo.txt") + self.assertEqual(zf.filelist[1].filename, u"\xf6.txt") def test_create_non_existent_file_for_append(self): if os.path.exists(TESTFN): @@ -616,17 +608,15 @@ content = 'hello, world. this is some content.' try: - zf = zipfile.ZipFile(TESTFN, 'a') - zf.writestr(filename, content) - zf.close() + with zipfile.ZipFile(TESTFN, 'a') as zf: + zf.writestr(filename, content) except IOError: self.fail('Could not append data to a non-existent zip file.') self.assertTrue(os.path.exists(TESTFN)) - zf = zipfile.ZipFile(TESTFN, 'r') - self.assertEqual(zf.read(filename), content) - zf.close() + with zipfile.ZipFile(TESTFN, 'r') as zf: + self.assertEqual(zf.read(filename), content) def test_close_erroneous_file(self): # This test checks that the ZipFile constructor closes the file object @@ -670,9 +660,8 @@ # a file that is a zip file # - passing a filename - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.writestr("foo.txt", "O, for a Muse of Fire!") chk = zipfile.is_zipfile(TESTFN) self.assertTrue(chk) # - passing a file object @@ -717,9 +706,8 @@ def test_closed_zip_raises_RuntimeError(self): # Verify that testzip() doesn't swallow inappropriate exceptions. data = StringIO() - zipf = zipfile.ZipFile(data, mode="w") - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() + with zipfile.ZipFile(data, mode="w") as zipf: + zipf.writestr("foo.txt", "O, for a Muse of Fire!") # This is correct; calling .read on a closed ZipFile should throw # a RuntimeError, and so should calling .testzip. An earlier @@ -738,33 +726,31 @@ def test_bad_open_mode(self): # Check that bad modes passed to ZipFile.open are caught - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipf = zipfile.ZipFile(TESTFN, mode="r") + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + + with zipfile.ZipFile(TESTFN, mode="r") as zipf: # read the data to make sure the file is there - zipf.read("foo.txt") - self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q") - zipf.close() + zipf.read("foo.txt") + self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q") def test_read0(self): # Check that calling read(0) on a ZipExtFile object returns an empty # string and doesn't advance file pointer - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - # read the data to make sure the file is there - f = zipf.open("foo.txt") - for i in xrange(FIXEDTEST_SIZE): - self.assertEqual(f.read(0), '') + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + # read the data to make sure the file is there + f = zipf.open("foo.txt") + for i in xrange(FIXEDTEST_SIZE): + self.assertEqual(f.read(0), '') - self.assertEqual(f.read(), "O, for a Muse of Fire!") - zipf.close() + self.assertEqual(f.read(), "O, for a Muse of Fire!") def test_open_non_existent_item(self): # Check that attempting to call open() for an item that doesn't # exist in the archive raises a RuntimeError - zipf = zipfile.ZipFile(TESTFN, mode="w") - self.assertRaises(KeyError, zipf.open, "foo.txt", "r") + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + self.assertRaises(KeyError, zipf.open, "foo.txt", "r") def test_bad_compression_mode(self): # Check that bad compression methods passed to ZipFile.open are caught @@ -772,9 +758,9 @@ def test_null_byte_in_filename(self): # Check that a filename containing a null byte is properly terminated - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.writestr("foo.txt\x00qqq", "O, for a Muse of Fire!") - self.assertEqual(zipf.namelist(), ['foo.txt']) + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.writestr("foo.txt\x00qqq", "O, for a Muse of Fire!") + self.assertEqual(zipf.namelist(), ['foo.txt']) def test_struct_sizes(self): # check that ZIP internal structure sizes are calculated correctly @@ -787,42 +773,36 @@ # This test checks that comments on the archive are handled properly # check default comment is empty - zipf = zipfile.ZipFile(TESTFN, mode="w") - self.assertEqual(zipf.comment, '') - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipfr = zipfile.ZipFile(TESTFN, mode="r") - self.assertEqual(zipfr.comment, '') - zipfr.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + self.assertEqual(zipf.comment, '') + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + + with zipfile.ZipFile(TESTFN, mode="r") as zipf: + self.assertEqual(zipf.comment, '') # check a simple short comment comment = 'Bravely taking to his feet, he beat a very brave retreat.' - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.comment = comment - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipfr = zipfile.ZipFile(TESTFN, mode="r") - self.assertEqual(zipfr.comment, comment) - zipfr.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.comment = comment + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + with zipfile.ZipFile(TESTFN, mode="r") as zipf: + self.assertEqual(zipf.comment, comment) # check a comment of max length comment2 = ''.join(['%d' % (i**3 % 10) for i in xrange((1 << 16)-1)]) - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.comment = comment2 - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipfr = zipfile.ZipFile(TESTFN, mode="r") - self.assertEqual(zipfr.comment, comment2) - zipfr.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.comment = comment2 + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + + with zipfile.ZipFile(TESTFN, mode="r") as zipf: + self.assertEqual(zipf.comment, comment2) # check a comment that is too long is truncated - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.comment = comment2 + 'oops' - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipfr = zipfile.ZipFile(TESTFN, mode="r") - self.assertEqual(zipfr.comment, comment2) - zipfr.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.comment = comment2 + 'oops' + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + with zipfile.ZipFile(TESTFN, mode="r") as zipf: + self.assertEqual(zipf.comment, comment2) def tearDown(self): unlink(TESTFN) @@ -907,21 +887,19 @@ def make_test_archive(self, f, compression): # Create the ZIP archive - zipfp = zipfile.ZipFile(f, "w", compression) - zipfp.write(TESTFN, "another"+os.extsep+"name") - zipfp.write(TESTFN, TESTFN) - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + zipfp.write(TESTFN, "another"+os.extsep+"name") + zipfp.write(TESTFN, TESTFN) def zip_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - testdata = zipfp.read(TESTFN) - self.assertEqual(len(testdata), len(self.data)) - self.assertEqual(testdata, self.data) - self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data) - zipfp.close() + with zipfile.ZipFile(f, "r", compression) as zipfp: + testdata = zipfp.read(TESTFN) + self.assertEqual(len(testdata), len(self.data)) + self.assertEqual(testdata, self.data) + self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data) def test_stored(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -931,31 +909,30 @@ self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - zipdata1 = [] - zipopen1 = zipfp.open(TESTFN) - while 1: - read_data = zipopen1.read(256) - if not read_data: - break - zipdata1.append(read_data) - - zipdata2 = [] - zipopen2 = zipfp.open("another"+os.extsep+"name") - while 1: - read_data = zipopen2.read(256) - if not read_data: - break - zipdata2.append(read_data) - - testdata1 = ''.join(zipdata1) - self.assertEqual(len(testdata1), len(self.data)) - self.assertEqual(testdata1, self.data) - - testdata2 = ''.join(zipdata2) - self.assertEqual(len(testdata1), len(self.data)) - self.assertEqual(testdata1, self.data) - zipfp.close() + with zipfile.ZipFile(f, "r", compression) as zipfp: + zipdata1 = [] + zipopen1 = zipfp.open(TESTFN) + while True: + read_data = zipopen1.read(256) + if not read_data: + break + zipdata1.append(read_data) + + zipdata2 = [] + zipopen2 = zipfp.open("another"+os.extsep+"name") + while True: + read_data = zipopen2.read(256) + if not read_data: + break + zipdata2.append(read_data) + + testdata1 = ''.join(zipdata1) + self.assertEqual(len(testdata1), len(self.data)) + self.assertEqual(testdata1, self.data) + + testdata2 = ''.join(zipdata2) + self.assertEqual(len(testdata1), len(self.data)) + self.assertEqual(testdata1, self.data) def test_open_stored(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -965,19 +942,18 @@ self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - zipdata1 = [] - zipopen1 = zipfp.open(TESTFN) - while 1: - read_data = zipopen1.read(randint(1, 1024)) - if not read_data: - break - zipdata1.append(read_data) - - testdata = ''.join(zipdata1) - self.assertEqual(len(testdata), len(self.data)) - self.assertEqual(testdata, self.data) - zipfp.close() + with zipfile.ZipFile(f, "r", compression) as zipfp: + zipdata1 = [] + zipopen1 = zipfp.open(TESTFN) + while True: + read_data = zipopen1.read(randint(1, 1024)) + if not read_data: + break + zipdata1.append(read_data) + + testdata = ''.join(zipdata1) + self.assertEqual(len(testdata), len(self.data)) + self.assertEqual(testdata, self.data) def test_random_open_stored(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -988,51 +964,47 @@ class TestsWithMultipleOpens(unittest.TestCase): def setUp(self): # Create the ZIP archive - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) - zipfp.writestr('ones', '1'*FIXEDTEST_SIZE) - zipfp.writestr('twos', '2'*FIXEDTEST_SIZE) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp: + zipfp.writestr('ones', '1'*FIXEDTEST_SIZE) + zipfp.writestr('twos', '2'*FIXEDTEST_SIZE) def test_same_file(self): # Verify that (when the ZipFile is in control of creating file objects) # multiple open() calls can be made without interfering with each other. - zipf = zipfile.ZipFile(TESTFN2, mode="r") - zopen1 = zipf.open('ones') - zopen2 = zipf.open('ones') - data1 = zopen1.read(500) - data2 = zopen2.read(500) - data1 += zopen1.read(500) - data2 += zopen2.read(500) - self.assertEqual(data1, data2) - zipf.close() + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + zopen1 = zipf.open('ones') + zopen2 = zipf.open('ones') + data1 = zopen1.read(500) + data2 = zopen2.read(500) + data1 += zopen1.read(500) + data2 += zopen2.read(500) + self.assertEqual(data1, data2) def test_different_file(self): # Verify that (when the ZipFile is in control of creating file objects) # multiple open() calls can be made without interfering with each other. - zipf = zipfile.ZipFile(TESTFN2, mode="r") - zopen1 = zipf.open('ones') - zopen2 = zipf.open('twos') - data1 = zopen1.read(500) - data2 = zopen2.read(500) - data1 += zopen1.read(500) - data2 += zopen2.read(500) - self.assertEqual(data1, '1'*FIXEDTEST_SIZE) - self.assertEqual(data2, '2'*FIXEDTEST_SIZE) - zipf.close() + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + zopen1 = zipf.open('ones') + zopen2 = zipf.open('twos') + data1 = zopen1.read(500) + data2 = zopen2.read(500) + data1 += zopen1.read(500) + data2 += zopen2.read(500) + self.assertEqual(data1, '1'*FIXEDTEST_SIZE) + self.assertEqual(data2, '2'*FIXEDTEST_SIZE) def test_interleaved(self): # Verify that (when the ZipFile is in control of creating file objects) # multiple open() calls can be made without interfering with each other. - zipf = zipfile.ZipFile(TESTFN2, mode="r") - zopen1 = zipf.open('ones') - data1 = zopen1.read(500) - zopen2 = zipf.open('twos') - data2 = zopen2.read(500) - data1 += zopen1.read(500) - data2 += zopen2.read(500) - self.assertEqual(data1, '1'*FIXEDTEST_SIZE) - self.assertEqual(data2, '2'*FIXEDTEST_SIZE) - zipf.close() + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + zopen1 = zipf.open('ones') + data1 = zopen1.read(500) + zopen2 = zipf.open('twos') + data2 = zopen2.read(500) + data1 += zopen1.read(500) + data2 += zopen2.read(500) + self.assertEqual(data1, '1'*FIXEDTEST_SIZE) + self.assertEqual(data2, '2'*FIXEDTEST_SIZE) def tearDown(self): unlink(TESTFN2) @@ -1043,8 +1015,8 @@ os.mkdir(TESTFN2) def test_extract_dir(self): - zipf = zipfile.ZipFile(findfile("zipdir.zip")) - zipf.extractall(TESTFN2) + with zipfile.ZipFile(findfile("zipdir.zip")) as zipf: + zipf.extractall(TESTFN2) self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a"))) self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a", "b"))) self.assertTrue(os.path.exists(os.path.join(TESTFN2, "a", "b", "c"))) @@ -1078,57 +1050,48 @@ def make_test_archive(self, f, compression): # Create the ZIP archive - zipfp = zipfile.ZipFile(f, "w", compression) - for fn in self.arcfiles.values(): - zipfp.write(fn, fn) - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + for fn in self.arcfiles.values(): + zipfp.write(fn, fn) def read_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for sep, fn in self.arcfiles.items(): - zipdata = zipfp.open(fn, "rU").read() - self.assertEqual(self.arcdata[sep], zipdata) - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for sep, fn in self.arcfiles.items(): + zipdata = zipfp.open(fn, "rU").read() + self.assertEqual(self.arcdata[sep], zipdata) def readline_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for sep, fn in self.arcfiles.items(): - zipopen = zipfp.open(fn, "rU") - for line in self.line_gen: - linedata = zipopen.readline() - self.assertEqual(linedata, line + '\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for sep, fn in self.arcfiles.items(): + zipopen = zipfp.open(fn, "rU") + for line in self.line_gen: + linedata = zipopen.readline() + self.assertEqual(linedata, line + '\n') def readlines_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for sep, fn in self.arcfiles.items(): - ziplines = zipfp.open(fn, "rU").readlines() - for line, zipline in zip(self.line_gen, ziplines): - self.assertEqual(zipline, line + '\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for sep, fn in self.arcfiles.items(): + ziplines = zipfp.open(fn, "rU").readlines() + for line, zipline in zip(self.line_gen, ziplines): + self.assertEqual(zipline, line + '\n') def iterlines_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for sep, fn in self.arcfiles.items(): - for line, zipline in zip(self.line_gen, zipfp.open(fn, "rU")): - self.assertEqual(zipline, line + '\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for sep, fn in self.arcfiles.items(): + for line, zipline in zip(self.line_gen, zipfp.open(fn, "rU")): + self.assertEqual(zipline, line + '\n') def test_read_stored(self): for f in (TESTFN2, TemporaryFile(), StringIO()): Modified: python/trunk/Lib/zipfile.py ============================================================================== --- python/trunk/Lib/zipfile.py (original) +++ python/trunk/Lib/zipfile.py Wed Dec 30 07:14:51 2009 @@ -721,6 +721,12 @@ self.fp = None raise RuntimeError, 'Mode must be "r", "w" or "a"' + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + def _GetContents(self): """Read the directory, making sure we close the file if the format is bad.""" Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Dec 30 07:14:51 2009 @@ -44,8 +44,11 @@ Library ------- +- Issue #5511: now zipfile.ZipFile can be used as a context manager. + Initial patch by Brian Curtin. + - Distutils now correctly identifies the build architecture as "x86_64" - when building on OSX 10.6 without "-arch" flags. + when building on OSX 10.6 without "-arch" flags. - Issue #7556: Distutils' msvc9compiler now opens the MSVC Manifest file in text mode. From python-checkins at python.org Wed Dec 30 10:02:01 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 30 Dec 2009 09:02:01 -0000 Subject: [Python-checkins] r77137 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Wed Dec 30 10:02:01 2009 New Revision: 77137 Log: changed the range mechanism, after recent discussions in various MLs Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Wed Dec 30 10:02:01 2009 @@ -296,7 +296,7 @@ Provides-Dist (multiple use) :::::::::::::::::::::::::::: -Each entry contains a string naming a distutlis project which +Each entry contains a string naming a Distutils project which is contained within this distribution. This field *must* include the project identified in the ``Name`` field. @@ -416,29 +416,48 @@ Each version number must be in the format specified in PEP 386. -The range operator ("~=") is a special operator that can be used to -define a range of versions by describing a MAJOR or a MAJOR.MINOR -version. All versions that starts with the definition will -be included in the range. - -Examples: - -- ``Requires-Python: ~=2.5`` means all versions of Python 2.5. -- ``Requires-Python: ~=2`` means all versions of Python 2. -- ``~=2.5.2`` is equivalent to ``==2.5.2`` - -The range operator is limited to the MAJOR and MINOR parts of -a version string, as specified in PEP 386. Post and pre-releases -are not included in range operators. - -The ``Requires-External`` field can use the operators described in this -section but since the version scheme might not be compatible with PEP 386, -the range operator might not be appliable. - -For each field that uses a version, if no operator is provided, the -range operator is used by default. For example, ``Requires-Python: 2.5`` -is equivalent to ``Requires-Python: ~=2.5``. - +When a version is provided, it always includes all versions that +starts with the same value. For example the "2.5" version of Python +will include versions like "2.5.2" or "2.5.3". Pre and post releases +in that case are excluded. So in our example, versions like "2.5a1" are +not included when "2.5" is used. If the first version of the range is +required, it has to be explicitly given. In our example, it will be +"2.5.0". + +Notice that some projects might omit the ".0" prefix for the first release +of the "2.5.x" series: + +- 2.5 +- 2.5.1 +- 2.5.2 +- etc. + +In that case, "2.5.0" will have to be explicitly used to avoid any confusion +between the "2.5" notation that represents the full range. It is a recommended +practice to use schemes of the same length for a series to completely avoid +this problem. + +Some Examples: + +- ``Requires-Dist: zope.interface (3.1)``: any version that starts with 3.1, + excluding post or pre-releases. +- ``Requires-Dist: zope.interface (3.1.0)``: any version that starts with + 3.1.0, excluding post or pre-releases. Since that particular project doesn't + use more than 3 digits, it also means "only the 3.1.0 release". +- ``Requires-Python: 3``: Any Python 3 version, no matter wich one, excluding + post or pre-releases. +- ``Requires-Python: >=2.6,<3``: Any version of Python 2.6 or 2.7, including + post releases of 2.6, pre and post releases of 2.7. It excludes pre releases + of Python 3. +- ``Requires-Python: 2.6.2``: Equivalent to ">=2.6.2,<2.6.3". So this includes + only Python 2.6.2. Of course, if Python was numbered with 4 digits, it would + have include all versions of the 2.6.2 series. +- ``Requires-Python: 2.5.0``: Equivalent to ">=2.5.0,<2.5.1". +- ``Requires-Dist: zope.interface (3.1,!=3.1.3)``: any version that starts with + 3.1, excluding post or pre-releases of 3.1 *and* excluding any version that + starts with "3.1.3". For this particular project, this means: "any version + of the 3.1 series but not 3.1.3". This is equivalent to: + ">=3.1,!=3.1.3,<3.2". Environment markers =================== @@ -449,9 +468,9 @@ Here are some example of fields using such markers:: - Requires-Dist: pywin32 > 1.0; sys.platform == 'win32' + Requires-Dist: pywin32 (>1.0); sys.platform == 'win32' Obsoletes-Dist: pywin31; sys.platform == 'win32' - Requires-Dist: foo; os.machine == 'i386' + Requires-Dist: foo (1,!=1.3); os.machine == 'i386' Requires-Dist: bar; python_version == '2.4' or python_version == '2.5' Requires-External: libxslt; 'linux' in sys.platform From python-checkins at python.org Wed Dec 30 10:02:25 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 30 Dec 2009 09:02:25 -0000 Subject: [Python-checkins] r77138 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Wed Dec 30 10:02:25 2009 New Revision: 77138 Log: we don't work in the branch anymore Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Wed Dec 30 10:02:25 2009 @@ -27,7 +27,7 @@ Distutils will soon extend its capabilities to allow distributions to express a dependency on other distributions through the ``Requires-Dist`` metadata field -(see PEP 345 [#pep345]_) and it will optionally allow use of that field to +(see PEP 345) and it will optionally allow use of that field to restrict the dependency to a set of compatible versions. Notice that this field is replacing ``Requires`` that was expressing dependencies on modules and packages. @@ -467,9 +467,6 @@ .. [#requires] http://peak.telecommunity.com/DevCenter/setuptools -.. [#pep345] - http://svn.python.org/projects/peps/branches/jim-update-345/pep-0345.txt - .. [#prototype] http://bitbucket.org/tarek/distutilsversion/ From python-checkins at python.org Wed Dec 30 13:12:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 30 Dec 2009 12:12:24 -0000 Subject: [Python-checkins] r77139 - in python/trunk: Lib/test/ieee754.txt Lib/test/test_float.py Misc/NEWS Objects/floatobject.c Message-ID: Author: mark.dickinson Date: Wed Dec 30 13:12:23 2009 New Revision: 77139 Log: Issue #7534: Fix handling of nans, infinities, and negative zero in ** operator, on IEEE 754 platforms. Thanks Marcos Donolo for original patch. Modified: python/trunk/Lib/test/ieee754.txt python/trunk/Lib/test/test_float.py python/trunk/Misc/NEWS python/trunk/Objects/floatobject.c Modified: python/trunk/Lib/test/ieee754.txt ============================================================================== --- python/trunk/Lib/test/ieee754.txt (original) +++ python/trunk/Lib/test/ieee754.txt Wed Dec 30 13:12:23 2009 @@ -72,7 +72,7 @@ >>> NAN >= 0 False -All operations involving a NaN return a NaN except for the power of *0* and *1*. +All operations involving a NaN return a NaN except for nan**0 and 1**nan. >>> 1 + NAN nan >>> 1 * NAN @@ -81,8 +81,10 @@ nan >>> 1 ** NAN 1.0 +>>> NAN ** 0 +1.0 >>> 0 ** NAN -0.0 +nan >>> (1.0 + FI.epsilon) * NAN nan Modified: python/trunk/Lib/test/test_float.py ============================================================================== --- python/trunk/Lib/test/test_float.py (original) +++ python/trunk/Lib/test/test_float.py Wed Dec 30 13:12:23 2009 @@ -12,6 +12,11 @@ INF = float("inf") NAN = float("nan") +# decorator for skipping tests on non-IEEE 754 platforms +requires_IEEE_754 = unittest.skipUnless( + float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + #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') @@ -142,6 +147,213 @@ self.assertRaises(OverflowError, float('-inf').as_integer_ratio) self.assertRaises(ValueError, float('nan').as_integer_ratio) + def assertEqualAndEqualSign(self, a, b): + # fail unless a == b and a and b have the same sign bit; + # the only difference from assertEqual is that this test + # distingishes -0.0 and 0.0. + self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b))) + + @requires_IEEE_754 + def test_float_pow(self): + # test builtin pow and ** operator for IEEE 754 special cases. + # Special cases taken from section F.9.4.4 of the C99 specification + + for pow_op in pow, operator.pow: + # x**NAN is NAN for any x except 1 + self.assertTrue(isnan(pow_op(-INF, NAN))) + self.assertTrue(isnan(pow_op(-2.0, NAN))) + self.assertTrue(isnan(pow_op(-1.0, NAN))) + self.assertTrue(isnan(pow_op(-0.5, NAN))) + self.assertTrue(isnan(pow_op(-0.0, NAN))) + self.assertTrue(isnan(pow_op(0.0, NAN))) + self.assertTrue(isnan(pow_op(0.5, NAN))) + self.assertTrue(isnan(pow_op(2.0, NAN))) + self.assertTrue(isnan(pow_op(INF, NAN))) + self.assertTrue(isnan(pow_op(NAN, NAN))) + + # NAN**y is NAN for any y except +-0 + self.assertTrue(isnan(pow_op(NAN, -INF))) + self.assertTrue(isnan(pow_op(NAN, -2.0))) + self.assertTrue(isnan(pow_op(NAN, -1.0))) + self.assertTrue(isnan(pow_op(NAN, -0.5))) + self.assertTrue(isnan(pow_op(NAN, 0.5))) + self.assertTrue(isnan(pow_op(NAN, 1.0))) + self.assertTrue(isnan(pow_op(NAN, 2.0))) + self.assertTrue(isnan(pow_op(NAN, INF))) + + # (+-0)**y raises ZeroDivisionError for y a negative odd integer + self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0) + self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0) + + # (+-0)**y raises ZeroDivisionError for y finite and negative + # but not an odd integer + self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0) + self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5) + self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0) + self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5) + + # (+-0)**y is +-0 for y a positive odd integer + self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0) + self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0) + + # (+-0)**y is 0 for y finite and positive but not an odd integer + self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0) + self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0) + self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0) + self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0) + + # (-1)**+-inf is 1 + self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0) + + # 1**y is 1 for any y, even if y is an infinity or nan + self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 1.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 2.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, INF), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0) + + # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan + self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0) + + # x**y raises ValueError for finite negative x and non-integral y + self.assertRaises(ValueError, pow_op, -2.0, -0.5) + self.assertRaises(ValueError, pow_op, -2.0, 0.5) + self.assertRaises(ValueError, pow_op, -1.0, -0.5) + self.assertRaises(ValueError, pow_op, -1.0, 0.5) + self.assertRaises(ValueError, pow_op, -0.5, -0.5) + self.assertRaises(ValueError, pow_op, -0.5, 0.5) + + # x**-INF is INF for abs(x) < 1 + self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF) + self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF) + self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF) + self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF) + + # x**-INF is 0 for abs(x) > 1 + self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0) + self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0) + self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0) + self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0) + + # x**INF is 0 for abs(x) < 1 + self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0) + self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0) + self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0) + self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0) + + # x**INF is INF for abs(x) > 1 + self.assertEqualAndEqualSign(pow_op(-INF, INF), INF) + self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF) + self.assertEqualAndEqualSign(pow_op(2.0, INF), INF) + self.assertEqualAndEqualSign(pow_op(INF, INF), INF) + + # (-INF)**y is -0.0 for y a negative odd integer + self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0) + + # (-INF)**y is 0.0 for y negative but not an odd integer + self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0) + self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0) + + # (-INF)**y is -INF for y a positive odd integer + self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF) + + # (-INF)**y is INF for y positive but not an odd integer + self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF) + self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF) + + # INF**y is INF for y positive + self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF) + self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF) + self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF) + + # INF**y is 0.0 for y negative + self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0) + self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0) + self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0) + + # basic checks not covered by the special cases above + self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25) + self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5) + self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0) + self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25) + self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5) + self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0) + self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0) + + # 1 ** large and -1 ** large; some libms apparently + # have problems with these + self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0) + + # check sign for results that underflow to 0 + self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0) + self.assertRaises(ValueError, pow_op, -2.0, -2000.5) + self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0) + self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0) + self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0) + self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0) + self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0) + self.assertRaises(ValueError, pow_op, -0.5, 2000.5) + self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0) + self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0) + self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0) + self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0) + + # check we don't raise an exception for subnormal results, + # and validate signs. Tests currently disabled, since + # they fail on systems where a subnormal result from pow + # is flushed to zero (e.g. Debian/ia64.) + #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315) + #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315) + #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315) + #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315) + #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315) + #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315) + #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315) + #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315) + + class FormatFunctionsTestCase(unittest.TestCase): def setUp(self): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Dec 30 13:12:23 2009 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #7534: Fix handling of IEEE specials (infinities, nans, + negative zero) in ** operator. The behaviour now conforms to that + described in C99 Annex F. + - Issue #7579: the msvcrt module now has docstrings for all its functions. - Issue #7413: Passing '\0' as the separator to datetime.datetime.isoformat() Modified: python/trunk/Objects/floatobject.c ============================================================================== --- python/trunk/Objects/floatobject.c (original) +++ python/trunk/Objects/floatobject.c Wed Dec 30 13:12:23 2009 @@ -791,10 +791,15 @@ return r; } +/* determine whether x is an odd integer or not; assumes that + x is not an infinity or nan. */ +#define DOUBLE_IS_ODD_INTEGER(x) (fmod(fabs(x), 2.0) == 1.0) + static PyObject * float_pow(PyObject *v, PyObject *w, PyObject *z) { double iv, iw, ix; + int negate_result = 0; if ((PyObject *)z != Py_None) { PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not " @@ -806,20 +811,56 @@ CONVERT_TO_DOUBLE(w, iw); /* Sort out special cases here instead of relying on pow() */ - if (iw == 0) { /* v**0 is 1, even 0**0 */ + if (iw == 0) { /* v**0 is 1, even 0**0 */ return PyFloat_FromDouble(1.0); } - if (iv == 0.0) { /* 0**w is error if w<0, else 1 */ + if (Py_IS_NAN(iv)) { /* nan**w = nan, unless w == 0 */ + return PyFloat_FromDouble(iv); + } + if (Py_IS_NAN(iw)) { /* v**nan = nan, unless v == 1; 1**nan = 1 */ + return PyFloat_FromDouble(iv == 1.0 ? 1.0 : iw); + } + if (Py_IS_INFINITY(iw)) { + /* v**inf is: 0.0 if abs(v) < 1; 1.0 if abs(v) == 1; inf if + * abs(v) > 1 (including case where v infinite) + * + * v**-inf is: inf if abs(v) < 1; 1.0 if abs(v) == 1; 0.0 if + * abs(v) > 1 (including case where v infinite) + */ + iv = fabs(iv); + if (iv == 1.0) + return PyFloat_FromDouble(1.0); + else if ((iw > 0.0) == (iv > 1.0)) + return PyFloat_FromDouble(fabs(iw)); /* return inf */ + else + return PyFloat_FromDouble(0.0); + } + if (Py_IS_INFINITY(iv)) { + /* (+-inf)**w is: inf for w positive, 0 for w negative; in + * both cases, we need to add the appropriate sign if w is + * an odd integer. + */ + int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw); + if (iw > 0.0) + return PyFloat_FromDouble(iw_is_odd ? iv : fabs(iv)); + else + return PyFloat_FromDouble(iw_is_odd ? + copysign(0.0, iv) : 0.0); + } + if (iv == 0.0) { /* 0**w is: 0 for w positive, 1 for w zero + (already dealt with above), and an error + if w is negative. */ + int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw); if (iw < 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, - "0.0 cannot be raised to a negative power"); + "0.0 cannot be raised to a " + "negative power"); return NULL; } - return PyFloat_FromDouble(0.0); - } - if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */ - return PyFloat_FromDouble(1.0); + /* use correct sign if iw is odd */ + return PyFloat_FromDouble(iw_is_odd ? iv : 0.0); } + if (iv < 0.0) { /* Whether this is an error is a mess, and bumps into libm * bugs so we have to figure it out ourselves. @@ -829,33 +870,41 @@ "cannot be raised to a fractional power"); return NULL; } - /* iw is an exact integer, albeit perhaps a very large one. + /* iw is an exact integer, albeit perhaps a very large + * one. Replace iv by its absolute value and remember + * to negate the pow result if iw is odd. + */ + iv = -iv; + negate_result = DOUBLE_IS_ODD_INTEGER(iw); + } + + if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */ + /* (-1) ** large_integer also ends up here. Here's an + * extract from the comments for the previous + * implementation explaining why this special case is + * necessary: + * * -1 raised to an exact integer should never be exceptional. * Alas, some libms (chiefly glibc as of early 2003) return * NaN and set EDOM on pow(-1, large_int) if the int doesn't * happen to be representable in a *C* integer. That's a - * bug; we let that slide in math.pow() (which currently - * reflects all platform accidents), but not for Python's **. - */ - if (iv == -1.0 && Py_IS_FINITE(iw)) { - /* Return 1 if iw is even, -1 if iw is odd; there's - * no guarantee that any C integral type is big - * enough to hold iw, so we have to check this - * indirectly. - */ - ix = floor(iw * 0.5) * 2.0; - return PyFloat_FromDouble(ix == iw ? 1.0 : -1.0); - } - /* Else iv != -1.0, and overflow or underflow are possible. - * Unless we're to write pow() ourselves, we have to trust - * the platform to do this correctly. + * bug. */ + return PyFloat_FromDouble(negate_result ? -1.0 : 1.0); } + + /* Now iv and iw are finite, iw is nonzero, and iv is + * positive and not equal to 1.0. We finally allow + * the platform pow to step in and do the rest. + */ errno = 0; PyFPE_START_PROTECT("pow", return NULL) ix = pow(iv, iw); PyFPE_END_PROTECT(ix) Py_ADJUST_ERANGE1(ix); + if (negate_result) + ix = -ix; + if (errno != 0) { /* We don't expect any errno value other than ERANGE, but * the range of libm bugs appears unbounded. @@ -867,6 +916,8 @@ return PyFloat_FromDouble(ix); } +#undef DOUBLE_IS_ODD_INTEGER + static PyObject * float_neg(PyFloatObject *v) { From python-checkins at python.org Wed Dec 30 13:22:50 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 30 Dec 2009 12:22:50 -0000 Subject: [Python-checkins] r77140 - python/trunk/Misc/ACKS Message-ID: Author: mark.dickinson Date: Wed Dec 30 13:22:49 2009 New Revision: 77140 Log: Add Marcos Donolo for work on issue 7534 patch. Modified: python/trunk/Misc/ACKS Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Wed Dec 30 13:22:49 2009 @@ -187,6 +187,7 @@ Daniel Dittmar Jaromir Dolecek Ismail Donmez +Marcos Donolo Dima Dorfman Cesar Douady Dean Draayer From python-checkins at python.org Wed Dec 30 13:26:22 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 30 Dec 2009 12:26:22 -0000 Subject: [Python-checkins] r77141 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Wed Dec 30 13:26:22 2009 New Revision: 77141 Log: Blocked revisions 77139-77140 via svnmerge ........ r77139 | mark.dickinson | 2009-12-30 12:12:23 +0000 (Wed, 30 Dec 2009) | 3 lines Issue #7534: Fix handling of nans, infinities, and negative zero in ** operator, on IEEE 754 platforms. Thanks Marcos Donolo for original patch. ........ r77140 | mark.dickinson | 2009-12-30 12:22:49 +0000 (Wed, 30 Dec 2009) | 1 line Add Marcos Donolo for work on issue 7534 patch. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Dec 30 13:35:00 2009 From: python-checkins at python.org (ezio.melotti) Date: Wed, 30 Dec 2009 12:35:00 -0000 Subject: [Python-checkins] r77142 - in python/branches/py3k: Doc/library/zipfile.rst Lib/test/test_zipfile.py Lib/zipfile.py Misc/NEWS Message-ID: Author: ezio.melotti Date: Wed Dec 30 13:34:59 2009 New Revision: 77142 Log: Merged revisions 77136 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77136 | ezio.melotti | 2009-12-30 08:14:51 +0200 (Wed, 30 Dec 2009) | 1 line #5511: Added the ability to use ZipFile as a context manager. Patch by Brian Curtin. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/zipfile.rst python/branches/py3k/Lib/test/test_zipfile.py python/branches/py3k/Lib/zipfile.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/zipfile.rst ============================================================================== --- python/branches/py3k/Doc/library/zipfile.rst (original) +++ python/branches/py3k/Doc/library/zipfile.rst Wed Dec 30 13:34:59 2009 @@ -102,25 +102,32 @@ Open a ZIP file, where *file* can be either a path to a file (a string) or a file-like object. The *mode* parameter should be ``'r'`` to read an existing file, ``'w'`` to truncate and write a new file, or ``'a'`` to append to an - existing file. If *mode* is ``'a'`` and *file* refers to an existing ZIP file, - then additional files are added to it. If *file* does not refer to a ZIP file, - then a new ZIP archive is appended to the file. This is meant for adding a ZIP - archive to another file, such as :file:`python.exe`. Using :: - - cat myzip.zip >> python.exe - - also works, and at least :program:`WinZip` can read such files. If *mode* is - ``a`` and the file does not exist at all, it is created. *compression* is the - ZIP compression method to use when writing the archive, and should be - :const:`ZIP_STORED` or :const:`ZIP_DEFLATED`; unrecognized values will cause - :exc:`RuntimeError` to be raised. If :const:`ZIP_DEFLATED` is specified but the - :mod:`zlib` module is not available, :exc:`RuntimeError` is also raised. The - default is :const:`ZIP_STORED`. If *allowZip64* is ``True`` zipfile will create - ZIP files that use the ZIP64 extensions when the zipfile is larger than 2 GB. If - it is false (the default) :mod:`zipfile` will raise an exception when the ZIP - file would require ZIP64 extensions. ZIP64 extensions are disabled by default - because the default :program:`zip` and :program:`unzip` commands on Unix (the - InfoZIP utilities) don't support these extensions. + existing file. If *mode* is ``'a'`` and *file* refers to an existing ZIP + file, then additional files are added to it. If *file* does not refer to a + ZIP file, then a new ZIP archive is appended to the file. This is meant for + adding a ZIP archive to another file (such as :file:`python.exe`). If + *mode* is ``a`` and the file does not exist at all, it is created. + *compression* is the ZIP compression method to use when writing the archive, + and should be :const:`ZIP_STORED` or :const:`ZIP_DEFLATED`; unrecognized + values will cause :exc:`RuntimeError` to be raised. If :const:`ZIP_DEFLATED` + is specified but the :mod:`zlib` module is not available, :exc:`RuntimeError` + is also raised. The default is :const:`ZIP_STORED`. If *allowZip64* is + ``True`` zipfile will create ZIP files that use the ZIP64 extensions when + the zipfile is larger than 2 GB. If it is false (the default) :mod:`zipfile` + will raise an exception when the ZIP file would require ZIP64 extensions. + ZIP64 extensions are disabled by default because the default :program:`zip` + and :program:`unzip` commands on Unix (the InfoZIP utilities) don't support + these extensions. + + ZipFile is also a context manager and therefore supports the + :keyword:`with` statement. In the example, *myzip* is closed after the + :keyword:`with` statement's suite is finished---even if an exception occurs:: + + with ZipFile('spam.zip', 'w') as myzip: + myzip.write('eggs.txt') + + .. versionadded:: 3.2 + Added the ability to use :class:`ZipFile` as a context manager. .. method:: ZipFile.close() Modified: python/branches/py3k/Lib/test/test_zipfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_zipfile.py (original) +++ python/branches/py3k/Lib/test/test_zipfile.py Wed Dec 30 13:34:59 2009 @@ -42,63 +42,61 @@ def make_test_archive(self, f, compression): # Create the ZIP archive - zipfp = zipfile.ZipFile(f, "w", compression) - zipfp.write(TESTFN, "another.name") - zipfp.write(TESTFN, TESTFN) - zipfp.writestr("strfile", self.data) - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + zipfp.write(TESTFN, "another.name") + zipfp.write(TESTFN, TESTFN) + zipfp.writestr("strfile", self.data) def zip_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - self.assertEqual(zipfp.read(TESTFN), self.data) - self.assertEqual(zipfp.read("another.name"), self.data) - self.assertEqual(zipfp.read("strfile"), self.data) - - # Print the ZIP directory - fp = io.StringIO() - zipfp.printdir(file=fp) - directory = fp.getvalue() - lines = directory.splitlines() - self.assertEquals(len(lines), 4) # Number of files + header - - self.assertTrue('File Name' in lines[0]) - self.assertTrue('Modified' in lines[0]) - self.assertTrue('Size' in lines[0]) - - fn, date, time, size = lines[1].split() - self.assertEquals(fn, 'another.name') - # XXX: timestamp is not tested - self.assertEquals(size, str(len(self.data))) - - # Check the namelist - names = zipfp.namelist() - self.assertEquals(len(names), 3) - self.assertTrue(TESTFN in names) - self.assertTrue("another.name" in names) - self.assertTrue("strfile" in names) - - # Check infolist - infos = zipfp.infolist() - names = [ i.filename for i in infos ] - self.assertEquals(len(names), 3) - self.assertTrue(TESTFN in names) - self.assertTrue("another.name" in names) - self.assertTrue("strfile" in names) - for i in infos: - self.assertEquals(i.file_size, len(self.data)) - - # check getinfo - for nm in (TESTFN, "another.name", "strfile"): - info = zipfp.getinfo(nm) - self.assertEquals(info.filename, nm) - self.assertEquals(info.file_size, len(self.data)) - - # Check that testzip doesn't raise an exception - zipfp.testzip() - zipfp.close() + with zipfile.ZipFile(f, "r", compression) as zipfp: + self.assertEqual(zipfp.read(TESTFN), self.data) + self.assertEqual(zipfp.read("another.name"), self.data) + self.assertEqual(zipfp.read("strfile"), self.data) + + # Print the ZIP directory + fp = io.StringIO() + zipfp.printdir(file=fp) + directory = fp.getvalue() + lines = directory.splitlines() + self.assertEquals(len(lines), 4) # Number of files + header + + self.assertTrue('File Name' in lines[0]) + self.assertTrue('Modified' in lines[0]) + self.assertTrue('Size' in lines[0]) + + fn, date, time, size = lines[1].split() + self.assertEquals(fn, 'another.name') + # XXX: timestamp is not tested + self.assertEquals(size, str(len(self.data))) + + # Check the namelist + names = zipfp.namelist() + self.assertEquals(len(names), 3) + self.assertTrue(TESTFN in names) + self.assertTrue("another.name" in names) + self.assertTrue("strfile" in names) + + # Check infolist + infos = zipfp.infolist() + names = [ i.filename for i in infos ] + self.assertEquals(len(names), 3) + self.assertTrue(TESTFN in names) + self.assertTrue("another.name" in names) + self.assertTrue("strfile" in names) + for i in infos: + self.assertEquals(i.file_size, len(self.data)) + + # check getinfo + for nm in (TESTFN, "another.name", "strfile"): + info = zipfp.getinfo(nm) + self.assertEquals(info.filename, nm) + self.assertEquals(info.file_size, len(self.data)) + + # Check that testzip doesn't raise an exception + zipfp.testzip() def test_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -108,26 +106,25 @@ self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - zipdata1 = [] - zipopen1 = zipfp.open(TESTFN) - while 1: - read_data = zipopen1.read(256) - if not read_data: - break - zipdata1.append(read_data) - - zipdata2 = [] - zipopen2 = zipfp.open("another.name") - while 1: - read_data = zipopen2.read(256) - if not read_data: - break - zipdata2.append(read_data) - - self.assertEqual(b''.join(zipdata1), self.data) - self.assertEqual(b''.join(zipdata2), self.data) - zipfp.close() + with zipfile.ZipFile(f, "r", compression) as zipfp: + zipdata1 = [] + zipopen1 = zipfp.open(TESTFN) + while True: + read_data = zipopen1.read(256) + if not read_data: + break + zipdata1.append(read_data) + + zipdata2 = [] + zipopen2 = zipfp.open("another.name") + while True: + read_data = zipopen2.read(256) + if not read_data: + break + zipdata2.append(read_data) + + self.assertEqual(b''.join(zipdata1), self.data) + self.assertEqual(b''.join(zipdata2), self.data) def test_open_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -135,38 +132,36 @@ def test_open_via_zip_info(self): # Create the ZIP archive - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - zipfp.writestr("name", "foo") - zipfp.writestr("name", "bar") - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r") - infos = zipfp.infolist() - data = b"" - for info in infos: - data += zipfp.open(info).read() - self.assertTrue(data == b"foobar" or data == b"barfoo") - data = b"" - for info in infos: - data += zipfp.read(info) - self.assertTrue(data == b"foobar" or data == b"barfoo") - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.writestr("name", "foo") + zipfp.writestr("name", "bar") + + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + infos = zipfp.infolist() + data = b"" + for info in infos: + data += zipfp.open(info).read() + self.assertTrue(data == b"foobar" or data == b"barfoo") + data = b"" + for info in infos: + data += zipfp.read(info) + self.assertTrue(data == b"foobar" or data == b"barfoo") def zip_random_open_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - zipdata1 = [] - zipopen1 = zipfp.open(TESTFN) - while 1: - read_data = zipopen1.read(randint(1, 1024)) - if not read_data: - break - zipdata1.append(read_data) + with zipfile.ZipFile(f, "r", compression) as zipfp: + zipdata1 = [] + zipopen1 = zipfp.open(TESTFN) + while True: + read_data = zipopen1.read(randint(1, 1024)) + if not read_data: + break + zipdata1.append(read_data) + + self.assertEqual(b''.join(zipdata1), self.data) - self.assertEqual(b''.join(zipdata1), self.data) - zipfp.close() def test_random_open_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -176,34 +171,28 @@ self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - zipopen = zipfp.open(TESTFN) - for line in self.line_gen: - linedata = zipopen.readline() - self.assertEqual(linedata, line + '\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + zipopen = zipfp.open(TESTFN) + for line in self.line_gen: + linedata = zipopen.readline() + self.assertEqual(linedata, line + '\n') def zip_readlines_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - ziplines = zipfp.open(TESTFN).readlines() - for line, zipline in zip(self.line_gen, ziplines): - self.assertEqual(zipline, line + '\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + ziplines = zipfp.open(TESTFN).readlines() + for line, zipline in zip(self.line_gen, ziplines): + self.assertEqual(zipline, line + '\n') def zip_iterlines_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for line, zipline in zip(self.line_gen, zipfp.open(TESTFN)): - self.assertEqual(zipline, line + '\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for line, zipline in zip(self.line_gen, zipfp.open(TESTFN)): + self.assertEqual(zipline, line + '\n') def test_readline_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -252,34 +241,30 @@ def test_low_compression(self): # Checks for cases where compressed data is larger than original # Create the ZIP archive - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) - zipfp.writestr("strfile", '12') - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp: + zipfp.writestr("strfile", '12') # Get an open object for strfile - zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_DEFLATED) - openobj = zipfp.open("strfile") - self.assertEqual(openobj.read(1), b'1') - self.assertEqual(openobj.read(1), b'2') + with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_DEFLATED) as zipfp: + openobj = zipfp.open("strfile") + self.assertEqual(openobj.read(1), b'1') + self.assertEqual(openobj.read(1), b'2') def test_absolute_arcnames(self): - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - zipfp.write(TESTFN, "/absolute") - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) - self.assertEqual(zipfp.namelist(), ["absolute"]) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, "/absolute") + + with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp: + self.assertEqual(zipfp.namelist(), ["absolute"]) def test_append_to_zip_file(self): # Test appending to an existing zipfile - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - zipfp.write(TESTFN, TESTFN) - zipfp.close() - zipfp = zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) - zipfp.writestr("strfile", self.data) - self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"]) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) + + with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp: + zipfp.writestr("strfile", self.data) + self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"]) def test_append_to_non_zip_file(self): # Test appending to an existing file that is not a zipfile @@ -289,94 +274,82 @@ f = open(TESTFN2, 'wb') f.write(d) f.close() - zipfp = zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) - zipfp.write(TESTFN, TESTFN) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) f = open(TESTFN2, 'rb') f.seek(len(d)) - zipfp = zipfile.ZipFile(f, "r") - self.assertEqual(zipfp.namelist(), [TESTFN]) - zipfp.close() - f.close() + with zipfile.ZipFile(f, "r") as zipfp: + self.assertEqual(zipfp.namelist(), [TESTFN]) def test_write_default_name(self): # Check that calling ZipFile.write without arcname specified produces the expected result - zipfp = zipfile.ZipFile(TESTFN2, "w") - zipfp.write(TESTFN) - self.assertEqual(zipfp.read(TESTFN), open(TESTFN, "rb").read()) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w") as zipfp: + zipfp.write(TESTFN) + self.assertEqual(zipfp.read(TESTFN), open(TESTFN, "rb").read()) @skipUnless(zlib, "requires zlib") def test_per_file_compression(self): # Check that files within a Zip archive can have different compression options - zipfp = zipfile.ZipFile(TESTFN2, "w") - zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED) - zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED) - sinfo = zipfp.getinfo('storeme') - dinfo = zipfp.getinfo('deflateme') - self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED) - self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w") as zipfp: + zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED) + zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED) + sinfo = zipfp.getinfo('storeme') + dinfo = zipfp.getinfo('deflateme') + self.assertEqual(sinfo.compress_type, zipfile.ZIP_STORED) + self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED) def test_write_to_readonly(self): # Check that trying to call write() on a readonly ZipFile object # raises a RuntimeError - zipf = zipfile.ZipFile(TESTFN2, mode="w") - zipf.writestr("somefile.txt", "bogus") - zipf.close() - zipf = zipfile.ZipFile(TESTFN2, mode="r") - self.assertRaises(RuntimeError, zipf.write, TESTFN) - zipf.close() + with zipfile.ZipFile(TESTFN2, mode="w") as zipfp: + zipfp.writestr("somefile.txt", "bogus") - def test_extract(self): - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - for fpath, fdata in SMALL_TEST_DATA: - zipfp.writestr(fpath, fdata) - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r") - for fpath, fdata in SMALL_TEST_DATA: - writtenfile = zipfp.extract(fpath) - - # make sure it was written to the right place - if os.path.isabs(fpath): - correctfile = os.path.join(os.getcwd(), fpath[1:]) - else: - correctfile = os.path.join(os.getcwd(), fpath) - correctfile = os.path.normpath(correctfile) + with zipfile.ZipFile(TESTFN2, mode="r") as zipfp: + self.assertRaises(RuntimeError, zipfp.write, TESTFN) - self.assertEqual(writtenfile, correctfile) + def test_extract(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + writtenfile = zipfp.extract(fpath) + + # make sure it was written to the right place + if os.path.isabs(fpath): + correctfile = os.path.join(os.getcwd(), fpath[1:]) + else: + correctfile = os.path.join(os.getcwd(), fpath) + correctfile = os.path.normpath(correctfile) - # make sure correct data is in correct file - self.assertEqual(fdata.encode(), open(writtenfile, "rb").read()) + self.assertEqual(writtenfile, correctfile) - os.remove(writtenfile) + # make sure correct data is in correct file + self.assertEqual(fdata.encode(), open(writtenfile, "rb").read()) - zipfp.close() + os.remove(writtenfile) # remove the test file subdirectories shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) def test_extract_all(self): - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) - for fpath, fdata in SMALL_TEST_DATA: - zipfp.writestr(fpath, fdata) - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r") - zipfp.extractall() - for fpath, fdata in SMALL_TEST_DATA: - if os.path.isabs(fpath): - outfile = os.path.join(os.getcwd(), fpath[1:]) - else: - outfile = os.path.join(os.getcwd(), fpath) - - self.assertEqual(fdata.encode(), open(outfile, "rb").read()) + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + zipfp.extractall() + for fpath, fdata in SMALL_TEST_DATA: + if os.path.isabs(fpath): + outfile = os.path.join(os.getcwd(), fpath[1:]) + else: + outfile = os.path.join(os.getcwd(), fpath) - os.remove(outfile) + self.assertEqual(fdata.encode(), open(outfile, "rb").read()) - zipfp.close() + os.remove(outfile) # remove the test file subdirectories shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) @@ -386,21 +359,45 @@ # when it is passed a name rather than a ZipInfo instance. self.make_test_archive(f, compression) - zipfp = zipfile.ZipFile(f, "r") - zinfo = zipfp.getinfo('strfile') - self.assertEqual(zinfo.external_attr, 0o600 << 16) + with zipfile.ZipFile(f, "r") as zipfp: + zinfo = zipfp.getinfo('strfile') + self.assertEqual(zinfo.external_attr, 0o600 << 16) def test_writestr_permissions(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): self.zip_test_writestr_permissions(f, zipfile.ZIP_STORED) def test_writestr_extended_local_header_issue1202(self): - orig_zip = zipfile.ZipFile(TESTFN2, 'w') - for data in 'abcdefghijklmnop': - zinfo = zipfile.ZipInfo(data) - zinfo.flag_bits |= 0x08 # Include an extended local header. - orig_zip.writestr(zinfo, data) - orig_zip.close() + with zipfile.ZipFile(TESTFN2, 'w') as orig_zip: + for data in 'abcdefghijklmnop': + zinfo = zipfile.ZipInfo(data) + zinfo.flag_bits |= 0x08 # Include an extended local header. + orig_zip.writestr(zinfo, data) + + def test_close(self): + """Check that the zipfile is closed after the 'with' block.""" + with zipfile.ZipFile(TESTFN2, "w") as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + self.assertTrue(zipfp.fp is not None, 'zipfp is not open') + self.assertTrue(zipfp.fp is None, 'zipfp is not closed') + + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertTrue(zipfp.fp is not None, 'zipfp is not open') + self.assertTrue(zipfp.fp is None, 'zipfp is not closed') + + def test_close_on_exception(self): + """Check that the zipfile is closed if an exception is raised in the + 'with' block.""" + with zipfile.ZipFile(TESTFN2, "w") as zipfp: + for fpath, fdata in SMALL_TEST_DATA: + zipfp.writestr(fpath, fdata) + + try: + with zipfile.ZipFile(TESTFN2, "r") as zipfp2: + raise zipfile.BadZipfile() + except zipfile.BadZipfile: + self.assertTrue(zipfp2.fp is None, 'zipfp is not closed') def tearDown(self): unlink(TESTFN) @@ -425,16 +422,14 @@ fp.close() def large_file_exception_test(self, f, compression): - zipfp = zipfile.ZipFile(f, "w", compression) - self.assertRaises(zipfile.LargeZipFile, - zipfp.write, TESTFN, "another.name") - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + self.assertRaises(zipfile.LargeZipFile, + zipfp.write, TESTFN, "another.name") def large_file_exception_test2(self, f, compression): - zipfp = zipfile.ZipFile(f, "w", compression) - self.assertRaises(zipfile.LargeZipFile, - zipfp.writestr, "another.name", self.data) - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + self.assertRaises(zipfile.LargeZipFile, + zipfp.writestr, "another.name", self.data) def test_large_file_exception(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -443,62 +438,59 @@ def zip_test(self, f, compression): # Create the ZIP archive - zipfp = zipfile.ZipFile(f, "w", compression, allowZip64=True) - zipfp.write(TESTFN, "another.name") - zipfp.write(TESTFN, TESTFN) - zipfp.writestr("strfile", self.data) - zipfp.close() + with zipfile.ZipFile(f, "w", compression, allowZip64=True) as zipfp: + zipfp.write(TESTFN, "another.name") + zipfp.write(TESTFN, TESTFN) + zipfp.writestr("strfile", self.data) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - self.assertEqual(zipfp.read(TESTFN), self.data) - self.assertEqual(zipfp.read("another.name"), self.data) - self.assertEqual(zipfp.read("strfile"), self.data) - - # Print the ZIP directory - fp = io.StringIO() - zipfp.printdir(fp) - - directory = fp.getvalue() - lines = directory.splitlines() - self.assertEquals(len(lines), 4) # Number of files + header - - self.assertTrue('File Name' in lines[0]) - self.assertTrue('Modified' in lines[0]) - self.assertTrue('Size' in lines[0]) - - fn, date, time, size = lines[1].split() - self.assertEquals(fn, 'another.name') - # XXX: timestamp is not tested - self.assertEquals(size, str(len(self.data))) - - # Check the namelist - names = zipfp.namelist() - self.assertEquals(len(names), 3) - self.assertTrue(TESTFN in names) - self.assertTrue("another.name" in names) - self.assertTrue("strfile" in names) - - # Check infolist - infos = zipfp.infolist() - names = [ i.filename for i in infos ] - self.assertEquals(len(names), 3) - self.assertTrue(TESTFN in names) - self.assertTrue("another.name" in names) - self.assertTrue("strfile" in names) - for i in infos: - self.assertEquals(i.file_size, len(self.data)) - - # check getinfo - for nm in (TESTFN, "another.name", "strfile"): - info = zipfp.getinfo(nm) - self.assertEquals(info.filename, nm) - self.assertEquals(info.file_size, len(self.data)) + with zipfile.ZipFile(f, "r", compression) as zipfp: + self.assertEqual(zipfp.read(TESTFN), self.data) + self.assertEqual(zipfp.read("another.name"), self.data) + self.assertEqual(zipfp.read("strfile"), self.data) + + # Print the ZIP directory + fp = io.StringIO() + zipfp.printdir(fp) + + directory = fp.getvalue() + lines = directory.splitlines() + self.assertEquals(len(lines), 4) # Number of files + header + + self.assertTrue('File Name' in lines[0]) + self.assertTrue('Modified' in lines[0]) + self.assertTrue('Size' in lines[0]) + + fn, date, time, size = lines[1].split() + self.assertEquals(fn, 'another.name') + # XXX: timestamp is not tested + self.assertEquals(size, str(len(self.data))) - # Check that testzip doesn't raise an exception - zipfp.testzip() + # Check the namelist + names = zipfp.namelist() + self.assertEquals(len(names), 3) + self.assertTrue(TESTFN in names) + self.assertTrue("another.name" in names) + self.assertTrue("strfile" in names) + + # Check infolist + infos = zipfp.infolist() + names = [ i.filename for i in infos ] + self.assertEquals(len(names), 3) + self.assertTrue(TESTFN in names) + self.assertTrue("another.name" in names) + self.assertTrue("strfile" in names) + for i in infos: + self.assertEquals(i.file_size, len(self.data)) + + # check getinfo + for nm in (TESTFN, "another.name", "strfile"): + info = zipfp.getinfo(nm) + self.assertEquals(info.filename, nm) + self.assertEquals(info.file_size, len(self.data)) - zipfp.close() + # Check that testzip doesn't raise an exception + zipfp.testzip() def test_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -510,13 +502,12 @@ self.zip_test(f, zipfile.ZIP_DEFLATED) def test_absolute_arcnames(self): - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED, allowZip64=True) - zipfp.write(TESTFN, "/absolute") - zipfp.close() - - zipfp = zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) - self.assertEqual(zipfp.namelist(), ["absolute"]) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED, + allowZip64=True) as zipfp: + zipfp.write(TESTFN, "/absolute") + + with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp: + self.assertEqual(zipfp.namelist(), ["absolute"]) def tearDown(self): zipfile.ZIP64_LIMIT = self._limit @@ -526,41 +517,43 @@ class PyZipFileTests(unittest.TestCase): def test_write_pyfile(self): - zipfp = zipfile.PyZipFile(TemporaryFile(), "w") - fn = __file__ - if fn.endswith('.pyc') or fn.endswith('.pyo'): - fn = fn[:-1] - - zipfp.writepy(fn) - - bn = os.path.basename(fn) - self.assertTrue(bn not in zipfp.namelist()) - self.assertTrue(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist()) - zipfp.close() - - zipfp = zipfile.PyZipFile(TemporaryFile(), "w") - fn = __file__ - if fn.endswith('.pyc') or fn.endswith('.pyo'): - fn = fn[:-1] - - zipfp.writepy(fn, "testpackage") - - bn = "%s/%s"%("testpackage", os.path.basename(fn)) - self.assertTrue(bn not in zipfp.namelist()) - self.assertTrue(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist()) - zipfp.close() + with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: + fn = __file__ + if fn.endswith('.pyc') or fn.endswith('.pyo'): + fn = fn[:-1] + + zipfp.writepy(fn) + + bn = os.path.basename(fn) + self.assertTrue(bn not in zipfp.namelist()) + self.assertTrue(bn + 'o' in zipfp.namelist() or + bn + 'c' in zipfp.namelist()) + + with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: + fn = __file__ + if fn.endswith('.pyc') or fn.endswith('.pyo'): + fn = fn[:-1] + + zipfp.writepy(fn, "testpackage") + + bn = "%s/%s"%("testpackage", os.path.basename(fn)) + self.assertTrue(bn not in zipfp.namelist()) + self.assertTrue(bn + 'o' in zipfp.namelist() or + bn + 'c' in zipfp.namelist()) def test_write_python_package(self): import email packagedir = os.path.dirname(email.__file__) - zipfp = zipfile.PyZipFile(TemporaryFile(), "w") - zipfp.writepy(packagedir) + with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: + zipfp.writepy(packagedir) - # Check for a couple of modules at different levels of the hieararchy - names = zipfp.namelist() - self.assertTrue('email/__init__.pyo' in names or 'email/__init__.pyc' in names) - self.assertTrue('email/mime/text.pyo' in names or 'email/mime/text.pyc' in names) + # Check for a couple of modules at different levels of the hieararchy + names = zipfp.namelist() + self.assertTrue('email/__init__.pyo' in names or + 'email/__init__.pyc' in names) + self.assertTrue('email/mime/text.pyo' in names or + 'email/mime/text.pyc' in names) def test_write_python_directory(self): os.mkdir(TESTFN2) @@ -589,22 +582,22 @@ shutil.rmtree(TESTFN2) def test_write_non_pyfile(self): - zipfp = zipfile.PyZipFile(TemporaryFile(), "w") - open(TESTFN, 'w').write('most definitely not a python file') - self.assertRaises(RuntimeError, zipfp.writepy, TESTFN) - os.remove(TESTFN) + with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: + open(TESTFN, 'w').write('most definitely not a python file') + self.assertRaises(RuntimeError, zipfp.writepy, TESTFN) + os.remove(TESTFN) + class OtherTests(unittest.TestCase): def test_unicode_filenames(self): - zf = zipfile.ZipFile(TESTFN, "w") - zf.writestr("foo.txt", "Test for unicode filename") - zf.writestr("\xf6.txt", "Test for unicode filename") - zf.close() - zf = zipfile.ZipFile(TESTFN, "r") - self.assertEqual(zf.filelist[0].filename, "foo.txt") - self.assertEqual(zf.filelist[1].filename, "\xf6.txt") - zf.close() + with zipfile.ZipFile(TESTFN, "w") as zf: + zf.writestr("foo.txt", "Test for unicode filename") + zf.writestr("\xf6.txt", "Test for unicode filename") + + with zipfile.ZipFile(TESTFN, "r") as zf: + self.assertEqual(zf.filelist[0].filename, "foo.txt") + self.assertEqual(zf.filelist[1].filename, "\xf6.txt") def test_create_non_existent_file_for_append(self): if os.path.exists(TESTFN): @@ -614,17 +607,15 @@ content = b'hello, world. this is some content.' try: - zf = zipfile.ZipFile(TESTFN, 'a') - zf.writestr(filename, content) - zf.close() + with zipfile.ZipFile(TESTFN, 'a') as zf: + zf.writestr(filename, content) except IOError: self.fail('Could not append data to a non-existent zip file.') self.assertTrue(os.path.exists(TESTFN)) - zf = zipfile.ZipFile(TESTFN, 'r') - self.assertEqual(zf.read(filename), content) - zf.close() + with zipfile.ZipFile(TESTFN, 'r') as zf: + self.assertEqual(zf.read(filename), content) def test_close_erroneous_file(self): # This test checks that the ZipFile constructor closes the file object @@ -668,9 +659,9 @@ # a file that is a zip file # - passing a filename - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.writestr("foo.txt", b"O, for a Muse of Fire!") - zipf.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.writestr("foo.txt", b"O, for a Muse of Fire!") + chk = zipfile.is_zipfile(TESTFN) self.assertTrue(chk) # - passing a file object @@ -715,9 +706,8 @@ def test_closed_zip_raises_RuntimeError(self): # Verify that testzip() doesn't swallow inappropriate exceptions. data = io.BytesIO() - zipf = zipfile.ZipFile(data, mode="w") - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() + with zipfile.ZipFile(data, mode="w") as zipf: + zipf.writestr("foo.txt", "O, for a Muse of Fire!") # This is correct; calling .read on a closed ZipFile should throw # a RuntimeError, and so should calling .testzip. An earlier @@ -736,33 +726,31 @@ def test_bad_open_mode(self): # Check that bad modes passed to ZipFile.open are caught - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipf = zipfile.ZipFile(TESTFN, mode="r") + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + + with zipfile.ZipFile(TESTFN, mode="r") as zipf: # read the data to make sure the file is there - zipf.read("foo.txt") - self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q") - zipf.close() + zipf.read("foo.txt") + self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q") def test_read0(self): # Check that calling read(0) on a ZipExtFile object returns an empty # string and doesn't advance file pointer - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - # read the data to make sure the file is there - f = zipf.open("foo.txt") - for i in range(FIXEDTEST_SIZE): - self.assertEqual(f.read(0), b'') + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + # read the data to make sure the file is there + f = zipf.open("foo.txt") + for i in range(FIXEDTEST_SIZE): + self.assertEqual(f.read(0), b'') - self.assertEqual(f.read(), b"O, for a Muse of Fire!") - zipf.close() + self.assertEqual(f.read(), b"O, for a Muse of Fire!") def test_open_non_existent_item(self): # Check that attempting to call open() for an item that doesn't # exist in the archive raises a RuntimeError - zipf = zipfile.ZipFile(TESTFN, mode="w") - self.assertRaises(KeyError, zipf.open, "foo.txt", "r") + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + self.assertRaises(KeyError, zipf.open, "foo.txt", "r") def test_bad_compression_mode(self): # Check that bad compression methods passed to ZipFile.open are caught @@ -770,9 +758,9 @@ def test_null_byte_in_filename(self): # Check that a filename containing a null byte is properly terminated - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.writestr("foo.txt\x00qqq", b"O, for a Muse of Fire!") - self.assertEqual(zipf.namelist(), ['foo.txt']) + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.writestr("foo.txt\x00qqq", b"O, for a Muse of Fire!") + self.assertEqual(zipf.namelist(), ['foo.txt']) def test_struct_sizes(self): # check that ZIP internal structure sizes are calculated correctly @@ -785,43 +773,37 @@ # This test checks that comments on the archive are handled properly # check default comment is empty - zipf = zipfile.ZipFile(TESTFN, mode="w") - self.assertEqual(zipf.comment, b'') - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipfr = zipfile.ZipFile(TESTFN, mode="r") - self.assertEqual(zipfr.comment, b'') - zipfr.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + self.assertEqual(zipf.comment, b'') + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + + with zipfile.ZipFile(TESTFN, mode="r") as zipfr: + self.assertEqual(zipfr.comment, b'') # check a simple short comment comment = b'Bravely taking to his feet, he beat a very brave retreat.' - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.comment = comment - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipfr = zipfile.ZipFile(TESTFN, mode="r") - self.assertEqual(zipfr.comment, comment) - zipfr.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.comment = comment + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + with zipfile.ZipFile(TESTFN, mode="r") as zipfr: + self.assertEqual(zipf.comment, comment) # check a comment of max length comment2 = ''.join(['%d' % (i**3 % 10) for i in range((1 << 16)-1)]) comment2 = comment2.encode("ascii") - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.comment = comment2 - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipfr = zipfile.ZipFile(TESTFN, mode="r") - self.assertEqual(zipfr.comment, comment2) - zipfr.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.comment = comment2 + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + + with zipfile.ZipFile(TESTFN, mode="r") as zipfr: + self.assertEqual(zipfr.comment, comment2) # check a comment that is too long is truncated - zipf = zipfile.ZipFile(TESTFN, mode="w") - zipf.comment = comment2 + b'oops' - zipf.writestr("foo.txt", "O, for a Muse of Fire!") - zipf.close() - zipfr = zipfile.ZipFile(TESTFN, mode="r") - self.assertEqual(zipfr.comment, comment2) - zipfr.close() + with zipfile.ZipFile(TESTFN, mode="w") as zipf: + zipf.comment = comment2 + b'oops' + zipf.writestr("foo.txt", "O, for a Muse of Fire!") + with zipfile.ZipFile(TESTFN, mode="r") as zipfr: + self.assertEqual(zipfr.comment, comment2) def tearDown(self): unlink(TESTFN) @@ -907,21 +889,19 @@ def make_test_archive(self, f, compression): # Create the ZIP archive - zipfp = zipfile.ZipFile(f, "w", compression) - zipfp.write(TESTFN, "another.name") - zipfp.write(TESTFN, TESTFN) - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + zipfp.write(TESTFN, "another.name") + zipfp.write(TESTFN, TESTFN) def zip_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - testdata = zipfp.read(TESTFN) - self.assertEqual(len(testdata), len(self.data)) - self.assertEqual(testdata, self.data) - self.assertEqual(zipfp.read("another.name"), self.data) - zipfp.close() + with zipfile.ZipFile(f, "r", compression) as zipfp: + testdata = zipfp.read(TESTFN) + self.assertEqual(len(testdata), len(self.data)) + self.assertEqual(testdata, self.data) + self.assertEqual(zipfp.read("another.name"), self.data) def test_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -931,31 +911,30 @@ self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - zipdata1 = [] - zipopen1 = zipfp.open(TESTFN) - while 1: - read_data = zipopen1.read(256) - if not read_data: - break - zipdata1.append(read_data) - - zipdata2 = [] - zipopen2 = zipfp.open("another.name") - while 1: - read_data = zipopen2.read(256) - if not read_data: - break - zipdata2.append(read_data) - - testdata1 = b''.join(zipdata1) - self.assertEqual(len(testdata1), len(self.data)) - self.assertEqual(testdata1, self.data) - - testdata2 = b''.join(zipdata2) - self.assertEqual(len(testdata1), len(self.data)) - self.assertEqual(testdata1, self.data) - zipfp.close() + with zipfile.ZipFile(f, "r", compression) as zipfp: + zipdata1 = [] + zipopen1 = zipfp.open(TESTFN) + while True: + read_data = zipopen1.read(256) + if not read_data: + break + zipdata1.append(read_data) + + zipdata2 = [] + zipopen2 = zipfp.open("another.name") + while True: + read_data = zipopen2.read(256) + if not read_data: + break + zipdata2.append(read_data) + + testdata1 = b''.join(zipdata1) + self.assertEqual(len(testdata1), len(self.data)) + self.assertEqual(testdata1, self.data) + + testdata2 = b''.join(zipdata2) + self.assertEqual(len(testdata1), len(self.data)) + self.assertEqual(testdata1, self.data) def test_open_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -965,19 +944,18 @@ self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r", compression) - zipdata1 = [] - zipopen1 = zipfp.open(TESTFN) - while 1: - read_data = zipopen1.read(randint(1, 1024)) - if not read_data: - break - zipdata1.append(read_data) - - testdata = b''.join(zipdata1) - self.assertEqual(len(testdata), len(self.data)) - self.assertEqual(testdata, self.data) - zipfp.close() + with zipfile.ZipFile(f, "r", compression) as zipfp: + zipdata1 = [] + zipopen1 = zipfp.open(TESTFN) + while True: + read_data = zipopen1.read(randint(1, 1024)) + if not read_data: + break + zipdata1.append(read_data) + + testdata = b''.join(zipdata1) + self.assertEqual(len(testdata), len(self.data)) + self.assertEqual(testdata, self.data) def test_random_open_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -988,51 +966,47 @@ class TestsWithMultipleOpens(unittest.TestCase): def setUp(self): # Create the ZIP archive - zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) - zipfp.writestr('ones', '1'*FIXEDTEST_SIZE) - zipfp.writestr('twos', '2'*FIXEDTEST_SIZE) - zipfp.close() + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp: + zipfp.writestr('ones', '1'*FIXEDTEST_SIZE) + zipfp.writestr('twos', '2'*FIXEDTEST_SIZE) def test_same_file(self): # Verify that (when the ZipFile is in control of creating file objects) # multiple open() calls can be made without interfering with each other. - zipf = zipfile.ZipFile(TESTFN2, mode="r") - zopen1 = zipf.open('ones') - zopen2 = zipf.open('ones') - data1 = zopen1.read(500) - data2 = zopen2.read(500) - data1 += zopen1.read(500) - data2 += zopen2.read(500) - self.assertEqual(data1, data2) - zipf.close() + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + zopen1 = zipf.open('ones') + zopen2 = zipf.open('ones') + data1 = zopen1.read(500) + data2 = zopen2.read(500) + data1 += zopen1.read(500) + data2 += zopen2.read(500) + self.assertEqual(data1, data2) def test_different_file(self): # Verify that (when the ZipFile is in control of creating file objects) # multiple open() calls can be made without interfering with each other. - zipf = zipfile.ZipFile(TESTFN2, mode="r") - zopen1 = zipf.open('ones') - zopen2 = zipf.open('twos') - data1 = zopen1.read(500) - data2 = zopen2.read(500) - data1 += zopen1.read(500) - data2 += zopen2.read(500) - self.assertEqual(data1, b'1'*FIXEDTEST_SIZE) - self.assertEqual(data2, b'2'*FIXEDTEST_SIZE) - zipf.close() + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + zopen1 = zipf.open('ones') + zopen2 = zipf.open('twos') + data1 = zopen1.read(500) + data2 = zopen2.read(500) + data1 += zopen1.read(500) + data2 += zopen2.read(500) + self.assertEqual(data1, b'1'*FIXEDTEST_SIZE) + self.assertEqual(data2, b'2'*FIXEDTEST_SIZE) def test_interleaved(self): # Verify that (when the ZipFile is in control of creating file objects) # multiple open() calls can be made without interfering with each other. - zipf = zipfile.ZipFile(TESTFN2, mode="r") - zopen1 = zipf.open('ones') - data1 = zopen1.read(500) - zopen2 = zipf.open('twos') - data2 = zopen2.read(500) - data1 += zopen1.read(500) - data2 += zopen2.read(500) - self.assertEqual(data1, b'1'*FIXEDTEST_SIZE) - self.assertEqual(data2, b'2'*FIXEDTEST_SIZE) - zipf.close() + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + zopen1 = zipf.open('ones') + data1 = zopen1.read(500) + zopen2 = zipf.open('twos') + data2 = zopen2.read(500) + data1 += zopen1.read(500) + data2 += zopen2.read(500) + self.assertEqual(data1, b'1'*FIXEDTEST_SIZE) + self.assertEqual(data2, b'2'*FIXEDTEST_SIZE) def tearDown(self): unlink(TESTFN2) @@ -1043,8 +1017,8 @@ os.mkdir(TESTFN2) def test_extract_dir(self): - zipf = zipfile.ZipFile(findfile("zipdir.zip")) - zipf.extractall(TESTFN2) + with zipfile.ZipFile(findfile("zipdir.zip")) as zipf: + zipf.extractall(TESTFN2) self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a"))) self.assertTrue(os.path.isdir(os.path.join(TESTFN2, "a", "b"))) self.assertTrue(os.path.exists(os.path.join(TESTFN2, "a", "b", "c"))) @@ -1084,57 +1058,48 @@ def make_test_archive(self, f, compression): # Create the ZIP archive - zipfp = zipfile.ZipFile(f, "w", compression) - for fn in self.arcfiles.values(): - zipfp.write(fn, fn) - zipfp.close() + with zipfile.ZipFile(f, "w", compression) as zipfp: + for fn in self.arcfiles.values(): + zipfp.write(fn, fn) def read_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for sep, fn in self.arcfiles.items(): - zipdata = zipfp.open(fn, "rU").read() - self.assertEqual(self.arcdata[sep], zipdata) - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for sep, fn in self.arcfiles.items(): + zipdata = zipfp.open(fn, "rU").read() + self.assertEqual(self.arcdata[sep], zipdata) def readline_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for sep, fn in self.arcfiles.items(): - zipopen = zipfp.open(fn, "rU") - for line in self.line_gen: - linedata = zipopen.readline() - self.assertEqual(linedata, line + b'\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for sep, fn in self.arcfiles.items(): + zipopen = zipfp.open(fn, "rU") + for line in self.line_gen: + linedata = zipopen.readline() + self.assertEqual(linedata, line + b'\n') def readlines_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for sep, fn in self.arcfiles.items(): - ziplines = zipfp.open(fn, "rU").readlines() - for line, zipline in zip(self.line_gen, ziplines): - self.assertEqual(zipline, line + b'\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for sep, fn in self.arcfiles.items(): + ziplines = zipfp.open(fn, "rU").readlines() + for line, zipline in zip(self.line_gen, ziplines): + self.assertEqual(zipline, line + b'\n') def iterlines_test(self, f, compression): self.make_test_archive(f, compression) # Read the ZIP archive - zipfp = zipfile.ZipFile(f, "r") - for sep, fn in self.arcfiles.items(): - for line, zipline in zip(self.line_gen, zipfp.open(fn, "rU")): - self.assertEqual(zipline, line + b'\n') - - zipfp.close() + with zipfile.ZipFile(f, "r") as zipfp: + for sep, fn in self.arcfiles.items(): + for line, zipline in zip(self.line_gen, zipfp.open(fn, "rU")): + self.assertEqual(zipline, line + b'\n') def test_read_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): Modified: python/branches/py3k/Lib/zipfile.py ============================================================================== --- python/branches/py3k/Lib/zipfile.py (original) +++ python/branches/py3k/Lib/zipfile.py Wed Dec 30 13:34:59 2009 @@ -719,6 +719,12 @@ self.fp = None raise RuntimeError('Mode must be "r", "w" or "a"') + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + def _GetContents(self): """Read the directory, making sure we close the file if the format is bad.""" Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 30 13:34:59 2009 @@ -171,6 +171,9 @@ Library ------- +- Issue #5511: now zipfile.ZipFile can be used as a context manager. + Initial patch by Brian Curtin. + - Issue #7556: Make sure Distutils' msvc9compile reads and writes the MSVC XML Manifest file in text mode so string patterns can be used in regular expressions. From python-checkins at python.org Wed Dec 30 17:21:26 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 16:21:26 -0000 Subject: [Python-checkins] r77145 - python/trunk/Doc/Makefile Message-ID: Author: georg.brandl Date: Wed Dec 30 17:21:26 2009 New Revision: 77145 Log: Use new Pygments version. Modified: python/trunk/Doc/Makefile Modified: python/trunk/Doc/Makefile ============================================================================== --- python/trunk/Doc/Makefile (original) +++ python/trunk/Doc/Makefile Wed Dec 30 17:21:26 2009 @@ -44,7 +44,7 @@ fi @if [ ! -d tools/pygments ]; then \ echo "Checking out Pygments..."; \ - svn checkout $(SVNROOT)/external/Pygments-0.11.1/pygments tools/pygments; \ + svn checkout $(SVNROOT)/external/Pygments-1.1.1/pygments tools/pygments; \ fi update: checkout From python-checkins at python.org Wed Dec 30 17:22:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 30 Dec 2009 16:22:49 -0000 Subject: [Python-checkins] r77146 - in python/branches/py3k: Lib/test/ieee754.txt Lib/test/test_float.py Misc/ACKS Misc/NEWS Objects/floatobject.c Message-ID: Author: mark.dickinson Date: Wed Dec 30 17:22:49 2009 New Revision: 77146 Log: Merged revisions 77139-77140 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77139 | mark.dickinson | 2009-12-30 12:12:23 +0000 (Wed, 30 Dec 2009) | 3 lines Issue #7534: Fix handling of nans, infinities, and negative zero in ** operator, on IEEE 754 platforms. Thanks Marcos Donolo for original patch. ........ r77140 | mark.dickinson | 2009-12-30 12:22:49 +0000 (Wed, 30 Dec 2009) | 1 line Add Marcos Donolo for work on issue 7534 patch. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/ieee754.txt python/branches/py3k/Lib/test/test_float.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/floatobject.c Modified: python/branches/py3k/Lib/test/ieee754.txt ============================================================================== --- python/branches/py3k/Lib/test/ieee754.txt (original) +++ python/branches/py3k/Lib/test/ieee754.txt Wed Dec 30 17:22:49 2009 @@ -72,7 +72,7 @@ >>> NAN >= 0 False -All operations involving a NaN return a NaN except for the power of *0* and *1*. +All operations involving a NaN return a NaN except for nan**0 and 1**nan. >>> 1 + NAN nan >>> 1 * NAN @@ -81,8 +81,10 @@ nan >>> 1 ** NAN 1.0 +>>> NAN ** 0 +1.0 >>> 0 ** NAN -0.0 +nan >>> (1.0 + FI.epsilon) * NAN nan 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 Dec 30 17:22:49 2009 @@ -11,6 +11,11 @@ INF = float("inf") NAN = float("nan") +# decorator for skipping tests on non-IEEE 754 platforms +requires_IEEE_754 = unittest.skipUnless( + float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + #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') @@ -161,6 +166,212 @@ self.assertTrue(s == s, "{%r} not equal to itself" % f) self.assertTrue(d == d, "{%r : None} not equal to itself" % f) + def assertEqualAndEqualSign(self, a, b): + # fail unless a == b and a and b have the same sign bit; + # the only difference from assertEqual is that this test + # distingishes -0.0 and 0.0. + self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b))) + + @requires_IEEE_754 + def test_float_pow(self): + # test builtin pow and ** operator for IEEE 754 special cases. + # Special cases taken from section F.9.4.4 of the C99 specification + + for pow_op in pow, operator.pow: + # x**NAN is NAN for any x except 1 + self.assertTrue(isnan(pow_op(-INF, NAN))) + self.assertTrue(isnan(pow_op(-2.0, NAN))) + self.assertTrue(isnan(pow_op(-1.0, NAN))) + self.assertTrue(isnan(pow_op(-0.5, NAN))) + self.assertTrue(isnan(pow_op(-0.0, NAN))) + self.assertTrue(isnan(pow_op(0.0, NAN))) + self.assertTrue(isnan(pow_op(0.5, NAN))) + self.assertTrue(isnan(pow_op(2.0, NAN))) + self.assertTrue(isnan(pow_op(INF, NAN))) + self.assertTrue(isnan(pow_op(NAN, NAN))) + + # NAN**y is NAN for any y except +-0 + self.assertTrue(isnan(pow_op(NAN, -INF))) + self.assertTrue(isnan(pow_op(NAN, -2.0))) + self.assertTrue(isnan(pow_op(NAN, -1.0))) + self.assertTrue(isnan(pow_op(NAN, -0.5))) + self.assertTrue(isnan(pow_op(NAN, 0.5))) + self.assertTrue(isnan(pow_op(NAN, 1.0))) + self.assertTrue(isnan(pow_op(NAN, 2.0))) + self.assertTrue(isnan(pow_op(NAN, INF))) + + # (+-0)**y raises ZeroDivisionError for y a negative odd integer + self.assertRaises(ZeroDivisionError, pow_op, -0.0, -1.0) + self.assertRaises(ZeroDivisionError, pow_op, 0.0, -1.0) + + # (+-0)**y raises ZeroDivisionError for y finite and negative + # but not an odd integer + self.assertRaises(ZeroDivisionError, pow_op, -0.0, -2.0) + self.assertRaises(ZeroDivisionError, pow_op, -0.0, -0.5) + self.assertRaises(ZeroDivisionError, pow_op, 0.0, -2.0) + self.assertRaises(ZeroDivisionError, pow_op, 0.0, -0.5) + + # (+-0)**y is +-0 for y a positive odd integer + self.assertEqualAndEqualSign(pow_op(-0.0, 1.0), -0.0) + self.assertEqualAndEqualSign(pow_op(0.0, 1.0), 0.0) + + # (+-0)**y is 0 for y finite and positive but not an odd integer + self.assertEqualAndEqualSign(pow_op(-0.0, 0.5), 0.0) + self.assertEqualAndEqualSign(pow_op(-0.0, 2.0), 0.0) + self.assertEqualAndEqualSign(pow_op(0.0, 0.5), 0.0) + self.assertEqualAndEqualSign(pow_op(0.0, 2.0), 0.0) + + # (-1)**+-inf is 1 + self.assertEqualAndEqualSign(pow_op(-1.0, -INF), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, INF), 1.0) + + # 1**y is 1 for any y, even if y is an infinity or nan + self.assertEqualAndEqualSign(pow_op(1.0, -INF), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -2.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -1.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -0.5), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 0.5), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 1.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 2.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, INF), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, NAN), 1.0) + + # x**+-0 is 1 for any x, even if x is a zero, infinity, or nan + self.assertEqualAndEqualSign(pow_op(-INF, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-0.5, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-0.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(0.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(0.5, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(INF, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(NAN, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-INF, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-0.5, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-0.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(0.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(0.5, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(INF, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(NAN, -0.0), 1.0) + + # x**y defers to complex pow for finite negative x and + # non-integral y. + self.assertEqual(type(pow_op(-2.0, -0.5)), complex) + self.assertEqual(type(pow_op(-2.0, 0.5)), complex) + self.assertEqual(type(pow_op(-1.0, -0.5)), complex) + self.assertEqual(type(pow_op(-1.0, 0.5)), complex) + self.assertEqual(type(pow_op(-0.5, -0.5)), complex) + self.assertEqual(type(pow_op(-0.5, 0.5)), complex) + + # x**-INF is INF for abs(x) < 1 + self.assertEqualAndEqualSign(pow_op(-0.5, -INF), INF) + self.assertEqualAndEqualSign(pow_op(-0.0, -INF), INF) + self.assertEqualAndEqualSign(pow_op(0.0, -INF), INF) + self.assertEqualAndEqualSign(pow_op(0.5, -INF), INF) + + # x**-INF is 0 for abs(x) > 1 + self.assertEqualAndEqualSign(pow_op(-INF, -INF), 0.0) + self.assertEqualAndEqualSign(pow_op(-2.0, -INF), 0.0) + self.assertEqualAndEqualSign(pow_op(2.0, -INF), 0.0) + self.assertEqualAndEqualSign(pow_op(INF, -INF), 0.0) + + # x**INF is 0 for abs(x) < 1 + self.assertEqualAndEqualSign(pow_op(-0.5, INF), 0.0) + self.assertEqualAndEqualSign(pow_op(-0.0, INF), 0.0) + self.assertEqualAndEqualSign(pow_op(0.0, INF), 0.0) + self.assertEqualAndEqualSign(pow_op(0.5, INF), 0.0) + + # x**INF is INF for abs(x) > 1 + self.assertEqualAndEqualSign(pow_op(-INF, INF), INF) + self.assertEqualAndEqualSign(pow_op(-2.0, INF), INF) + self.assertEqualAndEqualSign(pow_op(2.0, INF), INF) + self.assertEqualAndEqualSign(pow_op(INF, INF), INF) + + # (-INF)**y is -0.0 for y a negative odd integer + self.assertEqualAndEqualSign(pow_op(-INF, -1.0), -0.0) + + # (-INF)**y is 0.0 for y negative but not an odd integer + self.assertEqualAndEqualSign(pow_op(-INF, -0.5), 0.0) + self.assertEqualAndEqualSign(pow_op(-INF, -2.0), 0.0) + + # (-INF)**y is -INF for y a positive odd integer + self.assertEqualAndEqualSign(pow_op(-INF, 1.0), -INF) + + # (-INF)**y is INF for y positive but not an odd integer + self.assertEqualAndEqualSign(pow_op(-INF, 0.5), INF) + self.assertEqualAndEqualSign(pow_op(-INF, 2.0), INF) + + # INF**y is INF for y positive + self.assertEqualAndEqualSign(pow_op(INF, 0.5), INF) + self.assertEqualAndEqualSign(pow_op(INF, 1.0), INF) + self.assertEqualAndEqualSign(pow_op(INF, 2.0), INF) + + # INF**y is 0.0 for y negative + self.assertEqualAndEqualSign(pow_op(INF, -2.0), 0.0) + self.assertEqualAndEqualSign(pow_op(INF, -1.0), 0.0) + self.assertEqualAndEqualSign(pow_op(INF, -0.5), 0.0) + + # basic checks not covered by the special cases above + self.assertEqualAndEqualSign(pow_op(-2.0, -2.0), 0.25) + self.assertEqualAndEqualSign(pow_op(-2.0, -1.0), -0.5) + self.assertEqualAndEqualSign(pow_op(-2.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-2.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-2.0, 1.0), -2.0) + self.assertEqualAndEqualSign(pow_op(-2.0, 2.0), 4.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -2.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -1.0), -1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 1.0), -1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 2.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, -2.0), 0.25) + self.assertEqualAndEqualSign(pow_op(2.0, -1.0), 0.5) + self.assertEqualAndEqualSign(pow_op(2.0, -0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, 0.0), 1.0) + self.assertEqualAndEqualSign(pow_op(2.0, 1.0), 2.0) + self.assertEqualAndEqualSign(pow_op(2.0, 2.0), 4.0) + + # 1 ** large and -1 ** large; some libms apparently + # have problems with these + self.assertEqualAndEqualSign(pow_op(1.0, -1e100), 1.0) + self.assertEqualAndEqualSign(pow_op(1.0, 1e100), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, -1e100), 1.0) + self.assertEqualAndEqualSign(pow_op(-1.0, 1e100), 1.0) + + # check sign for results that underflow to 0 + self.assertEqualAndEqualSign(pow_op(-2.0, -2000.0), 0.0) + self.assertEqual(type(pow_op(-2.0, -2000.5)), complex) + self.assertEqualAndEqualSign(pow_op(-2.0, -2001.0), -0.0) + self.assertEqualAndEqualSign(pow_op(2.0, -2000.0), 0.0) + self.assertEqualAndEqualSign(pow_op(2.0, -2000.5), 0.0) + self.assertEqualAndEqualSign(pow_op(2.0, -2001.0), 0.0) + self.assertEqualAndEqualSign(pow_op(-0.5, 2000.0), 0.0) + self.assertEqual(type(pow_op(-0.5, 2000.5)), complex) + self.assertEqualAndEqualSign(pow_op(-0.5, 2001.0), -0.0) + self.assertEqualAndEqualSign(pow_op(0.5, 2000.0), 0.0) + self.assertEqualAndEqualSign(pow_op(0.5, 2000.5), 0.0) + self.assertEqualAndEqualSign(pow_op(0.5, 2001.0), 0.0) + + # check we don't raise an exception for subnormal results, + # and validate signs. Tests currently disabled, since + # they fail on systems where a subnormal result from pow + # is flushed to zero (e.g. Debian/ia64.) + #self.assertTrue(0.0 < pow_op(0.5, 1048) < 1e-315) + #self.assertTrue(0.0 < pow_op(-0.5, 1048) < 1e-315) + #self.assertTrue(0.0 < pow_op(0.5, 1047) < 1e-315) + #self.assertTrue(0.0 > pow_op(-0.5, 1047) > -1e-315) + #self.assertTrue(0.0 < pow_op(2.0, -1048) < 1e-315) + #self.assertTrue(0.0 < pow_op(-2.0, -1048) < 1e-315) + #self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315) + #self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315) class FormatFunctionsTestCase(unittest.TestCase): Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Wed Dec 30 17:22:49 2009 @@ -186,6 +186,7 @@ Daniel Dittmar Jaromir Dolecek Ismail Donmez +Marcos Donolo Dima Dorfman Cesar Douady Dean Draayer Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 30 17:22:49 2009 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #7534: Fix handling of IEEE specials (infinities, nans, + negative zero) in ** operator. The behaviour now conforms to that + described in C99 Annex F. + - Issue #1811: improve accuracy and cross-platform consistency for true division of integers: the result of a/b is now correctly rounded for ints a and b (at least on IEEE 754 platforms), and in Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Wed Dec 30 17:22:49 2009 @@ -671,10 +671,15 @@ return r; } +/* determine whether x is an odd integer or not; assumes that + x is not an infinity or nan. */ +#define DOUBLE_IS_ODD_INTEGER(x) (fmod(fabs(x), 2.0) == 1.0) + static PyObject * float_pow(PyObject *v, PyObject *w, PyObject *z) { double iv, iw, ix; + int negate_result = 0; if ((PyObject *)z != Py_None) { PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not " @@ -686,20 +691,56 @@ CONVERT_TO_DOUBLE(w, iw); /* Sort out special cases here instead of relying on pow() */ - if (iw == 0) { /* v**0 is 1, even 0**0 */ + if (iw == 0) { /* v**0 is 1, even 0**0 */ return PyFloat_FromDouble(1.0); } - if (iv == 0.0) { /* 0**w is error if w<0, else 1 */ + if (Py_IS_NAN(iv)) { /* nan**w = nan, unless w == 0 */ + return PyFloat_FromDouble(iv); + } + if (Py_IS_NAN(iw)) { /* v**nan = nan, unless v == 1; 1**nan = 1 */ + return PyFloat_FromDouble(iv == 1.0 ? 1.0 : iw); + } + if (Py_IS_INFINITY(iw)) { + /* v**inf is: 0.0 if abs(v) < 1; 1.0 if abs(v) == 1; inf if + * abs(v) > 1 (including case where v infinite) + * + * v**-inf is: inf if abs(v) < 1; 1.0 if abs(v) == 1; 0.0 if + * abs(v) > 1 (including case where v infinite) + */ + iv = fabs(iv); + if (iv == 1.0) + return PyFloat_FromDouble(1.0); + else if ((iw > 0.0) == (iv > 1.0)) + return PyFloat_FromDouble(fabs(iw)); /* return inf */ + else + return PyFloat_FromDouble(0.0); + } + if (Py_IS_INFINITY(iv)) { + /* (+-inf)**w is: inf for w positive, 0 for w negative; in + * both cases, we need to add the appropriate sign if w is + * an odd integer. + */ + int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw); + if (iw > 0.0) + return PyFloat_FromDouble(iw_is_odd ? iv : fabs(iv)); + else + return PyFloat_FromDouble(iw_is_odd ? + copysign(0.0, iv) : 0.0); + } + if (iv == 0.0) { /* 0**w is: 0 for w positive, 1 for w zero + (already dealt with above), and an error + if w is negative. */ + int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw); if (iw < 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, - "0.0 cannot be raised to a negative power"); + "0.0 cannot be raised to a " + "negative power"); return NULL; } - return PyFloat_FromDouble(0.0); - } - if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */ - return PyFloat_FromDouble(1.0); + /* use correct sign if iw is odd */ + return PyFloat_FromDouble(iw_is_odd ? iv : 0.0); } + if (iv < 0.0) { /* Whether this is an error is a mess, and bumps into libm * bugs so we have to figure it out ourselves. @@ -710,33 +751,41 @@ */ return PyComplex_Type.tp_as_number->nb_power(v, w, z); } - /* iw is an exact integer, albeit perhaps a very large one. + /* iw is an exact integer, albeit perhaps a very large + * one. Replace iv by its absolute value and remember + * to negate the pow result if iw is odd. + */ + iv = -iv; + negate_result = DOUBLE_IS_ODD_INTEGER(iw); + } + + if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */ + /* (-1) ** large_integer also ends up here. Here's an + * extract from the comments for the previous + * implementation explaining why this special case is + * necessary: + * * -1 raised to an exact integer should never be exceptional. * Alas, some libms (chiefly glibc as of early 2003) return * NaN and set EDOM on pow(-1, large_int) if the int doesn't * happen to be representable in a *C* integer. That's a - * bug; we let that slide in math.pow() (which currently - * reflects all platform accidents), but not for Python's **. - */ - if (iv == -1.0 && Py_IS_FINITE(iw)) { - /* Return 1 if iw is even, -1 if iw is odd; there's - * no guarantee that any C integral type is big - * enough to hold iw, so we have to check this - * indirectly. - */ - ix = floor(iw * 0.5) * 2.0; - return PyFloat_FromDouble(ix == iw ? 1.0 : -1.0); - } - /* Else iv != -1.0, and overflow or underflow are possible. - * Unless we're to write pow() ourselves, we have to trust - * the platform to do this correctly. + * bug. */ + return PyFloat_FromDouble(negate_result ? -1.0 : 1.0); } + + /* Now iv and iw are finite, iw is nonzero, and iv is + * positive and not equal to 1.0. We finally allow + * the platform pow to step in and do the rest. + */ errno = 0; PyFPE_START_PROTECT("pow", return NULL) ix = pow(iv, iw); PyFPE_END_PROTECT(ix) Py_ADJUST_ERANGE1(ix); + if (negate_result) + ix = -ix; + if (errno != 0) { /* We don't expect any errno value other than ERANGE, but * the range of libm bugs appears unbounded. @@ -748,6 +797,8 @@ return PyFloat_FromDouble(ix); } +#undef DOUBLE_IS_ODD_INTEGER + static PyObject * float_neg(PyFloatObject *v) { From python-checkins at python.org Wed Dec 30 17:23:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 30 Dec 2009 16:23:23 -0000 Subject: [Python-checkins] r77147 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Wed Dec 30 17:23:22 2009 New Revision: 77147 Log: Blocked revisions 77146 via svnmerge ................ r77146 | mark.dickinson | 2009-12-30 16:22:49 +0000 (Wed, 30 Dec 2009) | 14 lines Merged revisions 77139-77140 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77139 | mark.dickinson | 2009-12-30 12:12:23 +0000 (Wed, 30 Dec 2009) | 3 lines Issue #7534: Fix handling of nans, infinities, and negative zero in ** operator, on IEEE 754 platforms. Thanks Marcos Donolo for original patch. ........ r77140 | mark.dickinson | 2009-12-30 12:22:49 +0000 (Wed, 30 Dec 2009) | 1 line Add Marcos Donolo for work on issue 7534 patch. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Wed Dec 30 17:23:43 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 16:23:43 -0000 Subject: [Python-checkins] r77148 - in python/branches/release26-maint: Doc/Makefile Message-ID: Author: georg.brandl Date: Wed Dec 30 17:23:42 2009 New Revision: 77148 Log: Merged revisions 77145 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77145 | georg.brandl | 2009-12-30 17:21:26 +0100 (Mi, 30 Dez 2009) | 1 line Use new Pygments version. ........ Modified: python/branches/release26-maint/ (props changed) 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 Wed Dec 30 17:23:42 2009 @@ -44,7 +44,7 @@ fi @if [ ! -d tools/pygments ]; then \ echo "Checking out Pygments..."; \ - svn checkout $(SVNROOT)/external/Pygments-0.11.1/pygments tools/pygments; \ + svn checkout $(SVNROOT)/external/Pygments-1.1.1/pygments tools/pygments; \ fi update: checkout From python-checkins at python.org Wed Dec 30 17:24:25 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 16:24:25 -0000 Subject: [Python-checkins] r77149 - in python/branches/py3k: Doc/Makefile Message-ID: Author: georg.brandl Date: Wed Dec 30 17:24:25 2009 New Revision: 77149 Log: Merged revisions 77145 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77145 | georg.brandl | 2009-12-30 17:21:26 +0100 (Mi, 30 Dez 2009) | 1 line Use new Pygments version. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/Makefile Modified: python/branches/py3k/Doc/Makefile ============================================================================== --- python/branches/py3k/Doc/Makefile (original) +++ python/branches/py3k/Doc/Makefile Wed Dec 30 17:24:25 2009 @@ -44,7 +44,7 @@ fi @if [ ! -d tools/pygments ]; then \ echo "Checking out Pygments..."; \ - svn checkout $(SVNROOT)/external/Pygments-0.11.1/pygments tools/pygments; \ + svn checkout $(SVNROOT)/external/Pygments-1.1.1/pygments tools/pygments; \ fi update: checkout From python-checkins at python.org Wed Dec 30 17:25:13 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 16:25:13 -0000 Subject: [Python-checkins] r77150 - in python/branches/release31-maint: Doc/Makefile Message-ID: Author: georg.brandl Date: Wed Dec 30 17:25:13 2009 New Revision: 77150 Log: Merged revisions 77149 via svnmerge from svn+ssh://svn.python.org/python/branches/py3k ................ r77149 | georg.brandl | 2009-12-30 17:24:25 +0100 (Mi, 30 Dez 2009) | 9 lines Merged revisions 77145 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77145 | georg.brandl | 2009-12-30 17:21:26 +0100 (Mi, 30 Dez 2009) | 1 line Use new Pygments version. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/Makefile Modified: python/branches/release31-maint/Doc/Makefile ============================================================================== --- python/branches/release31-maint/Doc/Makefile (original) +++ python/branches/release31-maint/Doc/Makefile Wed Dec 30 17:25:13 2009 @@ -44,7 +44,7 @@ fi @if [ ! -d tools/pygments ]; then \ echo "Checking out Pygments..."; \ - svn checkout $(SVNROOT)/external/Pygments-0.11.1/pygments tools/pygments; \ + svn checkout $(SVNROOT)/external/Pygments-1.1.1/pygments tools/pygments; \ fi update: checkout From python-checkins at python.org Wed Dec 30 19:32:50 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 18:32:50 -0000 Subject: [Python-checkins] r77151 - in python/trunk/Doc: README.txt make.bat Message-ID: Author: georg.brandl Date: Wed Dec 30 19:32:50 2009 New Revision: 77151 Log: #7487: update Pygments version. Modified: python/trunk/Doc/README.txt python/trunk/Doc/make.bat Modified: python/trunk/Doc/README.txt ============================================================================== --- python/trunk/Doc/README.txt (original) +++ python/trunk/Doc/README.txt Wed Dec 30 19:32:50 2009 @@ -90,7 +90,7 @@ You can optionally also install Pygments, either as a checkout via :: - svn co http://svn.python.org/projects/external/Pygments-0.11.1/pygments tools/pygments + svn co http://svn.python.org/projects/external/Pygments-1.1.1/pygments tools/pygments or from PyPI at http://pypi.python.org/pypi/Pygments. Modified: python/trunk/Doc/make.bat ============================================================================== --- python/trunk/Doc/make.bat (original) +++ python/trunk/Doc/make.bat Wed Dec 30 19:32:50 2009 @@ -37,7 +37,7 @@ svn co %SVNROOT%/external/Sphinx-0.6.3/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 +svn co %SVNROOT%/external/Pygments-1.1.1/pygments tools/pygments goto end :update From python-checkins at python.org Wed Dec 30 19:36:09 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 18:36:09 -0000 Subject: [Python-checkins] r77152 - python/trunk/Doc/Makefile Message-ID: Author: georg.brandl Date: Wed Dec 30 19:36:09 2009 New Revision: 77152 Log: #7602: improve "clean" and "checkout" targets now that all tools are in externals. Modified: python/trunk/Doc/Makefile Modified: python/trunk/Doc/Makefile ============================================================================== --- python/trunk/Doc/Makefile (original) +++ python/trunk/Doc/Makefile Wed Dec 30 19:36:09 2009 @@ -47,11 +47,7 @@ svn checkout $(SVNROOT)/external/Pygments-1.1.1/pygments tools/pygments; \ fi -update: checkout - svn update tools/sphinx - svn update tools/docutils - svn update tools/jinja2 - svn update tools/pygments +update: clean checkout build: checkout mkdir -p build/$(BUILDER) build/doctrees @@ -111,6 +107,9 @@ clean: -rm -rf build/* -rm -rf tools/sphinx + -rm -rf tools/pygments + -rm -rf tools/jinja2 + -rm -rf tools/docutils dist: -rm -rf dist From python-checkins at python.org Wed Dec 30 19:44:39 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 18:44:39 -0000 Subject: [Python-checkins] r77153 - peps/trunk/pep-0373.txt Message-ID: Author: georg.brandl Date: Wed Dec 30 19:44:38 2009 New Revision: 77153 Log: Remove 3.2 version. Modified: peps/trunk/pep-0373.txt Modified: peps/trunk/pep-0373.txt ============================================================================== --- peps/trunk/pep-0373.txt (original) +++ peps/trunk/pep-0373.txt Wed Dec 30 19:44:38 2009 @@ -7,7 +7,7 @@ Type: Informational Content-Type: text/x-rst Created: 3-Nov-2008 -Python-Version: 2.7, 3.2 +Python-Version: 2.7 Abstract From python-checkins at python.org Wed Dec 30 19:59:49 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 18:59:49 -0000 Subject: [Python-checkins] r77154 - in peps/trunk: pep-0392.txt pep-3003.txt Message-ID: Author: georg.brandl Date: Wed Dec 30 19:59:48 2009 New Revision: 77154 Log: Add PEP 392, Python 3.2 Release Schedule. Added: peps/trunk/pep-0392.txt (contents, props changed) Modified: peps/trunk/pep-3003.txt Added: peps/trunk/pep-0392.txt ============================================================================== --- (empty file) +++ peps/trunk/pep-0392.txt Wed Dec 30 19:59:48 2009 @@ -0,0 +1,87 @@ +PEP: 375 +Title: Python 3.2 Release Schedule +Version: $Revision $ +Last-Modified: $Date $ +Author: Georg Brandl +Status: Active +Type: Informational +Content-Type: text/x-rst +Created: 30-Dec-2009 +Python-Version: 3.2 + + +Abstract +======== + +This document describes the development and release schedule for +Python 3.2. The schedule primarily concerns itself with PEP-sized +items. Small features may be added up to and including the first beta +release. Bugs may be fixed until the final release. + + +Release Manager and Crew +======================== + +======================= ================== +Position Name +======================= ================== +3.2 Release Manager Georg Brandl +Windows installers Martin v. Loewis +Mac installers Ronald Oussoren +======================= ================== + + +Release Schedule +================ + +The current schedule is: + +- 3.2 alpha 1: June 26, 2010 +- 3.2 alpha 2: July 24, 2010 +- 3.2 alpha 3: August 21, 2010 +- 3.2 beta 1: September 18, 2010 + +(No new features beyond this point.) + +- 3.2 beta 2: October 16, 2010 +- 3.2 candidate 1: November 13, 2010 +- 3.2 candidate 2: November 27, 2010 +- 3.2 final: December 11, 2010 + +Every release day listed here is a Saturday; the actual availability +of the release for download on python.org will depend on the schedules +of the crew. + + +Features for 3.2 +================ + +Note that PEP 3003 [#pep3003]_ is in effect: no changes to language +syntax and no additions to the builtins may be made. + +No large-scale changes have been recorded yet. + + +References +========== + +.. [#pep3003] + http://www.python.org/dev/peps/pep-3003/ + + + +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: Modified: peps/trunk/pep-3003.txt ============================================================================== --- peps/trunk/pep-3003.txt (original) +++ peps/trunk/pep-3003.txt Wed Dec 30 19:59:48 2009 @@ -129,11 +129,11 @@ Retroactive =========== -It is important to note that the moratorium covers all changes since the -release of Python 3.1. This rule is intended to avoid features being rushed or -smuggled into the CPython source tree while the moratorium is being discussed. -A review of the NEWS file for the py3k development branch showed no -commits would need to be rolled back in order to meet this goal. +It is important to note that the moratorium covers all changes since the release +of Python 3.1. This rule is intended to avoid features being rushed or smuggled +into the CPython source tree while the moratorium is being discussed. A review +of the NEWS file for the py3k development branch showed no commits would need to +be rolled back in order to meet this goal. Extensions @@ -154,7 +154,7 @@ .. [2] http://www.jython.org/ .. [3] http://www.codeplex.com/IronPython .. [4] http://codespeak.net/pypy/ -.. [5] http://code.google.com/p/unladen-swallow/ +.. [5] http://code.google.com/p/unladen-swallow/ .. From python-checkins at python.org Wed Dec 30 20:03:02 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 19:03:02 -0000 Subject: [Python-checkins] r77155 - in python/trunk: Doc/library/msvcrt.rst PC/msvcrtmodule.c Message-ID: Author: georg.brandl Date: Wed Dec 30 20:03:00 2009 New Revision: 77155 Log: We only support Windows NT derivatives now. Modified: python/trunk/Doc/library/msvcrt.rst python/trunk/PC/msvcrtmodule.c Modified: python/trunk/Doc/library/msvcrt.rst ============================================================================== --- python/trunk/Doc/library/msvcrt.rst (original) +++ python/trunk/Doc/library/msvcrt.rst Wed Dec 30 20:03:00 2009 @@ -153,6 +153,4 @@ .. function:: heapmin() Force the :cfunc:`malloc` heap to clean itself up and return unused blocks to - the operating system. This only works on Windows NT. On failure, this raises - :exc:`IOError`. - + the operating system. On failure, this raises :exc:`IOError`. Modified: python/trunk/PC/msvcrtmodule.c ============================================================================== --- python/trunk/PC/msvcrtmodule.c (original) +++ python/trunk/PC/msvcrtmodule.c Wed Dec 30 20:03:00 2009 @@ -47,8 +47,7 @@ "heapmin() -> None\n\ \n\ Force the malloc() heap to clean itself up and return unused blocks\n\ -to the operating system. This only works on Windows NT. On failure,\n\ -this raises IOError."); +to the operating system. On failure, this raises IOError."); // Perform locking operations on a C runtime file descriptor. static PyObject * From python-checkins at python.org Wed Dec 30 20:05:15 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 30 Dec 2009 19:05:15 -0000 Subject: [Python-checkins] r77156 - peps/trunk/pep-0392.txt Message-ID: Author: georg.brandl Date: Wed Dec 30 20:05:14 2009 New Revision: 77156 Log: Remove table. Modified: peps/trunk/pep-0392.txt Modified: peps/trunk/pep-0392.txt ============================================================================== --- peps/trunk/pep-0392.txt (original) +++ peps/trunk/pep-0392.txt Wed Dec 30 20:05:14 2009 @@ -16,19 +16,17 @@ This document describes the development and release schedule for Python 3.2. The schedule primarily concerns itself with PEP-sized items. Small features may be added up to and including the first beta -release. Bugs may be fixed until the final release. +release. Bugs may be fixed until the final release, which is planned +for December 2010. Release Manager and Crew ======================== -======================= ================== -Position Name -======================= ================== -3.2 Release Manager Georg Brandl -Windows installers Martin v. Loewis -Mac installers Ronald Oussoren -======================= ================== +- 3.2 Release Manager: Georg Brandl +- Windows installers: Martin v. Loewis +- Mac installers: Ronald Oussoren +- Documentation: Georg Brandl Release Schedule @@ -48,6 +46,8 @@ - 3.2 candidate 2: November 27, 2010 - 3.2 final: December 11, 2010 +.. don't forget to update final date above as well + Every release day listed here is a Saturday; the actual availability of the release for download on python.org will depend on the schedules of the crew. From python-checkins at python.org Wed Dec 30 20:34:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 19:34:10 -0000 Subject: [Python-checkins] r77157 - in python/trunk: Doc/c-api/structures.rst Lib/test/test_descr.py Misc/NEWS Python/structmember.c Message-ID: Author: benjamin.peterson Date: Wed Dec 30 20:34:10 2009 New Revision: 77157 Log: check if the attribute is set before deleting it with T_OBJECT_EX (fixes #7604) Also, add a note to the docs about the better behavior of T_OBJECT_EX as compared to T_OBJECT. Modified: python/trunk/Doc/c-api/structures.rst python/trunk/Lib/test/test_descr.py python/trunk/Misc/NEWS python/trunk/Python/structmember.c Modified: python/trunk/Doc/c-api/structures.rst ============================================================================== --- python/trunk/Doc/c-api/structures.rst (original) +++ python/trunk/Doc/c-api/structures.rst Wed Dec 30 20:34:10 2009 @@ -281,7 +281,10 @@ :cmacro:`T_OBJECT` and :cmacro:`T_OBJECT_EX` differ in that :cmacro:`T_OBJECT` returns ``None`` if the member is *NULL* and - :cmacro:`T_OBJECT_EX` raises an :exc:`AttributeError`. + :cmacro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use + :cmacro:`T_OBJECT_EX` over :cmacro:`T_OBJECT` because :cmacro:`T_OBJECT_EX` + handles use of the :stmt:`del` statement on that attribute more correctly + than :cmacro:`T_OBJECT`. :attr:`flags` can be 0 for write and read access or :cmacro:`READONLY` for read-only access. Using :cmacro:`T_STRING` for :attr:`type` implies Modified: python/trunk/Lib/test/test_descr.py ============================================================================== --- python/trunk/Lib/test/test_descr.py (original) +++ python/trunk/Lib/test/test_descr.py Wed Dec 30 20:34:10 2009 @@ -1166,6 +1166,11 @@ del h self.assertEqual(s.getvalue(), '') + class X(object): + __slots__ = "a" + with self.assertRaises(AttributeError): + del X().a + def test_slots_special(self): # Testing __dict__ and __weakref__ in __slots__... class D(object): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Dec 30 20:34:10 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7604: Deleting an unset slotted attribute did not raise an + AttributeError. + - Issue #7534: Fix handling of IEEE specials (infinities, nans, negative zero) in ** operator. The behaviour now conforms to that described in C99 Annex F. Modified: python/trunk/Python/structmember.c ============================================================================== --- python/trunk/Python/structmember.c (original) +++ python/trunk/Python/structmember.c Wed Dec 30 20:34:10 2009 @@ -170,6 +170,8 @@ { PyObject *oldv; + addr += l->offset; + if ((l->flags & READONLY) || l->type == T_STRING) { PyErr_SetString(PyExc_TypeError, "readonly attribute"); @@ -179,12 +181,20 @@ PyErr_SetString(PyExc_RuntimeError, "restricted attribute"); return -1; } - if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) { - PyErr_SetString(PyExc_TypeError, - "can't delete numeric/char attribute"); - return -1; + if (v == NULL) { + if (l->type == T_OBJECT_EX) { + /* Check if the attribute is set. */ + if (*(PyObject **)addr == NULL) { + PyErr_SetString(PyExc_AttributeError, l->name); + return -1; + } + } + else if (l->type != T_OBJECT) { + PyErr_SetString(PyExc_TypeError, + "can't delete numeric/char attribute"); + return -1; + } } - addr += l->offset; switch (l->type) { case T_BOOL:{ if (!PyBool_Check(v)) { From python-checkins at python.org Wed Dec 30 20:41:04 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 19:41:04 -0000 Subject: [Python-checkins] r77158 - sandbox/trunk/2to3/lib2to3/tests/test_main.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 20:41:03 2009 New Revision: 77158 Log: clean up logging's global state after the test finishes Modified: sandbox/trunk/2to3/lib2to3/tests/test_main.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_main.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_main.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_main.py Wed Dec 30 20:41:03 2009 @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import sys import codecs +import logging import StringIO import unittest @@ -9,6 +10,10 @@ class TestMain(unittest.TestCase): + def tearDown(self): + # Clean up logging configuration down by main. + del logging.root.handlers[:] + def run_2to3_capture(self, args, in_capture, out_capture, err_capture): save_stdin = sys.stdin save_stdout = sys.stdout From python-checkins at python.org Wed Dec 30 20:41:49 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 19:41:49 -0000 Subject: [Python-checkins] r77159 - in python/branches/release26-maint: Doc/c-api/structures.rst Lib/test/test_descr.py Misc/NEWS Python/structmember.c Message-ID: Author: benjamin.peterson Date: Wed Dec 30 20:41:48 2009 New Revision: 77159 Log: Merged revisions 77157 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77157 | benjamin.peterson | 2009-12-30 13:34:10 -0600 (Wed, 30 Dec 2009) | 5 lines check if the attribute is set before deleting it with T_OBJECT_EX (fixes #7604) Also, add a note to the docs about the better behavior of T_OBJECT_EX as compared to T_OBJECT. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/c-api/structures.rst python/branches/release26-maint/Lib/test/test_descr.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Python/structmember.c 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 Dec 30 20:41:48 2009 @@ -281,7 +281,10 @@ :cmacro:`T_OBJECT` and :cmacro:`T_OBJECT_EX` differ in that :cmacro:`T_OBJECT` returns ``None`` if the member is *NULL* and - :cmacro:`T_OBJECT_EX` raises an :exc:`AttributeError`. + :cmacro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use + :cmacro:`T_OBJECT_EX` over :cmacro:`T_OBJECT` because :cmacro:`T_OBJECT_EX` + handles use of the :stmt:`del` statement on that attribute more correctly + than :cmacro:`T_OBJECT`. :attr:`flags` can be 0 for write and read access or :cmacro:`READONLY` for read-only access. Using :cmacro:`T_STRING` for :attr:`type` implies 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 Wed Dec 30 20:41:48 2009 @@ -1142,6 +1142,11 @@ del h self.assertEqual(s.getvalue(), '') + class X(object): + __slots__ = "a" + with self.assertRaises(AttributeError): + del X().a + def test_slots_special(self): # Testing __dict__ and __weakref__ in __slots__... class D(object): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Dec 30 20:41:48 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7604: Deleting an unset slotted attribute did not raise an + AttributeError. + - Issue #7413: Passing '\0' as the separator to datetime.datetime.isoformat() used to drop the time part of the result. Modified: python/branches/release26-maint/Python/structmember.c ============================================================================== --- python/branches/release26-maint/Python/structmember.c (original) +++ python/branches/release26-maint/Python/structmember.c Wed Dec 30 20:41:48 2009 @@ -170,6 +170,8 @@ { PyObject *oldv; + addr += l->offset; + if ((l->flags & READONLY) || l->type == T_STRING) { PyErr_SetString(PyExc_TypeError, "readonly attribute"); @@ -179,12 +181,20 @@ PyErr_SetString(PyExc_RuntimeError, "restricted attribute"); return -1; } - if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) { - PyErr_SetString(PyExc_TypeError, - "can't delete numeric/char attribute"); - return -1; + if (v == NULL) { + if (l->type == T_OBJECT_EX) { + /* Check if the attribute is set. */ + if (*(PyObject **)addr == NULL) { + PyErr_SetString(PyExc_AttributeError, l->name); + return -1; + } + } + else if (l->type != T_OBJECT) { + PyErr_SetString(PyExc_TypeError, + "can't delete numeric/char attribute"); + return -1; + } } - addr += l->offset; switch (l->type) { case T_BOOL:{ if (!PyBool_Check(v)) { From python-checkins at python.org Wed Dec 30 20:44:23 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 19:44:23 -0000 Subject: [Python-checkins] r77160 - in python/trunk/Lib/lib2to3: tests/test_main.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 20:44:23 2009 New Revision: 77160 Log: Merged revisions 77158 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r77158 | benjamin.peterson | 2009-12-30 13:41:03 -0600 (Wed, 30 Dec 2009) | 1 line clean up logging's global state after the test finishes ........ Modified: python/trunk/Lib/lib2to3/ (props changed) python/trunk/Lib/lib2to3/tests/test_main.py Modified: python/trunk/Lib/lib2to3/tests/test_main.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_main.py (original) +++ python/trunk/Lib/lib2to3/tests/test_main.py Wed Dec 30 20:44:23 2009 @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import sys import codecs +import logging import StringIO import unittest @@ -9,6 +10,10 @@ class TestMain(unittest.TestCase): + def tearDown(self): + # Clean up logging configuration down by main. + del logging.root.handlers[:] + def run_2to3_capture(self, args, in_capture, out_capture, err_capture): save_stdin = sys.stdin save_stdout = sys.stdout From python-checkins at python.org Wed Dec 30 20:44:55 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 19:44:55 -0000 Subject: [Python-checkins] r77161 - in python/branches/py3k: Doc/c-api/structures.rst Lib/test/test_descr.py Misc/NEWS Python/structmember.c Message-ID: Author: benjamin.peterson Date: Wed Dec 30 20:44:54 2009 New Revision: 77161 Log: Merged revisions 77157 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77157 | benjamin.peterson | 2009-12-30 13:34:10 -0600 (Wed, 30 Dec 2009) | 5 lines check if the attribute is set before deleting it with T_OBJECT_EX (fixes #7604) Also, add a note to the docs about the better behavior of T_OBJECT_EX as compared to T_OBJECT. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/structures.rst python/branches/py3k/Lib/test/test_descr.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/structmember.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 Wed Dec 30 20:44:54 2009 @@ -273,7 +273,10 @@ :cmacro:`T_OBJECT` and :cmacro:`T_OBJECT_EX` differ in that :cmacro:`T_OBJECT` returns ``None`` if the member is *NULL* and - :cmacro:`T_OBJECT_EX` raises an :exc:`AttributeError`. + :cmacro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use + :cmacro:`T_OBJECT_EX` over :cmacro:`T_OBJECT` because :cmacro:`T_OBJECT_EX` + handles use of the :stmt:`del` statement on that attribute more correctly + than :cmacro:`T_OBJECT`. :attr:`flags` can be 0 for write and read access or :cmacro:`READONLY` for read-only access. Using :cmacro:`T_STRING` for :attr:`type` implies 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 Wed Dec 30 20:44:54 2009 @@ -1040,6 +1040,11 @@ del h self.assertEqual(s.getvalue(), '') + class X(object): + __slots__ = "a" + with self.assertRaises(AttributeError): + del X().a + def test_slots_special(self): # Testing __dict__ and __weakref__ in __slots__... class D(object): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Dec 30 20:44:54 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7604: Deleting an unset slotted attribute did not raise an + AttributeError. + - Issue #7534: Fix handling of IEEE specials (infinities, nans, negative zero) in ** operator. The behaviour now conforms to that described in C99 Annex F. Modified: python/branches/py3k/Python/structmember.c ============================================================================== --- python/branches/py3k/Python/structmember.c (original) +++ python/branches/py3k/Python/structmember.c Wed Dec 30 20:44:54 2009 @@ -104,17 +104,27 @@ { PyObject *oldv; + addr += l->offset; + if ((l->flags & READONLY) || l->type == T_STRING) { PyErr_SetString(PyExc_AttributeError, "readonly attribute"); return -1; } - if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) { - PyErr_SetString(PyExc_TypeError, - "can't delete numeric/char attribute"); - return -1; + if (v == NULL) { + if (l->type == T_OBJECT_EX) { + /* Check if the attribute is set. */ + if (*(PyObject **)addr == NULL) { + PyErr_SetString(PyExc_AttributeError, l->name); + return -1; + } + } + else if (l->type != T_OBJECT) { + PyErr_SetString(PyExc_TypeError, + "can't delete numeric/char attribute"); + return -1; + } } - addr += l->offset; switch (l->type) { case T_BOOL:{ if (!PyBool_Check(v)) { From python-checkins at python.org Wed Dec 30 20:47:05 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 19:47:05 -0000 Subject: [Python-checkins] r77162 - in python/branches/release31-maint: Doc/c-api/structures.rst Lib/test/test_descr.py Misc/NEWS Python/structmember.c Message-ID: Author: benjamin.peterson Date: Wed Dec 30 20:47:05 2009 New Revision: 77162 Log: Merged revisions 77161 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77161 | benjamin.peterson | 2009-12-30 13:44:54 -0600 (Wed, 30 Dec 2009) | 12 lines Merged revisions 77157 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77157 | benjamin.peterson | 2009-12-30 13:34:10 -0600 (Wed, 30 Dec 2009) | 5 lines check if the attribute is set before deleting it with T_OBJECT_EX (fixes #7604) Also, add a note to the docs about the better behavior of T_OBJECT_EX as compared to T_OBJECT. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/c-api/structures.rst python/branches/release31-maint/Lib/test/test_descr.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Python/structmember.c Modified: python/branches/release31-maint/Doc/c-api/structures.rst ============================================================================== --- python/branches/release31-maint/Doc/c-api/structures.rst (original) +++ python/branches/release31-maint/Doc/c-api/structures.rst Wed Dec 30 20:47:05 2009 @@ -273,7 +273,10 @@ :cmacro:`T_OBJECT` and :cmacro:`T_OBJECT_EX` differ in that :cmacro:`T_OBJECT` returns ``None`` if the member is *NULL* and - :cmacro:`T_OBJECT_EX` raises an :exc:`AttributeError`. + :cmacro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use + :cmacro:`T_OBJECT_EX` over :cmacro:`T_OBJECT` because :cmacro:`T_OBJECT_EX` + handles use of the :stmt:`del` statement on that attribute more correctly + than :cmacro:`T_OBJECT`. :attr:`flags` can be 0 for write and read access or :cmacro:`READONLY` for read-only access. Using :cmacro:`T_STRING` for :attr:`type` implies Modified: python/branches/release31-maint/Lib/test/test_descr.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_descr.py (original) +++ python/branches/release31-maint/Lib/test/test_descr.py Wed Dec 30 20:47:05 2009 @@ -1044,6 +1044,11 @@ del h self.assertEqual(s.getvalue(), '') + class X(object): + __slots__ = "a" + with self.assertRaises(AttributeError): + del X().a + def test_slots_special(self): # Testing __dict__ and __weakref__ in __slots__... class D(object): Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Wed Dec 30 20:47:05 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7604: Deleting an unset slotted attribute did not raise an + AttributeError. + - Issue #7466: segmentation fault when the garbage collector is called in the middle of populating a tuple. Patch by Florent Xicluna. Modified: python/branches/release31-maint/Python/structmember.c ============================================================================== --- python/branches/release31-maint/Python/structmember.c (original) +++ python/branches/release31-maint/Python/structmember.c Wed Dec 30 20:47:05 2009 @@ -104,17 +104,27 @@ { PyObject *oldv; + addr += l->offset; + if ((l->flags & READONLY) || l->type == T_STRING) { PyErr_SetString(PyExc_AttributeError, "readonly attribute"); return -1; } - if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) { - PyErr_SetString(PyExc_TypeError, - "can't delete numeric/char attribute"); - return -1; + if (v == NULL) { + if (l->type == T_OBJECT_EX) { + /* Check if the attribute is set. */ + if (*(PyObject **)addr == NULL) { + PyErr_SetString(PyExc_AttributeError, l->name); + return -1; + } + } + else if (l->type != T_OBJECT) { + PyErr_SetString(PyExc_TypeError, + "can't delete numeric/char attribute"); + return -1; + } } - addr += l->offset; switch (l->type) { case T_BOOL:{ if (!PyBool_Check(v)) { From python-checkins at python.org Wed Dec 30 20:52:55 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 19:52:55 -0000 Subject: [Python-checkins] r77163 - in python/branches/py3k: Lib/lib2to3/tests/test_main.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 20:52:54 2009 New Revision: 77163 Log: Merged revisions 77160 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r77160 | benjamin.peterson | 2009-12-30 13:44:23 -0600 (Wed, 30 Dec 2009) | 9 lines Merged revisions 77158 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r77158 | benjamin.peterson | 2009-12-30 13:41:03 -0600 (Wed, 30 Dec 2009) | 1 line clean up logging's global state after the test finishes ........ ................ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/lib2to3/tests/test_main.py Modified: python/branches/py3k/Lib/lib2to3/tests/test_main.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_main.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_main.py Wed Dec 30 20:52:54 2009 @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import sys import codecs +import logging import io import unittest @@ -9,6 +10,10 @@ class TestMain(unittest.TestCase): + def tearDown(self): + # Clean up logging configuration down by main. + del logging.root.handlers[:] + def run_2to3_capture(self, args, in_capture, out_capture, err_capture): save_stdin = sys.stdin save_stdout = sys.stdout From python-checkins at python.org Wed Dec 30 20:54:39 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 19:54:39 -0000 Subject: [Python-checkins] r77164 - in python/branches/release31-maint: Lib/lib2to3/tests/test_main.py Message-ID: Author: benjamin.peterson Date: Wed Dec 30 20:54:39 2009 New Revision: 77164 Log: Merged revisions 77163 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77163 | benjamin.peterson | 2009-12-30 13:52:54 -0600 (Wed, 30 Dec 2009) | 16 lines Merged revisions 77160 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r77160 | benjamin.peterson | 2009-12-30 13:44:23 -0600 (Wed, 30 Dec 2009) | 9 lines Merged revisions 77158 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r77158 | benjamin.peterson | 2009-12-30 13:41:03 -0600 (Wed, 30 Dec 2009) | 1 line clean up logging's global state after the test finishes ........ ................ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/lib2to3/tests/test_main.py Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_main.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_main.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_main.py Wed Dec 30 20:54:39 2009 @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import sys import codecs +import logging import io import unittest @@ -9,6 +10,10 @@ class TestMain(unittest.TestCase): + def tearDown(self): + # Clean up logging configuration down by main. + del logging.root.handlers[:] + def run_2to3_capture(self, args, in_capture, out_capture, err_capture): save_stdin = sys.stdin save_stdout = sys.stdout From python-checkins at python.org Thu Dec 31 00:15:15 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 23:15:15 -0000 Subject: [Python-checkins] r77165 - python/branches/release26-maint/Lib/test/test_descr.py Message-ID: Author: benjamin.peterson Date: Thu Dec 31 00:15:14 2009 New Revision: 77165 Log: rewrite for inferior assertRaises Modified: python/branches/release26-maint/Lib/test/test_descr.py 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 Thu Dec 31 00:15:14 2009 @@ -1144,8 +1144,12 @@ class X(object): __slots__ = "a" - with self.assertRaises(AttributeError): + try: del X().a + except AttributeError: + pass + else: + self.fail("didn't raise AttributeError") def test_slots_special(self): # Testing __dict__ and __weakref__ in __slots__... From solipsis at pitrou.net Thu Dec 31 00:48:54 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 31 Dec 2009 00:48:54 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r77163): sum=0 Message-ID: <20091230234854.71C871771C@ns6635.ovh.net> py3k results for svn r77163 (hg cset c2ab26dcc15b) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/refloguXnJPB', '-x', 'test_httpservers'] From python-checkins at python.org Thu Dec 31 00:53:35 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 30 Dec 2009 23:53:35 -0000 Subject: [Python-checkins] r77166 - peps/trunk/pep-0392.txt Message-ID: Author: benjamin.peterson Date: Thu Dec 31 00:53:34 2009 New Revision: 77166 Log: fix pep number Modified: peps/trunk/pep-0392.txt Modified: peps/trunk/pep-0392.txt ============================================================================== --- peps/trunk/pep-0392.txt (original) +++ peps/trunk/pep-0392.txt Thu Dec 31 00:53:34 2009 @@ -1,4 +1,4 @@ -PEP: 375 +PEP: 392 Title: Python 3.2 Release Schedule Version: $Revision $ Last-Modified: $Date $ From python-checkins at python.org Thu Dec 31 04:11:24 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 31 Dec 2009 03:11:24 -0000 Subject: [Python-checkins] r77167 - in python/branches/py3k: Doc/faq/design.rst Doc/library/2to3.rst Doc/library/ctypes.rst Doc/library/logging.rst Doc/library/msvcrt.rst Doc/library/optparse.rst Doc/library/os.rst Doc/library/select.rst Doc/library/stdtypes.rst Doc/library/string.rst Lib/test/regrtest.py Lib/test/test_posix.py Modules/gcmodule.c Modules/posixmodule.c Modules/selectmodule.c PC/msvcrtmodule.c Message-ID: Author: benjamin.peterson Date: Thu Dec 31 04:11:23 2009 New Revision: 77167 Log: Merged revisions 76847,76851,76869,76882,76891-76892,76924,77007,77070,77092,77096,77120,77126,77155 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76847 | benjamin.peterson | 2009-12-14 21:25:27 -0600 (Mon, 14 Dec 2009) | 1 line adverb ........ r76851 | benjamin.peterson | 2009-12-15 21:28:52 -0600 (Tue, 15 Dec 2009) | 1 line remove lib2to3 resource ........ r76869 | vinay.sajip | 2009-12-17 08:52:00 -0600 (Thu, 17 Dec 2009) | 1 line Issue #7529: logging: Minor correction to documentation. ........ r76882 | georg.brandl | 2009-12-19 11:30:28 -0600 (Sat, 19 Dec 2009) | 1 line #7527: use standard versionadded tags. ........ r76891 | georg.brandl | 2009-12-19 12:16:31 -0600 (Sat, 19 Dec 2009) | 1 line #7479: add note about function availability on Unices. ........ r76892 | georg.brandl | 2009-12-19 12:20:18 -0600 (Sat, 19 Dec 2009) | 1 line #7480: remove tautology. ........ r76924 | georg.brandl | 2009-12-20 08:28:05 -0600 (Sun, 20 Dec 2009) | 1 line Small indentation fix. ........ r77007 | gregory.p.smith | 2009-12-23 03:31:11 -0600 (Wed, 23 Dec 2009) | 3 lines Fix possible integer overflow in lchown and fchown functions. For issue1747858. ........ r77070 | amaury.forgeotdarc | 2009-12-27 14:06:44 -0600 (Sun, 27 Dec 2009) | 2 lines Fix a typo in comment ........ r77092 | georg.brandl | 2009-12-28 02:48:24 -0600 (Mon, 28 Dec 2009) | 1 line #7404: remove reference to non-existing example files. ........ r77096 | benjamin.peterson | 2009-12-28 14:51:17 -0600 (Mon, 28 Dec 2009) | 1 line document new fix_callable behavior ........ r77120 | georg.brandl | 2009-12-29 15:09:17 -0600 (Tue, 29 Dec 2009) | 1 line #7595: fix typo in argument default constant. ........ r77126 | amaury.forgeotdarc | 2009-12-29 17:06:17 -0600 (Tue, 29 Dec 2009) | 2 lines #7579: Add docstrings to the msvcrt module ........ r77155 | georg.brandl | 2009-12-30 13:03:00 -0600 (Wed, 30 Dec 2009) | 1 line We only support Windows NT derivatives now. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/faq/design.rst python/branches/py3k/Doc/library/2to3.rst python/branches/py3k/Doc/library/ctypes.rst python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Doc/library/msvcrt.rst python/branches/py3k/Doc/library/optparse.rst python/branches/py3k/Doc/library/os.rst python/branches/py3k/Doc/library/select.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/library/string.rst python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Lib/test/test_posix.py python/branches/py3k/Modules/gcmodule.c python/branches/py3k/Modules/posixmodule.c python/branches/py3k/Modules/selectmodule.c python/branches/py3k/PC/msvcrtmodule.c Modified: python/branches/py3k/Doc/faq/design.rst ============================================================================== --- python/branches/py3k/Doc/faq/design.rst (original) +++ python/branches/py3k/Doc/faq/design.rst Thu Dec 31 04:11:23 2009 @@ -810,7 +810,7 @@ looks like this:: with obj: - a = 1 # equivalent to obj.a = 1 + a = 1 # equivalent to obj.a = 1 total = total + 1 # obj.total = obj.total + 1 In Python, such a construct would be ambiguous. Modified: python/branches/py3k/Doc/library/2to3.rst ============================================================================== --- python/branches/py3k/Doc/library/2to3.rst (original) +++ python/branches/py3k/Doc/library/2to3.rst Thu Dec 31 04:11:23 2009 @@ -122,7 +122,8 @@ .. 2to3fixer:: callable - Converts ``callable(x)`` to ``hasattr(x, "__call_")``. + Converts ``callable(x)`` to ``isinstance(x, collections.Callable)``, adding + an import to :mod:`collections` if needed. .. 2to3fixer:: dict Modified: python/branches/py3k/Doc/library/ctypes.rst ============================================================================== --- python/branches/py3k/Doc/library/ctypes.rst (original) +++ python/branches/py3k/Doc/library/ctypes.rst Thu Dec 31 04:11:23 2009 @@ -1005,7 +1005,7 @@ >>> It is funny to see that on linux the sort function seems to work much more -efficient, it is doing less comparisons:: +efficiently, it is doing less comparisons:: >>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +LINUX py_cmp_func 5 1 Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Thu Dec 31 04:11:23 2009 @@ -1659,6 +1659,8 @@ and :meth:`flush` methods). +.. currentmodule:: logging + .. class:: StreamHandler(stream=None) Returns a new instance of the :class:`StreamHandler` class. If *stream* is Modified: python/branches/py3k/Doc/library/msvcrt.rst ============================================================================== --- python/branches/py3k/Doc/library/msvcrt.rst (original) +++ python/branches/py3k/Doc/library/msvcrt.rst Thu Dec 31 04:11:23 2009 @@ -144,6 +144,4 @@ .. function:: heapmin() Force the :cfunc:`malloc` heap to clean itself up and return unused blocks to - the operating system. This only works on Windows NT. On failure, this raises - :exc:`IOError`. - + the operating system. On failure, this raises :exc:`IOError`. Modified: python/branches/py3k/Doc/library/optparse.rst ============================================================================== --- python/branches/py3k/Doc/library/optparse.rst (original) +++ python/branches/py3k/Doc/library/optparse.rst Thu Dec 31 04:11:23 2009 @@ -153,9 +153,7 @@ an option that must be supplied on the command-line; note that the phrase "required option" is self-contradictory in English. :mod:`optparse` doesn't prevent you from implementing required options, but doesn't give you much - help at it either. See ``examples/required_1.py`` and - ``examples/required_2.py`` in the :mod:`optparse` source distribution for two - ways to implement required options with :mod:`optparse`. + help at it either. For example, consider this hypothetical command-line:: Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Thu Dec 31 04:11:23 2009 @@ -13,26 +13,34 @@ module, and for high-level file and directory handling see the :mod:`shutil` module. -The design of all built-in operating system dependent modules of Python is such -that as long as the same functionality is available, it uses the same interface; -for example, the function ``os.stat(path)`` returns stat information about -*path* in the same format (which happens to have originated with the POSIX -interface). +Notes on the availability of these functions: -Extensions peculiar to a particular operating system are also available through -the :mod:`os` module, but using them is of course a threat to portability! - -.. note:: - - All functions accepting path or file names accept both bytes and string - objects, and result in an object of the same type, if a path or file name is - returned. +* The design of all built-in operating system dependent modules of Python is + such that as long as the same functionality is available, it uses the same + interface; for example, the function ``os.stat(path)`` returns stat + information about *path* in the same format (which happens to have originated + with the POSIX interface). + +* Extensions peculiar to a particular operating system are also available + through the :mod:`os` module, but using them is of course a threat to + portability. + +* All functions accepting path or file names accept both bytes and string + objects, and result in an object of the same type, if a path or file name is + returned. .. note:: If not separately noted, all functions that claim "Availability: Unix" are supported on Mac OS X, which builds on a Unix core. +* An "Availability: Unix" note means that this function is commonly found on + Unix systems. It does not make any claims about its existence on a specific + operating system. + +* If not separately noted, all functions that claim "Availability: Unix" are + supported on Mac OS X, which builds on a Unix core. + .. note:: All functions in this module raise :exc:`OSError` in the case of invalid or @@ -46,9 +54,9 @@ .. data:: name - The name of the operating system dependent module imported. The following names - have currently been registered: ``'posix'``, ``'nt'``, ``'mac'``, ``'os2'``, - ``'ce'``, ``'java'``. + The name of the operating system dependent module imported. The following + names have currently been registered: ``'posix'``, ``'nt'``, ``'mac'``, + ``'os2'``, ``'ce'``, ``'java'``. .. _os-filenames: Modified: python/branches/py3k/Doc/library/select.rst ============================================================================== --- python/branches/py3k/Doc/library/select.rst (original) +++ python/branches/py3k/Doc/library/select.rst Thu Dec 31 04:11:23 2009 @@ -45,7 +45,7 @@ :ref:`kqueue-objects` below for the methods supported by kqueue objects. -.. function:: kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ADD, fflags=0, data=0, udata=0) +.. function:: kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0) (Only supported on BSD.) Returns a kernel event object object; see section :ref:`kevent-objects` below for the methods supported by kqueue objects. Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Thu Dec 31 04:11:23 2009 @@ -2458,8 +2458,7 @@ .. attribute:: class.__bases__ - The tuple of base classes of a class object. If there are no base classes, this - will be an empty tuple. + The tuple of base classes of a class object. .. attribute:: class.__name__ Modified: python/branches/py3k/Doc/library/string.rst ============================================================================== --- python/branches/py3k/Doc/library/string.rst (original) +++ python/branches/py3k/Doc/library/string.rst Thu Dec 31 04:11:23 2009 @@ -86,6 +86,7 @@ you to create and customize your own string formatting behaviors using the same implementation as the built-in :meth:`format` method. + .. class:: Formatter The :class:`Formatter` class has the following public methods: @@ -470,6 +471,8 @@ Template strings ---------------- +.. versionadded:: 2.4 + Templates provide simpler string substitutions as described in :pep:`292`. Instead of the normal ``%``\ -based substitutions, Templates support ``$``\ -based substitutions, using the following rules: Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Thu Dec 31 04:11:23 2009 @@ -121,8 +121,6 @@ curses - Tests that use curses and will modify the terminal's state and output modes. - lib2to3 - Run the tests for 2to3 (They take a while.) - largefile - It is okay to run some test that may create huge files. These tests can take a long time and may consume >2GB of disk space temporarily. 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 Thu Dec 31 04:11:23 2009 @@ -195,32 +195,54 @@ if hasattr(posix, 'stat'): self.assertTrue(posix.stat(support.TESTFN)) - if hasattr(posix, 'chown'): - def test_chown(self): - # raise an OSError if the file does not exist - os.unlink(support.TESTFN) - self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1) - - # re-create the file - open(support.TESTFN, 'w').close() - if os.getuid() == 0: - try: - # Many linux distros have a nfsnobody user as MAX_UID-2 - # that makes a good test case for signedness issues. - # http://bugs.python.org/issue1747858 - # This part of the test only runs when run as root. - # Only scary people run their tests as root. - ent = pwd.getpwnam('nfsnobody') - posix.chown(support.TESTFN, ent.pw_uid, ent.pw_gid) - except KeyError: - pass - else: - # non-root cannot chown to root, raises OSError - self.assertRaises(OSError, posix.chown, - support.TESTFN, 0, 0) - - # test a successful chown call - posix.chown(support.TESTFN, os.getuid(), os.getgid()) + def _test_all_chown_common(self, chown_func, first_param): + """Common code for chown, fchown and lchown tests.""" + if os.getuid() == 0: + try: + # Many linux distros have a nfsnobody user as MAX_UID-2 + # that makes a good test case for signedness issues. + # http://bugs.python.org/issue1747858 + # This part of the test only runs when run as root. + # Only scary people run their tests as root. + ent = pwd.getpwnam('nfsnobody') + chown_func(first_param, ent.pw_uid, ent.pw_gid) + except KeyError: + pass + else: + # non-root cannot chown to root, raises OSError + self.assertRaises(OSError, chown_func, + first_param, 0, 0) + # test a successful chown call + chown_func(first_param, os.getuid(), os.getgid()) + + @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()") + def test_chown(self): + # raise an OSError if the file does not exist + os.unlink(support.TESTFN) + self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1) + + # re-create the file + open(support.TESTFN, 'w').close() + self._test_all_chown_common(posix.chown, support.TESTFN) + + @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()") + def test_fchown(self): + os.unlink(support.TESTFN) + + # re-create the file + test_file = open(support.TESTFN, 'w') + try: + fd = test_file.fileno() + self._test_all_chown_common(posix.fchown, fd) + finally: + test_file.close() + + @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()") + def test_lchown(self): + os.unlink(support.TESTFN) + # create a symlink + os.symlink('/tmp/dummy-symlink-target', support.TESTFN) + self._test_all_chown_common(posix.lchown, support.TESTFN) def test_chdir(self): if hasattr(posix, 'chdir'): Modified: python/branches/py3k/Modules/gcmodule.c ============================================================================== --- python/branches/py3k/Modules/gcmodule.c (original) +++ python/branches/py3k/Modules/gcmodule.c Thu Dec 31 04:11:23 2009 @@ -927,7 +927,7 @@ */ (void)handle_finalizers(&finalizers, old); - /* Clear free list only during the collection of the higest + /* Clear free list only during the collection of the highest * generation */ if (generation == NUM_GENERATIONS-1) { clear_freelists(); @@ -948,7 +948,7 @@ int i; Py_ssize_t n = 0; - /* Find the oldest generation (higest numbered) where the count + /* Find the oldest generation (highest numbered) where the count * exceeds the threshold. Objects in the that generation and * generations younger than it will be collected. */ for (i = NUM_GENERATIONS-1; i >= 0; i--) { Modified: python/branches/py3k/Modules/posixmodule.c ============================================================================== --- python/branches/py3k/Modules/posixmodule.c (original) +++ python/branches/py3k/Modules/posixmodule.c Thu Dec 31 04:11:23 2009 @@ -1988,9 +1988,10 @@ static PyObject * posix_fchown(PyObject *self, PyObject *args) { - int fd, uid, gid; + int fd; + long uid, gid; int res; - if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS res = fchown(fd, (uid_t) uid, (gid_t) gid); @@ -2012,9 +2013,9 @@ { PyObject *opath; char *path; - int uid, gid; + long uid, gid; int res; - if (!PyArg_ParseTuple(args, "O&ii:lchown", + if (!PyArg_ParseTuple(args, "O&ll:lchown", PyUnicode_FSConverter, &opath, &uid, &gid)) return NULL; Modified: python/branches/py3k/Modules/selectmodule.c ============================================================================== --- python/branches/py3k/Modules/selectmodule.c (original) +++ python/branches/py3k/Modules/selectmodule.c Thu Dec 31 04:11:23 2009 @@ -1166,7 +1166,7 @@ #endif PyDoc_STRVAR(kqueue_event_doc, -"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ADD, fflags=0, data=0, udata=0)\n\ +"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\ \n\ This object is the equivalent of the struct kevent for the C API.\n\ \n\ Modified: python/branches/py3k/PC/msvcrtmodule.c ============================================================================== --- python/branches/py3k/PC/msvcrtmodule.c (original) +++ python/branches/py3k/PC/msvcrtmodule.c Thu Dec 31 04:11:23 2009 @@ -45,6 +45,12 @@ return Py_None; } +PyDoc_STRVAR(heapmin_doc, +"heapmin() -> None\n\ +\n\ +Force the malloc() heap to clean itself up and return unused blocks\n\ +to the operating system. On failure, this raises IOError."); + // Perform locking operations on a C runtime file descriptor. static PyObject * msvcrt_locking(PyObject *self, PyObject *args) @@ -67,6 +73,17 @@ return Py_None; } +PyDoc_STRVAR(locking_doc, +"locking(fd, mode, nbytes) -> None\n\ +\n\ +Lock part of a file based on file descriptor fd from the C runtime.\n\ +Raises IOError on failure. The locked region of the file extends from\n\ +the current file position for nbytes bytes, and may continue beyond\n\ +the end of the file. mode must be one of the LK_* constants listed\n\ +below. Multiple regions in a file may be locked at the same time, but\n\ +may not overlap. Adjacent regions are not merged; they must be unlocked\n\ +individually."); + // Set the file translation mode for a C runtime file descriptor. static PyObject * msvcrt_setmode(PyObject *self, PyObject *args) @@ -83,6 +100,13 @@ return PyLong_FromLong(flags); } +PyDoc_STRVAR(setmode_doc, +"setmode(fd, mode) -> Previous mode\n\ +\n\ +Set the line-end translation mode for the file descriptor fd. To set\n\ +it to text mode, flags should be os.O_TEXT; for binary, it should be\n\ +os.O_BINARY."); + // Convert an OS file handle to a C runtime file descriptor. static PyObject * msvcrt_open_osfhandle(PyObject *self, PyObject *args) @@ -101,6 +125,14 @@ return PyLong_FromLong(fd); } +PyDoc_STRVAR(open_osfhandle_doc, +"open_osfhandle(handle, flags) -> file descriptor\n\ +\n\ +Create a C runtime file descriptor from the file handle handle. The\n\ +flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY,\n\ +and os.O_TEXT. The returned file descriptor may be used as a parameter\n\ +to os.fdopen() to create a file object."); + // Convert a C runtime file descriptor to an OS file handle. static PyObject * msvcrt_get_osfhandle(PyObject *self, PyObject *args) @@ -121,6 +153,12 @@ return PyLong_FromVoidPtr((void*)handle); } +PyDoc_STRVAR(get_osfhandle_doc, +"get_osfhandle(fd) -> file handle\n\ +\n\ +Return the file handle for the file descriptor fd. Raises IOError\n\ +if fd is not recognized."); + /* Console I/O */ static PyObject * @@ -135,6 +173,11 @@ return PyLong_FromLong(ok); } +PyDoc_STRVAR(kbhit_doc, +"kbhit() -> bool\n\ +\n\ +Return true if a keypress is waiting to be read."); + static PyObject * msvcrt_getch(PyObject *self, PyObject *args) { @@ -151,6 +194,16 @@ return PyBytes_FromStringAndSize(s, 1); } +PyDoc_STRVAR(getch_doc, +"getch() -> key character\n\ +\n\ +Read a keypress and return the resulting character. Nothing is echoed to\n\ +the console. This call will block if a keypress is not already\n\ +available, but will not wait for Enter to be pressed. If the pressed key\n\ +was a special function key, this will return '\\000' or '\\xe0'; the next\n\ +call will return the keycode. The Control-C keypress cannot be read with\n\ +this function."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_getwch(PyObject *self, PyObject *args) @@ -167,6 +220,11 @@ u[0] = ch; return PyUnicode_FromUnicode(u, 1); } + +PyDoc_STRVAR(getwch_doc, +"getwch() -> Unicode key character\n\ +\n\ +Wide char variant of getch(), returning a Unicode value."); #endif static PyObject * @@ -185,6 +243,12 @@ return PyBytes_FromStringAndSize(s, 1); } +PyDoc_STRVAR(getche_doc, +"getche() -> key character\n\ +\n\ +Similar to getch(), but the keypress will be echoed if it represents\n\ +a printable character."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_getwche(PyObject *self, PyObject *args) @@ -201,6 +265,11 @@ s[0] = ch; return PyUnicode_FromUnicode(s, 1); } + +PyDoc_STRVAR(getwche_doc, +"getwche() -> Unicode key character\n\ +\n\ +Wide char variant of getche(), returning a Unicode value."); #endif static PyObject * @@ -216,6 +285,11 @@ return Py_None; } +PyDoc_STRVAR(putch_doc, +"putch(char) -> None\n\ +\n\ +Print the character char to the console without buffering."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_putwch(PyObject *self, PyObject *args) @@ -229,6 +303,11 @@ Py_RETURN_NONE; } + +PyDoc_STRVAR(putwch_doc, +"putwch(unicode_char) -> None\n\ +\n\ +Wide char variant of putch(), accepting a Unicode value."); #endif static PyObject * @@ -245,6 +324,12 @@ return Py_None; } +PyDoc_STRVAR(ungetch_doc, +"ungetch(char) -> None\n\ +\n\ +Cause the character char to be \"pushed back\" into the console buffer;\n\ +it will be the next character read by getch() or getche()."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_ungetwch(PyObject *self, PyObject *args) @@ -259,6 +344,11 @@ Py_INCREF(Py_None); return Py_None; } + +PyDoc_STRVAR(ungetwch_doc, +"ungetwch(unicode_char) -> None\n\ +\n\ +Wide char variant of ungetch(), accepting a Unicode value."); #endif static void @@ -332,16 +422,16 @@ /* List of functions exported by this module */ static struct PyMethodDef msvcrt_functions[] = { - {"heapmin", msvcrt_heapmin, METH_VARARGS}, - {"locking", msvcrt_locking, METH_VARARGS}, - {"setmode", msvcrt_setmode, METH_VARARGS}, - {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS}, - {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS}, - {"kbhit", msvcrt_kbhit, METH_VARARGS}, - {"getch", msvcrt_getch, METH_VARARGS}, - {"getche", msvcrt_getche, METH_VARARGS}, - {"putch", msvcrt_putch, METH_VARARGS}, - {"ungetch", msvcrt_ungetch, METH_VARARGS}, + {"heapmin", msvcrt_heapmin, METH_VARARGS, heapmin_doc}, + {"locking", msvcrt_locking, METH_VARARGS, locking_doc}, + {"setmode", msvcrt_setmode, METH_VARARGS, setmode_doc}, + {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS, open_osfhandle_doc}, + {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS, get_osfhandle_doc}, + {"kbhit", msvcrt_kbhit, METH_VARARGS, kbhit_doc}, + {"getch", msvcrt_getch, METH_VARARGS, getch_doc}, + {"getche", msvcrt_getche, METH_VARARGS, getche_doc}, + {"putch", msvcrt_putch, METH_VARARGS, putch_doc}, + {"ungetch", msvcrt_ungetch, METH_VARARGS, ungetch_doc}, {"SetErrorMode", seterrormode, METH_VARARGS}, #ifdef _DEBUG {"CrtSetReportFile", msvcrt_setreportfile, METH_VARARGS}, @@ -349,10 +439,10 @@ {"set_error_mode", msvcrt_seterrormode, METH_VARARGS}, #endif #ifdef _WCONIO_DEFINED - {"getwch", msvcrt_getwch, METH_VARARGS}, - {"getwche", msvcrt_getwche, METH_VARARGS}, - {"putwch", msvcrt_putwch, METH_VARARGS}, - {"ungetwch", msvcrt_ungetwch, METH_VARARGS}, + {"getwch", msvcrt_getwch, METH_VARARGS, getwch_doc}, + {"getwche", msvcrt_getwche, METH_VARARGS, getwche_doc}, + {"putwch", msvcrt_putwch, METH_VARARGS, putwch_doc}, + {"ungetwch", msvcrt_ungetwch, METH_VARARGS, ungetwch_doc}, #endif {NULL, NULL} }; From python-checkins at python.org Thu Dec 31 04:16:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 31 Dec 2009 03:16:47 -0000 Subject: [Python-checkins] r77168 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Thu Dec 31 04:16:47 2009 New Revision: 77168 Log: Blocked revisions 76912,76996,77030,77037 via svnmerge ........ r76912 | senthil.kumaran | 2009-12-20 01:29:31 -0600 (Sun, 20 Dec 2009) | 3 lines Document the headers parameter for set_tunnel. ........ r76996 | tarek.ziade | 2009-12-21 17:31:55 -0600 (Mon, 21 Dec 2009) | 1 line backported r76993 and r76994 so the trunk behaves the same way with MSVC Manifest files editing ........ r77030 | ronald.oussoren | 2009-12-24 07:30:42 -0600 (Thu, 24 Dec 2009) | 5 lines An update to the script that's used to build the binary installer: don't install files in /usr/local by default. Users can still choose to install files into /usr/local, but by default we'll only install files in /Library/Framework/Python.framework and /Applications/Python X.Y/ ........ r77037 | ronald.oussoren | 2009-12-24 08:50:35 -0600 (Thu, 24 Dec 2009) | 2 lines Unittests and news items for the patch in r77026. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Dec 31 04:17:18 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 31 Dec 2009 03:17:18 -0000 Subject: [Python-checkins] r77169 - in python/trunk: Misc/NEWS configure configure.in setup.py Message-ID: Author: benjamin.peterson Date: Thu Dec 31 04:17:18 2009 New Revision: 77169 Log: add a --with-system-expat option to build pyexpat against the system's lib #7609 Modified: python/trunk/Misc/NEWS python/trunk/configure python/trunk/configure.in python/trunk/setup.py Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Dec 31 04:17:18 2009 @@ -93,6 +93,10 @@ Build ----- +- Issue #7609: Add a --with-system-expat option that causes the system's expat + library to be used for the pyexpat module instead of the one included with + Python. + - Issue #7589: Only build the nis module when the correct header files are found. Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Thu Dec 31 04:17:18 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76644 . +# From configure.in Revision: 77031 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -1348,6 +1348,8 @@ --with-suffix=.exe set executable suffix --with-pydebug build with Py_DEBUG defined --with-libs='lib1 ...' link against additional libs + --with-system-expat build pyexpat module using an installed expat + library --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 @@ -3857,7 +3859,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f -r conftest* +rm -f conftest* @@ -5410,7 +5412,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -5431,7 +5433,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -6529,7 +6531,7 @@ fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -7059,7 +7061,7 @@ else ac_cv_type_uid_t=no fi -rm -f -r conftest* +rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -15513,6 +15515,19 @@ fi +# Check for use of the system expat library +{ echo "$as_me:$LINENO: checking for --with-system-expat" >&5 +echo $ECHO_N "checking for --with-system-expat... $ECHO_C" >&6; } + +# Check whether --with-system_expat was given. +if test "${with_system_expat+set}" = set; then + withval=$with_system_expat; +fi + + +{ echo "$as_me:$LINENO: result: $with_system_expat" >&5 +echo "${ECHO_T}$with_system_expat" >&6; } + # Check for use of the system libffi library { echo "$as_me:$LINENO: checking for --with-system-ffi" >&5 echo $ECHO_N "checking for --with-system-ffi... $ECHO_C" >&6; } @@ -15719,7 +15734,7 @@ else unistd_defines_pthreads=no fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -17333,7 +17348,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f -r conftest* +rm -f conftest* ;; kame) @@ -17356,7 +17371,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-glibc) @@ -17377,7 +17392,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-inet6) @@ -17415,7 +17430,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; v6d) @@ -17438,7 +17453,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f -r conftest* +rm -f conftest* ;; zeta) @@ -17460,7 +17475,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; esac @@ -26003,7 +26018,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -26022,7 +26037,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi @@ -26292,7 +26307,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Thu Dec 31 04:17:18 2009 @@ -1964,6 +1964,13 @@ ], [AC_MSG_RESULT(no)]) +# Check for use of the system expat library +AC_MSG_CHECKING(for --with-system-expat) +AC_ARG_WITH(system_expat, + AC_HELP_STRING(--with-system-expat, build pyexpat module using an installed expat library)) + +AC_MSG_RESULT($with_system_expat) + # Check for use of the system libffi library AC_MSG_CHECKING(for --with-system-ffi) AC_ARG_WITH(system_ffi, Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Thu Dec 31 04:17:18 2009 @@ -1220,19 +1220,26 @@ # # More information on Expat can be found at www.libexpat.org. # - expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat') - define_macros = [ - ('HAVE_EXPAT_CONFIG_H', '1'), - ] + if '--with-system-expat' in sysconfig.get_config_var("CONFIG_ARGS"): + expat_inc = [] + define_macros = [] + expat_lib = ['expat'] + expat_sources = [] + else: + expat_inc = [os.path.join(os.getcwd(), srcdir, 'Modules', 'expat')] + define_macros = [ + ('HAVE_EXPAT_CONFIG_H', '1'), + ] + expat_lib = [] + expat_sources = ['expat/xmlparse.c', + 'expat/xmlrole.c', + 'expat/xmltok.c'] exts.append(Extension('pyexpat', define_macros = define_macros, - include_dirs = [expatinc], - sources = ['pyexpat.c', - 'expat/xmlparse.c', - 'expat/xmlrole.c', - 'expat/xmltok.c', - ], + include_dirs = expat_inc, + libraries = expat_lib, + sources = ['pyexpat.c'] + expat_sources )) # Fredrik Lundh's cElementTree module. Note that this also @@ -1242,7 +1249,8 @@ define_macros.append(('USE_PYEXPAT_CAPI', None)) exts.append(Extension('_elementtree', define_macros = define_macros, - include_dirs = [expatinc], + include_dirs = expat_inc, + libraries = expat_lib, sources = ['_elementtree.c'], )) else: From python-checkins at python.org Thu Dec 31 04:23:11 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 31 Dec 2009 03:23:11 -0000 Subject: [Python-checkins] r77170 - in python/branches/py3k: Misc/NEWS configure configure.in setup.py Message-ID: Author: benjamin.peterson Date: Thu Dec 31 04:23:10 2009 New Revision: 77170 Log: Merged revisions 77169 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77169 | benjamin.peterson | 2009-12-30 21:17:18 -0600 (Wed, 30 Dec 2009) | 2 lines add a --with-system-expat option to build pyexpat against the system's lib #7609 ........ Modified: python/branches/py3k/ (props changed) 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 Dec 31 04:23:10 2009 @@ -514,6 +514,10 @@ Build ----- +- Issue #7609: Add a --with-system-expat option that causes the system's expat + library to be used for the pyexpat module instead of the one included with + Python. + - Issue #7589: Only build the nis module when the correct header files are found. Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Thu Dec 31 04:23:10 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76815 . +# From configure.in Revision: 77032 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -1342,6 +1342,8 @@ --with-suffix=.exe set executable suffix --with-pydebug build with Py_DEBUG defined --with-libs='lib1 ...' link against additional libs + --with-system-expat build pyexpat module using an installed expat + library --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 @@ -3792,7 +3794,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f -r conftest* +rm -f conftest* @@ -5335,7 +5337,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -5356,7 +5358,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -6454,7 +6456,7 @@ fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -6984,7 +6986,7 @@ else ac_cv_type_uid_t=no fi -rm -f -r conftest* +rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -15320,6 +15322,19 @@ fi +# Check for use of the system expat library +{ echo "$as_me:$LINENO: checking for --with-system-expat" >&5 +echo $ECHO_N "checking for --with-system-expat... $ECHO_C" >&6; } + +# Check whether --with-system_expat was given. +if test "${with_system_expat+set}" = set; then + withval=$with_system_expat; +fi + + +{ echo "$as_me:$LINENO: result: $with_system_expat" >&5 +echo "${ECHO_T}$with_system_expat" >&6; } + # Check for use of the system libffi library { echo "$as_me:$LINENO: checking for --with-system-ffi" >&5 echo $ECHO_N "checking for --with-system-ffi... $ECHO_C" >&6; } @@ -15526,7 +15541,7 @@ else unistd_defines_pthreads=no fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -16824,7 +16839,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f -r conftest* +rm -f conftest* ;; kame) @@ -16847,7 +16862,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-glibc) @@ -16868,7 +16883,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-inet6) @@ -16906,7 +16921,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; v6d) @@ -16929,7 +16944,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f -r conftest* +rm -f conftest* ;; zeta) @@ -16951,7 +16966,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; esac @@ -25292,7 +25307,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -25311,7 +25326,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi @@ -25581,7 +25596,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Thu Dec 31 04:23:10 2009 @@ -1856,6 +1856,13 @@ ], [AC_MSG_RESULT(no)]) +# Check for use of the system expat library +AC_MSG_CHECKING(for --with-system-expat) +AC_ARG_WITH(system_expat, + AC_HELP_STRING(--with-system-expat, build pyexpat module using an installed expat library)) + +AC_MSG_RESULT($with_system_expat) + # Check for use of the system libffi library AC_MSG_CHECKING(for --with-system-ffi) AC_ARG_WITH(system_ffi, Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Thu Dec 31 04:23:10 2009 @@ -1104,19 +1104,26 @@ # # More information on Expat can be found at www.libexpat.org. # - expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat') - define_macros = [ - ('HAVE_EXPAT_CONFIG_H', '1'), - ] + if '--with-system-expat' in sysconfig.get_config_var("CONFIG_ARGS"): + expat_inc = [] + define_macros = [] + expat_lib = ['expat'] + expat_sources = [] + else: + expat_inc = [os.path.join(os.getcwd(), srcdir, 'Modules', 'expat')] + define_macros = [ + ('HAVE_EXPAT_CONFIG_H', '1'), + ] + expat_lib = [] + expat_sources = ['expat/xmlparse.c', + 'expat/xmlrole.c', + 'expat/xmltok.c'] exts.append(Extension('pyexpat', define_macros = define_macros, - include_dirs = [expatinc], - sources = ['pyexpat.c', - 'expat/xmlparse.c', - 'expat/xmlrole.c', - 'expat/xmltok.c', - ], + include_dirs = expat_inc, + libraries = expat_lib, + sources = ['pyexpat.c'] + expat_sources )) # Fredrik Lundh's cElementTree module. Note that this also @@ -1126,7 +1133,8 @@ define_macros.append(('USE_PYEXPAT_CAPI', None)) exts.append(Extension('_elementtree', define_macros = define_macros, - include_dirs = [expatinc], + include_dirs = expat_inc, + libraries = expat_lib, sources = ['_elementtree.c'], )) else: From python-checkins at python.org Thu Dec 31 04:30:26 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 31 Dec 2009 03:30:26 -0000 Subject: [Python-checkins] r77171 - in python/branches/release31-maint: Doc/faq/design.rst Doc/library/2to3.rst Doc/library/ctypes.rst Doc/library/logging.rst Doc/library/msvcrt.rst Doc/library/optparse.rst Doc/library/os.rst Doc/library/select.rst Doc/library/stdtypes.rst Doc/library/string.rst Lib/test/regrtest.py Lib/test/test_posix.py Modules/gcmodule.c Modules/posixmodule.c Modules/selectmodule.c PC/msvcrtmodule.c Message-ID: Author: benjamin.peterson Date: Thu Dec 31 04:30:26 2009 New Revision: 77171 Log: Merged revisions 77167 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77167 | benjamin.peterson | 2009-12-30 21:11:23 -0600 (Wed, 30 Dec 2009) | 61 lines Merged revisions 76847,76851,76869,76882,76891-76892,76924,77007,77070,77092,77096,77120,77126,77155 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76847 | benjamin.peterson | 2009-12-14 21:25:27 -0600 (Mon, 14 Dec 2009) | 1 line adverb ........ r76851 | benjamin.peterson | 2009-12-15 21:28:52 -0600 (Tue, 15 Dec 2009) | 1 line remove lib2to3 resource ........ r76869 | vinay.sajip | 2009-12-17 08:52:00 -0600 (Thu, 17 Dec 2009) | 1 line Issue #7529: logging: Minor correction to documentation. ........ r76882 | georg.brandl | 2009-12-19 11:30:28 -0600 (Sat, 19 Dec 2009) | 1 line #7527: use standard versionadded tags. ........ r76891 | georg.brandl | 2009-12-19 12:16:31 -0600 (Sat, 19 Dec 2009) | 1 line #7479: add note about function availability on Unices. ........ r76892 | georg.brandl | 2009-12-19 12:20:18 -0600 (Sat, 19 Dec 2009) | 1 line #7480: remove tautology. ........ r76924 | georg.brandl | 2009-12-20 08:28:05 -0600 (Sun, 20 Dec 2009) | 1 line Small indentation fix. ........ r77007 | gregory.p.smith | 2009-12-23 03:31:11 -0600 (Wed, 23 Dec 2009) | 3 lines Fix possible integer overflow in lchown and fchown functions. For issue1747858. ........ r77070 | amaury.forgeotdarc | 2009-12-27 14:06:44 -0600 (Sun, 27 Dec 2009) | 2 lines Fix a typo in comment ........ r77092 | georg.brandl | 2009-12-28 02:48:24 -0600 (Mon, 28 Dec 2009) | 1 line #7404: remove reference to non-existing example files. ........ r77096 | benjamin.peterson | 2009-12-28 14:51:17 -0600 (Mon, 28 Dec 2009) | 1 line document new fix_callable behavior ........ r77120 | georg.brandl | 2009-12-29 15:09:17 -0600 (Tue, 29 Dec 2009) | 1 line #7595: fix typo in argument default constant. ........ r77126 | amaury.forgeotdarc | 2009-12-29 17:06:17 -0600 (Tue, 29 Dec 2009) | 2 lines #7579: Add docstrings to the msvcrt module ........ r77155 | georg.brandl | 2009-12-30 13:03:00 -0600 (Wed, 30 Dec 2009) | 1 line We only support Windows NT derivatives now. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/faq/design.rst python/branches/release31-maint/Doc/library/2to3.rst python/branches/release31-maint/Doc/library/ctypes.rst python/branches/release31-maint/Doc/library/logging.rst python/branches/release31-maint/Doc/library/msvcrt.rst python/branches/release31-maint/Doc/library/optparse.rst python/branches/release31-maint/Doc/library/os.rst python/branches/release31-maint/Doc/library/select.rst python/branches/release31-maint/Doc/library/stdtypes.rst python/branches/release31-maint/Doc/library/string.rst python/branches/release31-maint/Lib/test/regrtest.py python/branches/release31-maint/Lib/test/test_posix.py python/branches/release31-maint/Modules/gcmodule.c python/branches/release31-maint/Modules/posixmodule.c python/branches/release31-maint/Modules/selectmodule.c python/branches/release31-maint/PC/msvcrtmodule.c Modified: python/branches/release31-maint/Doc/faq/design.rst ============================================================================== --- python/branches/release31-maint/Doc/faq/design.rst (original) +++ python/branches/release31-maint/Doc/faq/design.rst Thu Dec 31 04:30:26 2009 @@ -818,7 +818,7 @@ looks like this:: with obj: - a = 1 # equivalent to obj.a = 1 + a = 1 # equivalent to obj.a = 1 total = total + 1 # obj.total = obj.total + 1 In Python, such a construct would be ambiguous. Modified: python/branches/release31-maint/Doc/library/2to3.rst ============================================================================== --- python/branches/release31-maint/Doc/library/2to3.rst (original) +++ python/branches/release31-maint/Doc/library/2to3.rst Thu Dec 31 04:30:26 2009 @@ -122,7 +122,8 @@ .. 2to3fixer:: callable - Converts ``callable(x)`` to ``hasattr(x, "__call_")``. + Converts ``callable(x)`` to ``isinstance(x, collections.Callable)``, adding + an import to :mod:`collections` if needed. .. 2to3fixer:: dict Modified: python/branches/release31-maint/Doc/library/ctypes.rst ============================================================================== --- python/branches/release31-maint/Doc/library/ctypes.rst (original) +++ python/branches/release31-maint/Doc/library/ctypes.rst Thu Dec 31 04:30:26 2009 @@ -1005,7 +1005,7 @@ >>> It is funny to see that on linux the sort function seems to work much more -efficient, it is doing less comparisons:: +efficiently, it is doing less comparisons:: >>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +LINUX py_cmp_func 5 1 Modified: python/branches/release31-maint/Doc/library/logging.rst ============================================================================== --- python/branches/release31-maint/Doc/library/logging.rst (original) +++ python/branches/release31-maint/Doc/library/logging.rst Thu Dec 31 04:30:26 2009 @@ -1611,6 +1611,8 @@ and :meth:`flush` methods). +.. currentmodule:: logging + .. class:: StreamHandler(stream=None) Returns a new instance of the :class:`StreamHandler` class. If *stream* is Modified: python/branches/release31-maint/Doc/library/msvcrt.rst ============================================================================== --- python/branches/release31-maint/Doc/library/msvcrt.rst (original) +++ python/branches/release31-maint/Doc/library/msvcrt.rst Thu Dec 31 04:30:26 2009 @@ -144,6 +144,4 @@ .. function:: heapmin() Force the :cfunc:`malloc` heap to clean itself up and return unused blocks to - the operating system. This only works on Windows NT. On failure, this raises - :exc:`IOError`. - + the operating system. On failure, this raises :exc:`IOError`. Modified: python/branches/release31-maint/Doc/library/optparse.rst ============================================================================== --- python/branches/release31-maint/Doc/library/optparse.rst (original) +++ python/branches/release31-maint/Doc/library/optparse.rst Thu Dec 31 04:30:26 2009 @@ -153,9 +153,7 @@ an option that must be supplied on the command-line; note that the phrase "required option" is self-contradictory in English. :mod:`optparse` doesn't prevent you from implementing required options, but doesn't give you much - help at it either. See ``examples/required_1.py`` and - ``examples/required_2.py`` in the :mod:`optparse` source distribution for two - ways to implement required options with :mod:`optparse`. + help at it either. For example, consider this hypothetical command-line:: Modified: python/branches/release31-maint/Doc/library/os.rst ============================================================================== --- python/branches/release31-maint/Doc/library/os.rst (original) +++ python/branches/release31-maint/Doc/library/os.rst Thu Dec 31 04:30:26 2009 @@ -13,26 +13,34 @@ module, and for high-level file and directory handling see the :mod:`shutil` module. -The design of all built-in operating system dependent modules of Python is such -that as long as the same functionality is available, it uses the same interface; -for example, the function ``os.stat(path)`` returns stat information about -*path* in the same format (which happens to have originated with the POSIX -interface). +Notes on the availability of these functions: -Extensions peculiar to a particular operating system are also available through -the :mod:`os` module, but using them is of course a threat to portability! - -.. note:: - - All functions accepting path or file names accept both bytes and string - objects, and result in an object of the same type, if a path or file name is - returned. +* The design of all built-in operating system dependent modules of Python is + such that as long as the same functionality is available, it uses the same + interface; for example, the function ``os.stat(path)`` returns stat + information about *path* in the same format (which happens to have originated + with the POSIX interface). + +* Extensions peculiar to a particular operating system are also available + through the :mod:`os` module, but using them is of course a threat to + portability. + +* All functions accepting path or file names accept both bytes and string + objects, and result in an object of the same type, if a path or file name is + returned. .. note:: If not separately noted, all functions that claim "Availability: Unix" are supported on Mac OS X, which builds on a Unix core. +* An "Availability: Unix" note means that this function is commonly found on + Unix systems. It does not make any claims about its existence on a specific + operating system. + +* If not separately noted, all functions that claim "Availability: Unix" are + supported on Mac OS X, which builds on a Unix core. + .. note:: All functions in this module raise :exc:`OSError` in the case of invalid or @@ -46,9 +54,9 @@ .. data:: name - The name of the operating system dependent module imported. The following names - have currently been registered: ``'posix'``, ``'nt'``, ``'mac'``, ``'os2'``, - ``'ce'``, ``'java'``. + The name of the operating system dependent module imported. The following + names have currently been registered: ``'posix'``, ``'nt'``, ``'mac'``, + ``'os2'``, ``'ce'``, ``'java'``. .. _os-filenames: Modified: python/branches/release31-maint/Doc/library/select.rst ============================================================================== --- python/branches/release31-maint/Doc/library/select.rst (original) +++ python/branches/release31-maint/Doc/library/select.rst Thu Dec 31 04:30:26 2009 @@ -46,7 +46,7 @@ :ref:`kqueue-objects` below for the methods supported by kqueue objects. -.. function:: kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ADD, fflags=0, data=0, udata=0) +.. function:: kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0) (Only supported on BSD.) Returns a kernel event object object; see section :ref:`kevent-objects` below for the methods supported by kqueue objects. Modified: python/branches/release31-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release31-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release31-maint/Doc/library/stdtypes.rst Thu Dec 31 04:30:26 2009 @@ -2454,8 +2454,7 @@ .. attribute:: class.__bases__ - The tuple of base classes of a class object. If there are no base classes, this - will be an empty tuple. + The tuple of base classes of a class object. .. attribute:: class.__name__ Modified: python/branches/release31-maint/Doc/library/string.rst ============================================================================== --- python/branches/release31-maint/Doc/library/string.rst (original) +++ python/branches/release31-maint/Doc/library/string.rst Thu Dec 31 04:30:26 2009 @@ -86,6 +86,7 @@ you to create and customize your own string formatting behaviors using the same implementation as the built-in :meth:`format` method. + .. class:: Formatter The :class:`Formatter` class has the following public methods: @@ -470,6 +471,8 @@ Template strings ---------------- +.. versionadded:: 2.4 + Templates provide simpler string substitutions as described in :pep:`292`. Instead of the normal ``%``\ -based substitutions, Templates support ``$``\ -based substitutions, using the following rules: Modified: python/branches/release31-maint/Lib/test/regrtest.py ============================================================================== --- python/branches/release31-maint/Lib/test/regrtest.py (original) +++ python/branches/release31-maint/Lib/test/regrtest.py Thu Dec 31 04:30:26 2009 @@ -105,8 +105,6 @@ curses - Tests that use curses and will modify the terminal's state and output modes. - lib2to3 - Run the tests for 2to3 (They take a while.) - largefile - It is okay to run some test that may create huge files. These tests can take a long time and may consume >2GB of disk space temporarily. Modified: python/branches/release31-maint/Lib/test/test_posix.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_posix.py (original) +++ python/branches/release31-maint/Lib/test/test_posix.py Thu Dec 31 04:30:26 2009 @@ -131,32 +131,54 @@ if hasattr(posix, 'stat'): self.assertTrue(posix.stat(support.TESTFN)) - if hasattr(posix, 'chown'): - def test_chown(self): - # raise an OSError if the file does not exist - os.unlink(support.TESTFN) - self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1) - - # re-create the file - open(support.TESTFN, 'w').close() - if os.getuid() == 0: - try: - # Many linux distros have a nfsnobody user as MAX_UID-2 - # that makes a good test case for signedness issues. - # http://bugs.python.org/issue1747858 - # This part of the test only runs when run as root. - # Only scary people run their tests as root. - ent = pwd.getpwnam('nfsnobody') - posix.chown(support.TESTFN, ent.pw_uid, ent.pw_gid) - except KeyError: - pass - else: - # non-root cannot chown to root, raises OSError - self.assertRaises(OSError, posix.chown, - support.TESTFN, 0, 0) - - # test a successful chown call - posix.chown(support.TESTFN, os.getuid(), os.getgid()) + def _test_all_chown_common(self, chown_func, first_param): + """Common code for chown, fchown and lchown tests.""" + if os.getuid() == 0: + try: + # Many linux distros have a nfsnobody user as MAX_UID-2 + # that makes a good test case for signedness issues. + # http://bugs.python.org/issue1747858 + # This part of the test only runs when run as root. + # Only scary people run their tests as root. + ent = pwd.getpwnam('nfsnobody') + chown_func(first_param, ent.pw_uid, ent.pw_gid) + except KeyError: + pass + else: + # non-root cannot chown to root, raises OSError + self.assertRaises(OSError, chown_func, + first_param, 0, 0) + # test a successful chown call + chown_func(first_param, os.getuid(), os.getgid()) + + @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()") + def test_chown(self): + # raise an OSError if the file does not exist + os.unlink(support.TESTFN) + self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1) + + # re-create the file + open(support.TESTFN, 'w').close() + self._test_all_chown_common(posix.chown, support.TESTFN) + + @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()") + def test_fchown(self): + os.unlink(support.TESTFN) + + # re-create the file + test_file = open(support.TESTFN, 'w') + try: + fd = test_file.fileno() + self._test_all_chown_common(posix.fchown, fd) + finally: + test_file.close() + + @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()") + def test_lchown(self): + os.unlink(support.TESTFN) + # create a symlink + os.symlink('/tmp/dummy-symlink-target', support.TESTFN) + self._test_all_chown_common(posix.lchown, support.TESTFN) def test_chdir(self): if hasattr(posix, 'chdir'): Modified: python/branches/release31-maint/Modules/gcmodule.c ============================================================================== --- python/branches/release31-maint/Modules/gcmodule.c (original) +++ python/branches/release31-maint/Modules/gcmodule.c Thu Dec 31 04:30:26 2009 @@ -927,7 +927,7 @@ */ (void)handle_finalizers(&finalizers, old); - /* Clear free list only during the collection of the higest + /* Clear free list only during the collection of the highest * generation */ if (generation == NUM_GENERATIONS-1) { clear_freelists(); @@ -948,7 +948,7 @@ int i; Py_ssize_t n = 0; - /* Find the oldest generation (higest numbered) where the count + /* Find the oldest generation (highest numbered) where the count * exceeds the threshold. Objects in the that generation and * generations younger than it will be collected. */ for (i = NUM_GENERATIONS-1; i >= 0; i--) { Modified: python/branches/release31-maint/Modules/posixmodule.c ============================================================================== --- python/branches/release31-maint/Modules/posixmodule.c (original) +++ python/branches/release31-maint/Modules/posixmodule.c Thu Dec 31 04:30:26 2009 @@ -2088,9 +2088,10 @@ static PyObject * posix_fchown(PyObject *self, PyObject *args) { - int fd, uid, gid; + int fd; + long uid, gid; int res; - if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS res = fchown(fd, (uid_t) uid, (gid_t) gid); @@ -2112,9 +2113,9 @@ { PyObject *opath; char *path; - int uid, gid; + long uid, gid; int res; - if (!PyArg_ParseTuple(args, "O&ii:lchown", + if (!PyArg_ParseTuple(args, "O&ll:lchown", PyUnicode_FSConverter, &opath, &uid, &gid)) return NULL; Modified: python/branches/release31-maint/Modules/selectmodule.c ============================================================================== --- python/branches/release31-maint/Modules/selectmodule.c (original) +++ python/branches/release31-maint/Modules/selectmodule.c Thu Dec 31 04:30:26 2009 @@ -1166,7 +1166,7 @@ #endif PyDoc_STRVAR(kqueue_event_doc, -"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_ADD, fflags=0, data=0, udata=0)\n\ +"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\ \n\ This object is the equivalent of the struct kevent for the C API.\n\ \n\ Modified: python/branches/release31-maint/PC/msvcrtmodule.c ============================================================================== --- python/branches/release31-maint/PC/msvcrtmodule.c (original) +++ python/branches/release31-maint/PC/msvcrtmodule.c Thu Dec 31 04:30:26 2009 @@ -45,6 +45,12 @@ return Py_None; } +PyDoc_STRVAR(heapmin_doc, +"heapmin() -> None\n\ +\n\ +Force the malloc() heap to clean itself up and return unused blocks\n\ +to the operating system. On failure, this raises IOError."); + // Perform locking operations on a C runtime file descriptor. static PyObject * msvcrt_locking(PyObject *self, PyObject *args) @@ -67,6 +73,17 @@ return Py_None; } +PyDoc_STRVAR(locking_doc, +"locking(fd, mode, nbytes) -> None\n\ +\n\ +Lock part of a file based on file descriptor fd from the C runtime.\n\ +Raises IOError on failure. The locked region of the file extends from\n\ +the current file position for nbytes bytes, and may continue beyond\n\ +the end of the file. mode must be one of the LK_* constants listed\n\ +below. Multiple regions in a file may be locked at the same time, but\n\ +may not overlap. Adjacent regions are not merged; they must be unlocked\n\ +individually."); + // Set the file translation mode for a C runtime file descriptor. static PyObject * msvcrt_setmode(PyObject *self, PyObject *args) @@ -83,6 +100,13 @@ return PyLong_FromLong(flags); } +PyDoc_STRVAR(setmode_doc, +"setmode(fd, mode) -> Previous mode\n\ +\n\ +Set the line-end translation mode for the file descriptor fd. To set\n\ +it to text mode, flags should be os.O_TEXT; for binary, it should be\n\ +os.O_BINARY."); + // Convert an OS file handle to a C runtime file descriptor. static PyObject * msvcrt_open_osfhandle(PyObject *self, PyObject *args) @@ -101,6 +125,14 @@ return PyLong_FromLong(fd); } +PyDoc_STRVAR(open_osfhandle_doc, +"open_osfhandle(handle, flags) -> file descriptor\n\ +\n\ +Create a C runtime file descriptor from the file handle handle. The\n\ +flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY,\n\ +and os.O_TEXT. The returned file descriptor may be used as a parameter\n\ +to os.fdopen() to create a file object."); + // Convert a C runtime file descriptor to an OS file handle. static PyObject * msvcrt_get_osfhandle(PyObject *self, PyObject *args) @@ -121,6 +153,12 @@ return PyLong_FromVoidPtr((void*)handle); } +PyDoc_STRVAR(get_osfhandle_doc, +"get_osfhandle(fd) -> file handle\n\ +\n\ +Return the file handle for the file descriptor fd. Raises IOError\n\ +if fd is not recognized."); + /* Console I/O */ static PyObject * @@ -135,6 +173,11 @@ return PyLong_FromLong(ok); } +PyDoc_STRVAR(kbhit_doc, +"kbhit() -> bool\n\ +\n\ +Return true if a keypress is waiting to be read."); + static PyObject * msvcrt_getch(PyObject *self, PyObject *args) { @@ -151,6 +194,16 @@ return PyBytes_FromStringAndSize(s, 1); } +PyDoc_STRVAR(getch_doc, +"getch() -> key character\n\ +\n\ +Read a keypress and return the resulting character. Nothing is echoed to\n\ +the console. This call will block if a keypress is not already\n\ +available, but will not wait for Enter to be pressed. If the pressed key\n\ +was a special function key, this will return '\\000' or '\\xe0'; the next\n\ +call will return the keycode. The Control-C keypress cannot be read with\n\ +this function."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_getwch(PyObject *self, PyObject *args) @@ -167,6 +220,11 @@ u[0] = ch; return PyUnicode_FromUnicode(u, 1); } + +PyDoc_STRVAR(getwch_doc, +"getwch() -> Unicode key character\n\ +\n\ +Wide char variant of getch(), returning a Unicode value."); #endif static PyObject * @@ -185,6 +243,12 @@ return PyBytes_FromStringAndSize(s, 1); } +PyDoc_STRVAR(getche_doc, +"getche() -> key character\n\ +\n\ +Similar to getch(), but the keypress will be echoed if it represents\n\ +a printable character."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_getwche(PyObject *self, PyObject *args) @@ -201,6 +265,11 @@ s[0] = ch; return PyUnicode_FromUnicode(s, 1); } + +PyDoc_STRVAR(getwche_doc, +"getwche() -> Unicode key character\n\ +\n\ +Wide char variant of getche(), returning a Unicode value."); #endif static PyObject * @@ -216,6 +285,11 @@ return Py_None; } +PyDoc_STRVAR(putch_doc, +"putch(char) -> None\n\ +\n\ +Print the character char to the console without buffering."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_putwch(PyObject *self, PyObject *args) @@ -229,6 +303,11 @@ Py_RETURN_NONE; } + +PyDoc_STRVAR(putwch_doc, +"putwch(unicode_char) -> None\n\ +\n\ +Wide char variant of putch(), accepting a Unicode value."); #endif static PyObject * @@ -245,6 +324,12 @@ return Py_None; } +PyDoc_STRVAR(ungetch_doc, +"ungetch(char) -> None\n\ +\n\ +Cause the character char to be \"pushed back\" into the console buffer;\n\ +it will be the next character read by getch() or getche()."); + #ifdef _WCONIO_DEFINED static PyObject * msvcrt_ungetwch(PyObject *self, PyObject *args) @@ -259,6 +344,11 @@ Py_INCREF(Py_None); return Py_None; } + +PyDoc_STRVAR(ungetwch_doc, +"ungetwch(unicode_char) -> None\n\ +\n\ +Wide char variant of ungetch(), accepting a Unicode value."); #endif static void @@ -332,16 +422,16 @@ /* List of functions exported by this module */ static struct PyMethodDef msvcrt_functions[] = { - {"heapmin", msvcrt_heapmin, METH_VARARGS}, - {"locking", msvcrt_locking, METH_VARARGS}, - {"setmode", msvcrt_setmode, METH_VARARGS}, - {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS}, - {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS}, - {"kbhit", msvcrt_kbhit, METH_VARARGS}, - {"getch", msvcrt_getch, METH_VARARGS}, - {"getche", msvcrt_getche, METH_VARARGS}, - {"putch", msvcrt_putch, METH_VARARGS}, - {"ungetch", msvcrt_ungetch, METH_VARARGS}, + {"heapmin", msvcrt_heapmin, METH_VARARGS, heapmin_doc}, + {"locking", msvcrt_locking, METH_VARARGS, locking_doc}, + {"setmode", msvcrt_setmode, METH_VARARGS, setmode_doc}, + {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS, open_osfhandle_doc}, + {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS, get_osfhandle_doc}, + {"kbhit", msvcrt_kbhit, METH_VARARGS, kbhit_doc}, + {"getch", msvcrt_getch, METH_VARARGS, getch_doc}, + {"getche", msvcrt_getche, METH_VARARGS, getche_doc}, + {"putch", msvcrt_putch, METH_VARARGS, putch_doc}, + {"ungetch", msvcrt_ungetch, METH_VARARGS, ungetch_doc}, {"SetErrorMode", seterrormode, METH_VARARGS}, #ifdef _DEBUG {"CrtSetReportFile", msvcrt_setreportfile, METH_VARARGS}, @@ -349,10 +439,10 @@ {"set_error_mode", msvcrt_seterrormode, METH_VARARGS}, #endif #ifdef _WCONIO_DEFINED - {"getwch", msvcrt_getwch, METH_VARARGS}, - {"getwche", msvcrt_getwche, METH_VARARGS}, - {"putwch", msvcrt_putwch, METH_VARARGS}, - {"ungetwch", msvcrt_ungetwch, METH_VARARGS}, + {"getwch", msvcrt_getwch, METH_VARARGS, getwch_doc}, + {"getwche", msvcrt_getwche, METH_VARARGS, getwche_doc}, + {"putwch", msvcrt_putwch, METH_VARARGS, putwch_doc}, + {"ungetwch", msvcrt_ungetwch, METH_VARARGS, ungetwch_doc}, #endif {NULL, NULL} }; From python-checkins at python.org Thu Dec 31 04:31:15 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 31 Dec 2009 03:31:15 -0000 Subject: [Python-checkins] r77172 - in python/branches/py3k: Doc/whatsnew/2.7.rst Message-ID: Author: benjamin.peterson Date: Thu Dec 31 04:31:15 2009 New Revision: 77172 Log: Merged revisions 76852,77001,77115,77127 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76852 | benjamin.peterson | 2009-12-15 21:36:22 -0600 (Tue, 15 Dec 2009) | 1 line remove type_compare, since type_richcompare does the same trick ........ r77001 | brett.cannon | 2009-12-21 20:37:37 -0600 (Mon, 21 Dec 2009) | 1 line Make a word plural. ........ r77115 | andrew.kuchling | 2009-12-29 14:10:16 -0600 (Tue, 29 Dec 2009) | 1 line Various additions ........ r77127 | andrew.kuchling | 2009-12-29 17:41:04 -0600 (Tue, 29 Dec 2009) | 1 line Add various items ........ 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 Thu Dec 31 04:31:15 2009 @@ -49,9 +49,9 @@ This saves the maintainer some effort going through the SVN logs when researching a change. -This article explains the new features in Python 2.7. No release -schedule has been decided yet for 2.7; the schedule will eventually be -described in :pep:`373`. +This article explains the new features in Python 2.7. The final +release of 2.7 is currently scheduled for June 2010; the detailed +schedule is described in :pep:`373`. .. Compare with previous release in 2 - 3 sentences here. add hyperlink when the documentation becomes available online. @@ -73,6 +73,11 @@ * The new format specifier described in :ref:`pep-0378`. * The :class:`memoryview` object. * A small subset of the :mod:`importlib` module `described below <#importlib-section>`__. +* Float-to-string and string-to-float conversions now round their + results more correctly. And :func:`repr` of a floating-point + number *x* returns a result that's guaranteed to round back to the + same number when converted back to a string. +* The :cfunc:`PyLong_AsLongAndOverflow` C API function. One porting change: the :option:`-3` switch now automatically enables the :option:`-Qwarn` switch that causes warnings @@ -237,6 +242,33 @@ (Proposed in http://codereview.appspot.com/53094; implemented by Georg Brandl.) +* Conversions between floating-point numbers and strings are + now correctly rounded on most platforms. These conversions occur + in many different places: :func:`str` on + floats and complex numbers; the :class:`float` and :class:`complex` + constructors; + numeric formatting; serialization and + deserialization of floats and complex numbers using the + :mod:`marshal`, :mod:`pickle` + and :mod:`json` modules; + parsing of float and imaginary literals in Python code; + and :class:`Decimal`-to-float conversion. + + Related to this, the :func:`repr` of a floating-point number *x* + now returns a result based on the shortest decimal string that's + guaranteed to round back to *x* under correct rounding (with + round-half-to-even rounding mode). Previously it gave a string + based on rounding x to 17 decimal digits. + + The rounding library responsible for this improvement works on + Windows, and on Unix platforms using the gcc, icc, or suncc + compilers. There may be a small number of platforms where correct + operation of this code cannot be guaranteed, so the code is not + used on such systems. + + Implemented by Mark Dickinson, using David Gay's :file:`dtoa.c` library; + :issue:`7117`. + * The :meth:`str.format` method now supports automatic numbering of the replacement fields. This makes using :meth:`str.format` more closely resemble using ``%s`` formatting:: @@ -259,6 +291,10 @@ alignment is applied to the whole of the resulting ``1.5+3j`` output. (Contributed by Eric Smith; :issue:`1588`.) + The 'F' format code now always formats its output using uppercase characters, + so it will now produce 'INF' and 'NAN'. + (Contributed by Eric Smith; :issue:`3382`.) + * 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:: @@ -301,6 +337,9 @@ (Implemented by Mark Dickinson; :issue:`3166`.) + Integer division is also more accurate in its rounding behaviours. (Also + implemented by Mark Dickinson; :issue:`1811`.) + * The :class:`bytearray` type's :meth:`translate` method now accepts ``None`` as its first argument. (Fixed by Georg Brandl; :issue:`4759`.) @@ -315,6 +354,15 @@ supported. (Contributed by Alexander Belchenko and Amaury Forgeot d'Arc; :issue:`1616979`.) +* The :class:`file` object will now set the :attr:`filename` attribute + on the :exc:`IOError` exception when trying to open a directory + on POSIX platforms. (Noted by Jan Kaliszewski; :issue:`4764`.) + +* Extra parentheses in function definitions are illegal in Python 3.x, + meaning that you get a syntax error from ``def f((x)): pass``. In + Python3-warning mode, Python 2.7 will now warn about this odd usage. + (Noted by James Lingard; :issue:`7362`.) + .. ====================================================================== @@ -333,16 +381,16 @@ :keyword:`with` statements, looking up the :meth:`__enter__` and :meth:`__exit__` methods. (Contributed by Benjamin Peterson.) -* 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 now performs better for one common usage + pattern: when many objects are being allocated without deallocating + any of them. This would previously take quadratic + time for garbage collection, but now the number of full garbage collections + is reduced as the number of objects on the heap grows. + The new logic is to only perform a full garbage collection pass 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. (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 @@ -410,7 +458,6 @@ conversion function that supports arbitrary bases. (Patch by Gawain Bolton; :issue:`6713`.) - .. ====================================================================== New and Improved Modules @@ -488,12 +535,22 @@ (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.) + read-only :attr:`maxlen` attribute, and has a + :meth:`reverse` method that reverses the elements of the deque in-place. + (Added by Raymond Hettinger.) + +* The :mod:`copy` module's :func:`deepcopy` function will now + correctly copy bound instance methods. (Implemented by + Robert Collins; :issue:`1515`.) * The :mod:`ctypes` module now always converts ``None`` to a C NULL pointer for arguments declared as pointers. (Changed by Thomas Heller; :issue:`4606`.) +* New method: the :mod:`datetime` module's :class:`timedelta` class + gained a :meth:`total_seconds` method that returns the number of seconds + in the duration. (Contributed by Brian Quinlan; :issue:`5788`.) + * 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`. @@ -539,14 +596,24 @@ process, but instead simply not install the failing extension. (Contributed by Georg Brandl; :issue:`5583`.) - Issue #7457: added a read_pkg_file method to.distutils.dist.DistributionMetadata - see file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata - (:issue:`7457`, added by Tarek). + The :class:`distutils.dist.DistributionMetadata` class' + :meth:`read_pkg_file` method will read the contents of a package's + :file:`PKG-INFO` metadata file. For an example of its use, + XXX link to file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata + (Contributed by Tarek Ziade; :issue:`7457`.) * The :class:`Fraction` class now accepts two rational numbers as arguments to its constructor. (Implemented by Mark Dickinson; :issue:`5812`.) +* The :mod:`ftplib` module gained the ability to establish secure FTP + connections using TLS encapsulation of authentication as well as + subsequent control and data transfers. This is provided by the new + :class:`ftplib.FTP_TLS` class. + (Contributed by Giampaolo Rodola', :issue:`2054`.) The :meth:`storbinary` + method for binary uploads can now restart uploads thanks to an added + *rest* parameter (patch by Pablo Mouzo; :issue:`6845`.) + * 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`.) @@ -627,8 +694,12 @@ with any object literal that decodes to a list of pairs. (Contributed by Raymond Hettinger; :issue:`5381`.) -* New functions: the :mod:`math` module now has - a :func:`gamma` function. +* New functions: the :mod:`math` module gained + :func:`erf` and :func:`erfc` for the error function and the complementary error function, + :func:`expm1` which computes ``e**x - 1`` with more precision than + using :func:`exp` and subtracting 1, + :func:`gamma` for the Gamma function, and + :func:`lgamma` for the natural log of the Gamma function. (Contributed by Mark Dickinson and nirinA raseliarison; :issue:`3366`.) * The :mod:`multiprocessing` module's :class:`Manager*` classes @@ -640,6 +711,15 @@ * The :mod:`nntplib` module now supports IPv6 addresses. (Contributed by Derek Morr; :issue:`1664`.) +* New functions: the :mod:`os` module wraps the following POSIX system + calls: :func:`getresgid` and :func:`getresuid`, which return the + real, effective, and saved GIDs and UIDs; + :func:`setresgid` and :func:`setresuid`, which set + real, effective, and saved GIDs and UIDs to new values; + :func:`initgroups`. (GID/UID functions + contributed by Travis H.; :issue:`6508`. Support for initgroups added + by Jean-Paul Calderone; :issue:`7333`.) + * 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`.) @@ -728,12 +808,6 @@ :mod:`zipfile` now supports archiving empty directories and extracts them correctly. (Fixed by Kuba Wieczorek; :issue:`4710`.) -* The :mod:`ftplib` module gains the ability to establish secure FTP - connections using TLS encapsulation of authentication as well as - subsequent control and data transfers. This is provided by the new - :class:`ftplib.FTP_TLS` class. - (Contributed by Giampaolo Rodola', :issue:`2054`.) - .. ====================================================================== .. whole new modules get described in subsections here @@ -855,7 +929,7 @@ 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 +to users 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`. @@ -934,12 +1008,23 @@ extensions needed to call :cfunc:`PyCode_New`, which had many more arguments. (Added by Jeffrey Yasskin.) +* New function: :cfunc:`PyErr_NewExceptionWithDoc` creates a new + exception class, just as the existing :cfunc:`PyErr_NewException` does, + but takes an extra ``char *`` argument containing the docstring for the + new exception class. (Added by the 'lekma' user on the Python bug tracker; + :issue:`7033`.) + * New function: :cfunc:`PyFrame_GetLineNumber` takes a frame object and returns the line number that the frame is currently executing. Previously code would need to get the index of the bytecode instruction currently executing, and then look up the line number corresponding to that address. (Added by Jeffrey Yasskin.) +* New function: :cfunc:`PyLong_AsLongAndOverflow` approximates a Python long + integer as a C :ctype:`long`. If the number is too large to fit into + a :ctype:`long`, an *overflow* flag is set and returned to the caller. + (Contributed by Case Van Horsen; :issue:`7528`.) + * New macros: the Python header files now define the following macros: :cmacro:`Py_ISALNUM`, :cmacro:`Py_ISALPHA`, @@ -958,6 +1043,12 @@ .. XXX these macros don't seem to be described in the c-api docs. +* New format codes: the :cfunc:`PyFormat_FromString`, + :cfunc:`PyFormat_FromStringV`, and :cfunc:`PyErr_Format` now + accepts ``%lld`` and ``%llu`` format codes for displaying values of + C's :ctype:`long long` types. + (Contributed by Mark Dickinson; :issue:`7228`.) + * The complicated interaction between threads and process forking has been changed. Previously, the child process created by :func:`os.fork` might fail because the child is created with only a @@ -992,6 +1083,12 @@ * The build process now supports Subversion 1.7. (Contributed by Arfrever Frehtes Taifersar Arahesis; :issue:`6094`.) +* Compiling Python with the :option:`--with-valgrind` option will now + disable the pymalloc allocator, which is difficult for the Valgrind to + analyze correctly. Valgrind will therefore be better at detecting + memory leaks and overruns. (Contributed by James Henstridge; :issue:`2422`.) + + .. ====================================================================== Port-Specific Changes: Windows @@ -1011,6 +1108,10 @@ * The :func:`os.listdir` function now correctly fails for an empty path. (Fixed by Hirokazu Yamamoto; :issue:`5913`.) +* The :mod:`mimelib` module will now read the MIME database from + the Windows registry when initializing. + (Patch by Gabriel Genellina; :issue:`4969`.) + .. ====================================================================== Port-Specific Changes: Mac OS X @@ -1070,6 +1171,10 @@ affects new-style classes (derived from :class:`object`) and C extension types. (:issue:`6101`.) +* The :meth:`readline` method of :class:`StringIO` objects now does + nothing when a negative length is requested, as other file-like + objects do. (:issue:`7348`). + .. ====================================================================== From python-checkins at python.org Thu Dec 31 04:35:15 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 31 Dec 2009 03:35:15 -0000 Subject: [Python-checkins] r77173 - in python/branches/py3k: Doc/Makefile Doc/README.txt Doc/make.bat Message-ID: Author: benjamin.peterson Date: Thu Dec 31 04:35:15 2009 New Revision: 77173 Log: Merged revisions 77151-77152 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77151 | georg.brandl | 2009-12-30 12:32:50 -0600 (Wed, 30 Dec 2009) | 1 line #7487: update Pygments version. ........ r77152 | georg.brandl | 2009-12-30 12:36:09 -0600 (Wed, 30 Dec 2009) | 1 line #7602: improve "clean" and "checkout" targets now that all tools are in externals. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/Makefile python/branches/py3k/Doc/README.txt python/branches/py3k/Doc/make.bat Modified: python/branches/py3k/Doc/Makefile ============================================================================== --- python/branches/py3k/Doc/Makefile (original) +++ python/branches/py3k/Doc/Makefile Thu Dec 31 04:35:15 2009 @@ -47,11 +47,7 @@ svn checkout $(SVNROOT)/external/Pygments-1.1.1/pygments tools/pygments; \ fi -update: checkout - svn update tools/sphinx - svn update tools/docutils - svn update tools/jinja2 - svn update tools/pygments +update: clean checkout build: checkout mkdir -p build/$(BUILDER) build/doctrees @@ -111,6 +107,9 @@ clean: -rm -rf build/* -rm -rf tools/sphinx + -rm -rf tools/pygments + -rm -rf tools/jinja2 + -rm -rf tools/docutils dist: -rm -rf dist Modified: python/branches/py3k/Doc/README.txt ============================================================================== --- python/branches/py3k/Doc/README.txt (original) +++ python/branches/py3k/Doc/README.txt Thu Dec 31 04:35:15 2009 @@ -95,7 +95,7 @@ You can optionally also install Pygments, either as a checkout via :: - svn co http://svn.python.org/projects/external/Pygments-0.11.1/pygments tools/pygments + svn co http://svn.python.org/projects/external/Pygments-1.1.1/pygments tools/pygments or from PyPI at http://pypi.python.org/pypi/Pygments. Modified: python/branches/py3k/Doc/make.bat ============================================================================== --- python/branches/py3k/Doc/make.bat (original) +++ python/branches/py3k/Doc/make.bat Thu Dec 31 04:35:15 2009 @@ -37,7 +37,7 @@ svn co %SVNROOT%/external/Sphinx-0.6.3/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 +svn co %SVNROOT%/external/Pygments-1.1.1/pygments tools/pygments goto end :update From python-checkins at python.org Thu Dec 31 04:56:10 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Thu, 31 Dec 2009 03:56:10 -0000 Subject: [Python-checkins] r77174 - in python/branches/py3k: Doc/c-api/object.rst Misc/NEWS Objects/bytesobject.c Message-ID: Author: alexandre.vassalotti Date: Thu Dec 31 04:56:09 2009 New Revision: 77174 Log: Issue #6687: Moved the special-case for integers out of PyBytes_FromObject. Modified: python/branches/py3k/Doc/c-api/object.rst python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/bytesobject.c 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 Thu Dec 31 04:56:09 2009 @@ -142,10 +142,11 @@ .. index:: builtin: bytes - Compute a bytes representation of object *o*. *NULL* is returned on failure - and a bytes object on success. This is equivalent to the Python expression - ``bytes(o)``. - + Compute a bytes representation of object *o*. *NULL* is returned on + failure and a bytes object on success. This is equivalent to the Python + expression ``bytes(o)``, when *o* is not an integer. Unlike ``bytes(o)``, + a TypeError is raised when *o* is an integer instead of a zero-initialized + bytes object. .. cfunction:: int PyObject_IsInstance(PyObject *inst, PyObject *cls) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Dec 31 04:56:09 2009 @@ -140,6 +140,9 @@ - Issue #4856: Remove checks for win NT. +- Issue #6687: PyBytes_FromObject() no longer accepts an integer as its + argument to construct a null-initialized bytes object. + C-API ----- Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Thu Dec 31 04:56:09 2009 @@ -2884,6 +2884,7 @@ const char *encoding = NULL; const char *errors = NULL; PyObject *new = NULL; + Py_ssize_t size; static char *kwlist[] = {"source", "encoding", "errors", 0}; if (type != &PyBytes_Type) @@ -2914,6 +2915,25 @@ assert(PyBytes_Check(new)); return new; } + /* Is it an integer? */ + size = PyNumber_AsSsize_t(x, PyExc_ValueError); + if (size == -1 && PyErr_Occurred()) { + PyErr_Clear(); + } + else { + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + new = PyBytes_FromStringAndSize(NULL, size); + if (new == NULL) { + return NULL; + } + if (size > 0) { + memset(((PyBytesObject*)new)->ob_sval, 0, size); + } + return new; + } /* If it's not unicode, there can't be encoding or errors */ if (encoding != NULL || errors != NULL) { @@ -2934,27 +2954,6 @@ PyErr_BadInternalCall(); return NULL; } - - /* Is it an int? */ - size = PyNumber_AsSsize_t(x, PyExc_ValueError); - if (size == -1 && PyErr_Occurred()) { - PyErr_Clear(); - } - else { - if (size < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return NULL; - } - new = PyBytes_FromStringAndSize(NULL, size); - if (new == NULL) { - return NULL; - } - if (size > 0) { - memset(((PyBytesObject*)new)->ob_sval, 0, size); - } - return new; - } - /* Use the modern buffer interface */ if (PyObject_CheckBuffer(x)) { Py_buffer view; @@ -2974,6 +2973,11 @@ PyBuffer_Release(&view); return NULL; } + if (PyUnicode_Check(x)) { + PyErr_SetString(PyExc_TypeError, + "cannot convert unicode object to bytes"); + return NULL; + } /* For iterator version, create a string object and resize as needed */ /* XXX(gb): is 64 a good value? also, optimize if length is known */ From python-checkins at python.org Thu Dec 31 09:22:12 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 31 Dec 2009 08:22:12 -0000 Subject: [Python-checkins] r77175 - peps/trunk/genpepindex.py Message-ID: Author: georg.brandl Date: Thu Dec 31 09:22:12 2009 New Revision: 77175 Log: Complain if filename does not match PEP number. Modified: peps/trunk/genpepindex.py Modified: peps/trunk/genpepindex.py ============================================================================== --- peps/trunk/genpepindex.py (original) +++ peps/trunk/genpepindex.py Thu Dec 31 09:22:12 2009 @@ -41,10 +41,14 @@ if file_path.startswith("pep-") and file_path.endswith(".txt"): with codecs.open(abs_file_path, 'r', encoding='UTF-8') as pep_file: try: - peps.append(PEP(pep_file)) + pep = PEP(pep_file) + if pep.number != int(file_path[4:-4]): + raise PEPError('PEP number does not match file name', + file_path, pep.number) + peps.append(pep) except PEPError, e: - errmsg = "Error processing PEP %s, excluding:" % \ - (e.number,) + errmsg = "Error processing PEP %s (%s), excluding:" % \ + (e.number, e.filename) print >>sys.stderr, errmsg, e sys.exit(1) peps.sort(key=attrgetter('number')) From python-checkins at python.org Thu Dec 31 13:24:39 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 31 Dec 2009 12:24:39 -0000 Subject: [Python-checkins] r77176 - python/branches/py3k/Doc/library/stdtypes.rst Message-ID: Author: ezio.melotti Date: Thu Dec 31 13:24:38 2009 New Revision: 77176 Log: #7612: typo in stdtypes.rst Modified: python/branches/py3k/Doc/library/stdtypes.rst Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Thu Dec 31 13:24:38 2009 @@ -650,7 +650,7 @@ Also, while in previous Python versions, byte strings and Unicode strings could be exchanged for each other rather freely (barring encoding issues), strings and bytes are now completely separate concepts. There's no implicit - en-/decoding if you pass and object of the wrong type. A string always + en-/decoding if you pass an object of the wrong type. A string always compares unequal to a bytes or bytearray object. Lists are constructed with square brackets, separating items with commas: ``[a, From python-checkins at python.org Thu Dec 31 13:26:02 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 31 Dec 2009 12:26:02 -0000 Subject: [Python-checkins] r77177 - in python/branches/release31-maint: Doc/library/stdtypes.rst Message-ID: Author: ezio.melotti Date: Thu Dec 31 13:26:02 2009 New Revision: 77177 Log: Merged revisions 77176 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r77176 | ezio.melotti | 2009-12-31 14:24:38 +0200 (Thu, 31 Dec 2009) | 1 line #7612: typo in stdtypes.rst ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/stdtypes.rst Modified: python/branches/release31-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release31-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release31-maint/Doc/library/stdtypes.rst Thu Dec 31 13:26:02 2009 @@ -650,7 +650,7 @@ Also, while in previous Python versions, byte strings and Unicode strings could be exchanged for each other rather freely (barring encoding issues), strings and bytes are now completely separate concepts. There's no implicit - en-/decoding if you pass and object of the wrong type. A string always + en-/decoding if you pass an object of the wrong type. A string always compares unequal to a bytes or bytearray object. Lists are constructed with square brackets, separating items with commas: ``[a, From python-checkins at python.org Thu Dec 31 14:00:43 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 31 Dec 2009 13:00:43 -0000 Subject: [Python-checkins] r77178 - python/trunk/Lib/test/test_zipfile.py Message-ID: Author: ezio.melotti Date: Thu Dec 31 14:00:43 2009 New Revision: 77178 Log: cleanup and refactoring Modified: python/trunk/Lib/test/test_zipfile.py Modified: python/trunk/Lib/test/test_zipfile.py ============================================================================== --- python/trunk/Lib/test/test_zipfile.py (original) +++ python/trunk/Lib/test/test_zipfile.py Thu Dec 31 14:00:43 2009 @@ -6,6 +6,7 @@ import os import sys +import time import shutil import struct import zipfile @@ -31,18 +32,17 @@ class TestsWithSourceFile(unittest.TestCase): def setUp(self): self.line_gen = ["Zipfile test line %d. random float: %f" % (i, random()) - for i in xrange(FIXEDTEST_SIZE)] + for i in xrange(FIXEDTEST_SIZE)] self.data = '\n'.join(self.line_gen) + '\n' # Make a source file with some lines - fp = open(TESTFN, "wb") - fp.write(self.data) - fp.close() + with open(TESTFN, "wb") as fp: + fp.write(self.data) def make_test_archive(self, f, compression): # Create the ZIP archive with zipfile.ZipFile(f, "w", compression) as zipfp: - zipfp.write(TESTFN, "another"+os.extsep+"name") + zipfp.write(TESTFN, "another.name") zipfp.write(TESTFN, TESTFN) zipfp.writestr("strfile", self.data) @@ -52,7 +52,7 @@ # Read the ZIP archive with zipfile.ZipFile(f, "r", compression) as zipfp: self.assertEqual(zipfp.read(TESTFN), self.data) - self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data) + self.assertEqual(zipfp.read("another.name"), self.data) self.assertEqual(zipfp.read("strfile"), self.data) # Print the ZIP directory @@ -66,39 +66,40 @@ directory = fp.getvalue() lines = directory.splitlines() - self.assertEquals(len(lines), 4) # Number of files + header + self.assertEqual(len(lines), 4) # Number of files + header self.assertTrue('File Name' in lines[0]) self.assertTrue('Modified' in lines[0]) self.assertTrue('Size' in lines[0]) - fn, date, time, size = lines[1].split() - self.assertEquals(fn, 'another.name') - # XXX: timestamp is not tested - self.assertEquals(size, str(len(self.data))) + fn, date, time_, size = lines[1].split() + self.assertEqual(fn, 'another.name') + self.assertTrue(time.strptime(date, '%Y-%m-%d')) + self.assertTrue(time.strptime(time_, '%H:%M:%S')) + self.assertEqual(size, str(len(self.data))) # Check the namelist names = zipfp.namelist() - self.assertEquals(len(names), 3) + self.assertEqual(len(names), 3) self.assertTrue(TESTFN in names) - self.assertTrue("another"+os.extsep+"name" in names) + self.assertTrue("another.name" in names) self.assertTrue("strfile" in names) # Check infolist infos = zipfp.infolist() - names = [ i.filename for i in infos ] - self.assertEquals(len(names), 3) + names = [i.filename for i in infos] + self.assertEqual(len(names), 3) self.assertTrue(TESTFN in names) - self.assertTrue("another"+os.extsep+"name" in names) + self.assertTrue("another.name" in names) self.assertTrue("strfile" in names) for i in infos: - self.assertEquals(i.file_size, len(self.data)) + self.assertEqual(i.file_size, len(self.data)) # check getinfo - for nm in (TESTFN, "another"+os.extsep+"name", "strfile"): + for nm in (TESTFN, "another.name", "strfile"): info = zipfp.getinfo(nm) - self.assertEquals(info.filename, nm) - self.assertEquals(info.file_size, len(self.data)) + self.assertEqual(info.filename, nm) + self.assertEqual(info.file_size, len(self.data)) # Check that testzip doesn't raise an exception zipfp.testzip() @@ -121,7 +122,7 @@ zipdata1.append(read_data) zipdata2 = [] - zipopen2 = zipfp.open("another"+os.extsep+"name") + zipopen2 = zipfp.open("another.name") while True: read_data = zipopen2.read(256) if not read_data: @@ -242,7 +243,7 @@ @skipUnless(zlib, "requires zlib") def test_low_compression(self): - # Checks for cases where compressed data is larger than original + """Check for cases where compressed data is larger than original.""" # Create the ZIP archive with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp: zipfp.writestr("strfile", '12') @@ -261,7 +262,7 @@ self.assertEqual(zipfp.namelist(), ["absolute"]) def test_append_to_zip_file(self): - # Test appending to an existing zipfile + """Test appending to an existing zipfile.""" with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: zipfp.write(TESTFN, TESTFN) @@ -270,31 +271,32 @@ self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"]) def test_append_to_non_zip_file(self): - # Test appending to an existing file that is not a zipfile + """Test appending to an existing file that is not a zipfile.""" # NOTE: this test fails if len(d) < 22 because of the first # line "fpin.seek(-22, 2)" in _EndRecData - d = 'I am not a ZipFile!'*10 - f = file(TESTFN2, 'wb') - f.write(d) - f.close() + data = 'I am not a ZipFile!'*10 + with open(TESTFN2, 'wb') as f: + f.write(data) + with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp: zipfp.write(TESTFN, TESTFN) - f = file(TESTFN2, 'rb') - f.seek(len(d)) - with zipfile.ZipFile(f, "r") as zipfp: - self.assertEqual(zipfp.namelist(), [TESTFN]) - f.close() + with open(TESTFN2, 'rb') as f: + f.seek(len(data)) + with zipfile.ZipFile(f, "r") as zipfp: + self.assertEqual(zipfp.namelist(), [TESTFN]) def test_write_default_name(self): - # Check that calling ZipFile.write without arcname specified produces the expected result + """Check that calling ZipFile.write without arcname specified + produces the expected result.""" with zipfile.ZipFile(TESTFN2, "w") as zipfp: zipfp.write(TESTFN) - self.assertEqual(zipfp.read(TESTFN), file(TESTFN).read()) + self.assertEqual(zipfp.read(TESTFN), open(TESTFN).read()) @skipUnless(zlib, "requires zlib") def test_per_file_compression(self): - # Check that files within a Zip archive can have different compression options + """Check that files within a Zip archive can have different + compression options.""" with zipfile.ZipFile(TESTFN2, "w") as zipfp: zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED) zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED) @@ -304,8 +306,8 @@ self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED) def test_write_to_readonly(self): - # Check that trying to call write() on a readonly ZipFile object - # raises a RuntimeError + """Check that trying to call write() on a readonly ZipFile object + raises a RuntimeError.""" with zipfile.ZipFile(TESTFN2, mode="w") as zipfp: zipfp.writestr("somefile.txt", "bogus") @@ -331,8 +333,7 @@ self.assertEqual(writtenfile, correctfile) # make sure correct data is in correct file - self.assertEqual(fdata, file(writtenfile, "rb").read()) - + self.assertEqual(fdata, open(writtenfile, "rb").read()) os.remove(writtenfile) # remove the test file subdirectories @@ -351,8 +352,7 @@ else: outfile = os.path.join(os.getcwd(), fpath) - self.assertEqual(fdata, file(outfile, "rb").read()) - + self.assertEqual(fdata, open(outfile, "rb").read()) os.remove(outfile) # remove the test file subdirectories @@ -409,23 +409,23 @@ self._limit = zipfile.ZIP64_LIMIT zipfile.ZIP64_LIMIT = 5 - line_gen = ("Test of zipfile line %d." % i for i in range(0, FIXEDTEST_SIZE)) + line_gen = ("Test of zipfile line %d." % i + for i in range(0, FIXEDTEST_SIZE)) self.data = '\n'.join(line_gen) # Make a source file with some lines - fp = open(TESTFN, "wb") - fp.write(self.data) - fp.close() + with open(TESTFN, "wb") as fp: + fp.write(self.data) def large_file_exception_test(self, f, compression): with zipfile.ZipFile(f, "w", compression) as zipfp: self.assertRaises(zipfile.LargeZipFile, - zipfp.write, TESTFN, "another"+os.extsep+"name") + zipfp.write, TESTFN, "another.name") def large_file_exception_test2(self, f, compression): with zipfile.ZipFile(f, "w", compression) as zipfp: self.assertRaises(zipfile.LargeZipFile, - zipfp.writestr, "another"+os.extsep+"name", self.data) + zipfp.writestr, "another.name", self.data) def test_large_file_exception(self): for f in (TESTFN2, TemporaryFile(), StringIO()): @@ -435,14 +435,14 @@ def zip_test(self, f, compression): # Create the ZIP archive with zipfile.ZipFile(f, "w", compression, allowZip64=True) as zipfp: - zipfp.write(TESTFN, "another"+os.extsep+"name") + zipfp.write(TESTFN, "another.name") zipfp.write(TESTFN, TESTFN) zipfp.writestr("strfile", self.data) # Read the ZIP archive with zipfile.ZipFile(f, "r", compression) as zipfp: self.assertEqual(zipfp.read(TESTFN), self.data) - self.assertEqual(zipfp.read("another"+os.extsep+"name"), self.data) + self.assertEqual(zipfp.read("another.name"), self.data) self.assertEqual(zipfp.read("strfile"), self.data) # Print the ZIP directory @@ -456,39 +456,40 @@ directory = fp.getvalue() lines = directory.splitlines() - self.assertEquals(len(lines), 4) # Number of files + header + self.assertEqual(len(lines), 4) # Number of files + header self.assertTrue('File Name' in lines[0]) self.assertTrue('Modified' in lines[0]) self.assertTrue('Size' in lines[0]) - fn, date, time, size = lines[1].split() - self.assertEquals(fn, 'another.name') - # XXX: timestamp is not tested - self.assertEquals(size, str(len(self.data))) + fn, date, time_, size = lines[1].split() + self.assertEqual(fn, 'another.name') + self.assertTrue(time.strptime(date, '%Y-%m-%d')) + self.assertTrue(time.strptime(time_, '%H:%M:%S')) + self.assertEqual(size, str(len(self.data))) # Check the namelist names = zipfp.namelist() - self.assertEquals(len(names), 3) + self.assertEqual(len(names), 3) self.assertTrue(TESTFN in names) - self.assertTrue("another"+os.extsep+"name" in names) + self.assertTrue("another.name" in names) self.assertTrue("strfile" in names) # Check infolist infos = zipfp.infolist() - names = [ i.filename for i in infos ] - self.assertEquals(len(names), 3) + names = [i.filename for i in infos] + self.assertEqual(len(names), 3) self.assertTrue(TESTFN in names) - self.assertTrue("another"+os.extsep+"name" in names) + self.assertTrue("another.name" in names) self.assertTrue("strfile" in names) for i in infos: - self.assertEquals(i.file_size, len(self.data)) + self.assertEqual(i.file_size, len(self.data)) # check getinfo - for nm in (TESTFN, "another"+os.extsep+"name", "strfile"): + for nm in (TESTFN, "another.name", "strfile"): info = zipfp.getinfo(nm) - self.assertEquals(info.filename, nm) - self.assertEquals(info.file_size, len(self.data)) + self.assertEqual(info.filename, nm) + self.assertEqual(info.file_size, len(self.data)) # Check that testzip doesn't raise an exception zipfp.testzip() @@ -532,12 +533,12 @@ with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: fn = __file__ - if fn.endswith('.pyc') or fn.endswith('.pyo'): + if fn.endswith(('.pyc', '.pyo')): fn = fn[:-1] zipfp.writepy(fn, "testpackage") - bn = "%s/%s"%("testpackage", os.path.basename(fn)) + bn = "%s/%s" % ("testpackage", os.path.basename(fn)) self.assertTrue(bn not in zipfp.namelist()) self.assertTrue(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist()) @@ -549,7 +550,8 @@ with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: zipfp.writepy(packagedir) - # Check for a couple of modules at different levels of the hieararchy + # Check for a couple of modules at different levels of the + # hierarchy names = zipfp.namelist() self.assertTrue('email/__init__.pyo' in names or 'email/__init__.pyc' in names) @@ -559,17 +561,14 @@ def test_write_python_directory(self): os.mkdir(TESTFN2) try: - fp = open(os.path.join(TESTFN2, "mod1.py"), "w") - fp.write("print 42\n") - fp.close() - - fp = open(os.path.join(TESTFN2, "mod2.py"), "w") - fp.write("print 42 * 42\n") - fp.close() - - fp = open(os.path.join(TESTFN2, "mod2.txt"), "w") - fp.write("bla bla bla\n") - fp.close() + with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp: + fp.write("print 42\n") + + with open(os.path.join(TESTFN2, "mod2.py"), "w") as fp: + fp.write("print 42 * 42\n") + + with open(os.path.join(TESTFN2, "mod2.txt"), "w") as fp: + fp.write("bla bla bla\n") zipfp = zipfile.PyZipFile(TemporaryFile(), "w") zipfp.writepy(TESTFN2) @@ -584,7 +583,7 @@ def test_write_non_pyfile(self): with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: - file(TESTFN, 'w').write('most definitely not a python file') + open(TESTFN, 'w').write('most definitely not a python file') self.assertRaises(RuntimeError, zipfp.writepy, TESTFN) os.remove(TESTFN) @@ -620,28 +619,26 @@ def test_close_erroneous_file(self): # This test checks that the ZipFile constructor closes the file object - # it opens if there's an error in the file. If it doesn't, the traceback - # holds a reference to the ZipFile object and, indirectly, the file object. + # it opens if there's an error in the file. If it doesn't, the + # traceback holds a reference to the ZipFile object and, indirectly, + # the file object. # On Windows, this causes the os.unlink() call to fail because the # underlying file is still open. This is SF bug #412214. # - fp = open(TESTFN, "w") - fp.write("this is not a legal zip file\n") - fp.close() + with open(TESTFN, "w") as fp: + fp.write("this is not a legal zip file\n") try: zf = zipfile.ZipFile(TESTFN) except zipfile.BadZipfile: pass def test_is_zip_erroneous_file(self): - # This test checks that the is_zipfile function correctly identifies - # a file that is not a zip file - + """Check that is_zipfile() correctly identifies non-zip files.""" # - passing a filename with open(TESTFN, "w") as fp: fp.write("this is not a legal zip file\n") chk = zipfile.is_zipfile(TESTFN) - self.assertTrue(not chk) + self.assertFalse(chk) # - passing a file object with open(TESTFN, "rb") as fp: chk = zipfile.is_zipfile(fp) @@ -651,14 +648,12 @@ fp.write("this is not a legal zip file\n") chk = zipfile.is_zipfile(fp) self.assertTrue(not chk) - fp.seek(0,0) + fp.seek(0, 0) chk = zipfile.is_zipfile(fp) self.assertTrue(not chk) def test_is_zip_valid_file(self): - # This test checks that the is_zipfile function correctly identifies - # a file that is a zip file - + """Check that is_zipfile() correctly identifies zip files.""" # - passing a filename with zipfile.ZipFile(TESTFN, mode="w") as zipf: zipf.writestr("foo.txt", "O, for a Muse of Fire!") @@ -668,14 +663,14 @@ with open(TESTFN, "rb") as fp: chk = zipfile.is_zipfile(fp) self.assertTrue(chk) - fp.seek(0,0) + fp.seek(0, 0) zip_contents = fp.read() # - passing a file-like object fp = StringIO() fp.write(zip_contents) chk = zipfile.is_zipfile(fp) self.assertTrue(chk) - fp.seek(0,0) + fp.seek(0, 0) chk = zipfile.is_zipfile(fp) self.assertTrue(chk) @@ -698,13 +693,12 @@ f.close() self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN) - f = open(TESTFN, 'w') - f.write("short file") - f.close() + with open(TESTFN, 'w') as fp: + fp.write("short file") self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN) def test_closed_zip_raises_RuntimeError(self): - # Verify that testzip() doesn't swallow inappropriate exceptions. + """Verify that testzip() doesn't swallow inappropriate exceptions.""" data = StringIO() with zipfile.ZipFile(data, mode="w") as zipf: zipf.writestr("foo.txt", "O, for a Muse of Fire!") @@ -717,15 +711,15 @@ self.assertRaises(RuntimeError, zipf.open, "foo.txt") self.assertRaises(RuntimeError, zipf.testzip) self.assertRaises(RuntimeError, zipf.writestr, "bogus.txt", "bogus") - file(TESTFN, 'w').write('zipfile test data') + open(TESTFN, 'w').write('zipfile test data') self.assertRaises(RuntimeError, zipf.write, TESTFN) def test_bad_constructor_mode(self): - # Check that bad modes passed to ZipFile constructor are caught + """Check that bad modes passed to ZipFile constructor are caught.""" self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "q") def test_bad_open_mode(self): - # Check that bad modes passed to ZipFile.open are caught + """Check that bad modes passed to ZipFile.open are caught.""" with zipfile.ZipFile(TESTFN, mode="w") as zipf: zipf.writestr("foo.txt", "O, for a Muse of Fire!") @@ -735,8 +729,8 @@ self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q") def test_read0(self): - # Check that calling read(0) on a ZipExtFile object returns an empty - # string and doesn't advance file pointer + """Check that calling read(0) on a ZipExtFile object returns an empty + string and doesn't advance file pointer.""" with zipfile.ZipFile(TESTFN, mode="w") as zipf: zipf.writestr("foo.txt", "O, for a Muse of Fire!") # read the data to make sure the file is there @@ -747,30 +741,32 @@ self.assertEqual(f.read(), "O, for a Muse of Fire!") def test_open_non_existent_item(self): - # Check that attempting to call open() for an item that doesn't - # exist in the archive raises a RuntimeError + """Check that attempting to call open() for an item that doesn't + exist in the archive raises a RuntimeError.""" with zipfile.ZipFile(TESTFN, mode="w") as zipf: self.assertRaises(KeyError, zipf.open, "foo.txt", "r") def test_bad_compression_mode(self): - # Check that bad compression methods passed to ZipFile.open are caught + """Check that bad compression methods passed to ZipFile.open are + caught.""" self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1) def test_null_byte_in_filename(self): - # Check that a filename containing a null byte is properly terminated + """Check that a filename containing a null byte is properly + terminated.""" with zipfile.ZipFile(TESTFN, mode="w") as zipf: zipf.writestr("foo.txt\x00qqq", "O, for a Muse of Fire!") self.assertEqual(zipf.namelist(), ['foo.txt']) def test_struct_sizes(self): - # check that ZIP internal structure sizes are calculated correctly + """Check that ZIP internal structure sizes are calculated correctly.""" self.assertEqual(zipfile.sizeEndCentDir, 22) self.assertEqual(zipfile.sizeCentralDir, 46) self.assertEqual(zipfile.sizeEndCentDir64, 56) self.assertEqual(zipfile.sizeEndCentDir64Locator, 20) def test_comments(self): - # This test checks that comments on the archive are handled properly + """Check that comments on the archive are handled properly.""" # check default comment is empty with zipfile.ZipFile(TESTFN, mode="w") as zipf: @@ -810,9 +806,9 @@ class DecryptionTests(unittest.TestCase): - # This test checks that ZIP decryption works. Since the library does not - # support encryption at the moment, we use a pre-generated encrypted - # ZIP file + """Check that ZIP decryption works. Since the library does not + support encryption at the moment, we use a pre-generated encrypted + ZIP file.""" data = ( 'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00' @@ -836,13 +832,11 @@ plain2 = '\x00'*512 def setUp(self): - fp = open(TESTFN, "wb") - fp.write(self.data) - fp.close() + with open(TESTFN, "wb") as fp: + fp.write(self.data) self.zip = zipfile.ZipFile(TESTFN, "r") - fp = open(TESTFN2, "wb") - fp.write(self.data2) - fp.close() + with open(TESTFN2, "wb") as fp: + fp.write(self.data2) self.zip2 = zipfile.ZipFile(TESTFN2, "r") def tearDown(self): @@ -866,20 +860,20 @@ @skipUnless(zlib, "requires zlib") def test_good_password(self): self.zip.setpassword("python") - self.assertEquals(self.zip.read("test.txt"), self.plain) + self.assertEqual(self.zip.read("test.txt"), self.plain) self.zip2.setpassword("12345") - self.assertEquals(self.zip2.read("zero"), self.plain2) + self.assertEqual(self.zip2.read("zero"), self.plain2) class TestsWithRandomBinaryFiles(unittest.TestCase): def setUp(self): datacount = randint(16, 64)*1024 + randint(1, 1024) - self.data = ''.join((struct.pack(' Author: ezio.melotti Date: Thu Dec 31 14:22:41 2009 New Revision: 77179 Log: Merged revisions 77178 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77178 | ezio.melotti | 2009-12-31 15:00:43 +0200 (Thu, 31 Dec 2009) | 1 line cleanup and refactoring ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_zipfile.py Modified: python/branches/py3k/Lib/test/test_zipfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_zipfile.py (original) +++ python/branches/py3k/Lib/test/test_zipfile.py Thu Dec 31 14:22:41 2009 @@ -6,6 +6,7 @@ import io import os +import time import shutil import struct import zipfile @@ -36,9 +37,8 @@ self.data = b'\n'.join(self.line_gen) + b'\n' # Make a source file with some lines - fp = open(TESTFN, "wb") - fp.write(self.data) - fp.close() + with open(TESTFN, "wb") as fp: + fp.write(self.data) def make_test_archive(self, f, compression): # Create the ZIP archive @@ -61,39 +61,40 @@ zipfp.printdir(file=fp) directory = fp.getvalue() lines = directory.splitlines() - self.assertEquals(len(lines), 4) # Number of files + header + self.assertEqual(len(lines), 4) # Number of files + header self.assertTrue('File Name' in lines[0]) self.assertTrue('Modified' in lines[0]) self.assertTrue('Size' in lines[0]) - fn, date, time, size = lines[1].split() - self.assertEquals(fn, 'another.name') - # XXX: timestamp is not tested - self.assertEquals(size, str(len(self.data))) + fn, date, time_, size = lines[1].split() + self.assertEqual(fn, 'another.name') + self.assertTrue(time.strptime(date, '%Y-%m-%d')) + self.assertTrue(time.strptime(time_, '%H:%M:%S')) + self.assertEqual(size, str(len(self.data))) # Check the namelist names = zipfp.namelist() - self.assertEquals(len(names), 3) + self.assertEqual(len(names), 3) self.assertTrue(TESTFN in names) self.assertTrue("another.name" in names) self.assertTrue("strfile" in names) # Check infolist infos = zipfp.infolist() - names = [ i.filename for i in infos ] - self.assertEquals(len(names), 3) + names = [i.filename for i in infos] + self.assertEqual(len(names), 3) self.assertTrue(TESTFN in names) self.assertTrue("another.name" in names) self.assertTrue("strfile" in names) for i in infos: - self.assertEquals(i.file_size, len(self.data)) + self.assertEqual(i.file_size, len(self.data)) # check getinfo for nm in (TESTFN, "another.name", "strfile"): info = zipfp.getinfo(nm) - self.assertEquals(info.filename, nm) - self.assertEquals(info.file_size, len(self.data)) + self.assertEqual(info.filename, nm) + self.assertEqual(info.file_size, len(self.data)) # Check that testzip doesn't raise an exception zipfp.testzip() @@ -239,7 +240,7 @@ @skipUnless(zlib, "requires zlib") def test_low_compression(self): - # Checks for cases where compressed data is larger than original + """Check for cases where compressed data is larger than original.""" # Create the ZIP archive with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp: zipfp.writestr("strfile", '12') @@ -258,7 +259,7 @@ self.assertEqual(zipfp.namelist(), ["absolute"]) def test_append_to_zip_file(self): - # Test appending to an existing zipfile + """Test appending to an existing zipfile.""" with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: zipfp.write(TESTFN, TESTFN) @@ -267,30 +268,32 @@ self.assertEqual(zipfp.namelist(), [TESTFN, "strfile"]) def test_append_to_non_zip_file(self): - # Test appending to an existing file that is not a zipfile + """Test appending to an existing file that is not a zipfile.""" # NOTE: this test fails if len(d) < 22 because of the first # line "fpin.seek(-22, 2)" in _EndRecData - d = b'I am not a ZipFile!'*10 - f = open(TESTFN2, 'wb') - f.write(d) - f.close() + data = b'I am not a ZipFile!'*10 + with open(TESTFN2, 'wb') as f: + f.write(data) + with zipfile.ZipFile(TESTFN2, "a", zipfile.ZIP_STORED) as zipfp: zipfp.write(TESTFN, TESTFN) - f = open(TESTFN2, 'rb') - f.seek(len(d)) - with zipfile.ZipFile(f, "r") as zipfp: - self.assertEqual(zipfp.namelist(), [TESTFN]) + with open(TESTFN2, 'rb') as f: + f.seek(len(data)) + with zipfile.ZipFile(f, "r") as zipfp: + self.assertEqual(zipfp.namelist(), [TESTFN]) def test_write_default_name(self): - # Check that calling ZipFile.write without arcname specified produces the expected result + """Check that calling ZipFile.write without arcname specified + produces the expected result.""" with zipfile.ZipFile(TESTFN2, "w") as zipfp: zipfp.write(TESTFN) self.assertEqual(zipfp.read(TESTFN), open(TESTFN, "rb").read()) @skipUnless(zlib, "requires zlib") def test_per_file_compression(self): - # Check that files within a Zip archive can have different compression options + """Check that files within a Zip archive can have different + compression options.""" with zipfile.ZipFile(TESTFN2, "w") as zipfp: zipfp.write(TESTFN, 'storeme', zipfile.ZIP_STORED) zipfp.write(TESTFN, 'deflateme', zipfile.ZIP_DEFLATED) @@ -300,8 +303,8 @@ self.assertEqual(dinfo.compress_type, zipfile.ZIP_DEFLATED) def test_write_to_readonly(self): - # Check that trying to call write() on a readonly ZipFile object - # raises a RuntimeError + """Check that trying to call write() on a readonly ZipFile object + raises a RuntimeError.""" with zipfile.ZipFile(TESTFN2, mode="w") as zipfp: zipfp.writestr("somefile.txt", "bogus") @@ -417,19 +420,18 @@ self.data = b'\n'.join(line_gen) # Make a source file with some lines - fp = open(TESTFN, "wb") - fp.write(self.data) - fp.close() + with open(TESTFN, "wb") as fp: + fp.write(self.data) def large_file_exception_test(self, f, compression): with zipfile.ZipFile(f, "w", compression) as zipfp: self.assertRaises(zipfile.LargeZipFile, - zipfp.write, TESTFN, "another.name") + zipfp.write, TESTFN, "another.name") def large_file_exception_test2(self, f, compression): with zipfile.ZipFile(f, "w", compression) as zipfp: self.assertRaises(zipfile.LargeZipFile, - zipfp.writestr, "another.name", self.data) + zipfp.writestr, "another.name", self.data) def test_large_file_exception(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): @@ -455,39 +457,40 @@ directory = fp.getvalue() lines = directory.splitlines() - self.assertEquals(len(lines), 4) # Number of files + header + self.assertEqual(len(lines), 4) # Number of files + header self.assertTrue('File Name' in lines[0]) self.assertTrue('Modified' in lines[0]) self.assertTrue('Size' in lines[0]) - fn, date, time, size = lines[1].split() - self.assertEquals(fn, 'another.name') - # XXX: timestamp is not tested - self.assertEquals(size, str(len(self.data))) + fn, date, time_, size = lines[1].split() + self.assertEqual(fn, 'another.name') + self.assertTrue(time.strptime(date, '%Y-%m-%d')) + self.assertTrue(time.strptime(time_, '%H:%M:%S')) + self.assertEqual(size, str(len(self.data))) # Check the namelist names = zipfp.namelist() - self.assertEquals(len(names), 3) + self.assertEqual(len(names), 3) self.assertTrue(TESTFN in names) self.assertTrue("another.name" in names) self.assertTrue("strfile" in names) # Check infolist infos = zipfp.infolist() - names = [ i.filename for i in infos ] - self.assertEquals(len(names), 3) + names = [i.filename for i in infos] + self.assertEqual(len(names), 3) self.assertTrue(TESTFN in names) self.assertTrue("another.name" in names) self.assertTrue("strfile" in names) for i in infos: - self.assertEquals(i.file_size, len(self.data)) + self.assertEqual(i.file_size, len(self.data)) # check getinfo for nm in (TESTFN, "another.name", "strfile"): info = zipfp.getinfo(nm) - self.assertEquals(info.filename, nm) - self.assertEquals(info.file_size, len(self.data)) + self.assertEqual(info.filename, nm) + self.assertEqual(info.file_size, len(self.data)) # Check that testzip doesn't raise an exception zipfp.testzip() @@ -531,12 +534,12 @@ with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: fn = __file__ - if fn.endswith('.pyc') or fn.endswith('.pyo'): + if fn.endswith(('.pyc', '.pyo')): fn = fn[:-1] zipfp.writepy(fn, "testpackage") - bn = "%s/%s"%("testpackage", os.path.basename(fn)) + bn = "%s/%s" % ("testpackage", os.path.basename(fn)) self.assertTrue(bn not in zipfp.namelist()) self.assertTrue(bn + 'o' in zipfp.namelist() or bn + 'c' in zipfp.namelist()) @@ -548,7 +551,8 @@ with zipfile.PyZipFile(TemporaryFile(), "w") as zipfp: zipfp.writepy(packagedir) - # Check for a couple of modules at different levels of the hieararchy + # Check for a couple of modules at different levels of the + # hierarchy names = zipfp.namelist() self.assertTrue('email/__init__.pyo' in names or 'email/__init__.pyc' in names) @@ -558,17 +562,14 @@ def test_write_python_directory(self): os.mkdir(TESTFN2) try: - fp = open(os.path.join(TESTFN2, "mod1.py"), "w") - fp.write("print(42)\n") - fp.close() - - fp = open(os.path.join(TESTFN2, "mod2.py"), "w") - fp.write("print(42 * 42)\n") - fp.close() - - fp = open(os.path.join(TESTFN2, "mod2.txt"), "w") - fp.write("bla bla bla\n") - fp.close() + with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp: + fp.write("print(42)\n") + + with open(os.path.join(TESTFN2, "mod2.py"), "w") as fp: + fp.write("print(42 * 42)\n") + + with open(os.path.join(TESTFN2, "mod2.txt"), "w") as fp: + fp.write("bla bla bla\n") zipfp = zipfile.PyZipFile(TemporaryFile(), "w") zipfp.writepy(TESTFN2) @@ -619,28 +620,26 @@ def test_close_erroneous_file(self): # This test checks that the ZipFile constructor closes the file object - # it opens if there's an error in the file. If it doesn't, the traceback - # holds a reference to the ZipFile object and, indirectly, the file object. + # it opens if there's an error in the file. If it doesn't, the + # traceback holds a reference to the ZipFile object and, indirectly, + # the file object. # On Windows, this causes the os.unlink() call to fail because the # underlying file is still open. This is SF bug #412214. # - fp = open(TESTFN, "w") - fp.write("this is not a legal zip file\n") - fp.close() + with open(TESTFN, "w") as fp: + fp.write("this is not a legal zip file\n") try: zf = zipfile.ZipFile(TESTFN) except zipfile.BadZipfile: pass def test_is_zip_erroneous_file(self): - # This test checks that the is_zipfile function correctly identifies - # a file that is not a zip file - + """Check that is_zipfile() correctly identifies non-zip files.""" # - passing a filename with open(TESTFN, "w") as fp: fp.write("this is not a legal zip file\n") chk = zipfile.is_zipfile(TESTFN) - self.assertTrue(not chk) + self.assertFalse(chk) # - passing a file object with open(TESTFN, "rb") as fp: chk = zipfile.is_zipfile(fp) @@ -650,14 +649,12 @@ fp.write(b"this is not a legal zip file\n") chk = zipfile.is_zipfile(fp) self.assertTrue(not chk) - fp.seek(0,0) + fp.seek(0, 0) chk = zipfile.is_zipfile(fp) self.assertTrue(not chk) def test_is_zip_valid_file(self): - # This test checks that the is_zipfile function correctly identifies - # a file that is a zip file - + """Check that is_zipfile() correctly identifies zip files.""" # - passing a filename with zipfile.ZipFile(TESTFN, mode="w") as zipf: zipf.writestr("foo.txt", b"O, for a Muse of Fire!") @@ -668,14 +665,14 @@ with open(TESTFN, "rb") as fp: chk = zipfile.is_zipfile(fp) self.assertTrue(chk) - fp.seek(0,0) + fp.seek(0, 0) zip_contents = fp.read() # - passing a file-like object fp = io.BytesIO() fp.write(zip_contents) chk = zipfile.is_zipfile(fp) self.assertTrue(chk) - fp.seek(0,0) + fp.seek(0, 0) chk = zipfile.is_zipfile(fp) self.assertTrue(chk) @@ -698,13 +695,12 @@ f.close() self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN) - f = open(TESTFN, 'w') - f.write("short file") - f.close() + with open(TESTFN, 'w') as fp: + fp.write("short file") self.assertRaises(zipfile.BadZipfile, zipfile.ZipFile, TESTFN) def test_closed_zip_raises_RuntimeError(self): - # Verify that testzip() doesn't swallow inappropriate exceptions. + """Verify that testzip() doesn't swallow inappropriate exceptions.""" data = io.BytesIO() with zipfile.ZipFile(data, mode="w") as zipf: zipf.writestr("foo.txt", "O, for a Muse of Fire!") @@ -721,11 +717,11 @@ self.assertRaises(RuntimeError, zipf.write, TESTFN) def test_bad_constructor_mode(self): - # Check that bad modes passed to ZipFile constructor are caught + """Check that bad modes passed to ZipFile constructor are caught.""" self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "q") def test_bad_open_mode(self): - # Check that bad modes passed to ZipFile.open are caught + """Check that bad modes passed to ZipFile.open are caught.""" with zipfile.ZipFile(TESTFN, mode="w") as zipf: zipf.writestr("foo.txt", "O, for a Muse of Fire!") @@ -735,8 +731,8 @@ self.assertRaises(RuntimeError, zipf.open, "foo.txt", "q") def test_read0(self): - # Check that calling read(0) on a ZipExtFile object returns an empty - # string and doesn't advance file pointer + """Check that calling read(0) on a ZipExtFile object returns an empty + string and doesn't advance file pointer.""" with zipfile.ZipFile(TESTFN, mode="w") as zipf: zipf.writestr("foo.txt", "O, for a Muse of Fire!") # read the data to make sure the file is there @@ -747,30 +743,32 @@ self.assertEqual(f.read(), b"O, for a Muse of Fire!") def test_open_non_existent_item(self): - # Check that attempting to call open() for an item that doesn't - # exist in the archive raises a RuntimeError + """Check that attempting to call open() for an item that doesn't + exist in the archive raises a RuntimeError.""" with zipfile.ZipFile(TESTFN, mode="w") as zipf: self.assertRaises(KeyError, zipf.open, "foo.txt", "r") def test_bad_compression_mode(self): - # Check that bad compression methods passed to ZipFile.open are caught + """Check that bad compression methods passed to ZipFile.open are + caught.""" self.assertRaises(RuntimeError, zipfile.ZipFile, TESTFN, "w", -1) def test_null_byte_in_filename(self): - # Check that a filename containing a null byte is properly terminated + """Check that a filename containing a null byte is properly + terminated.""" with zipfile.ZipFile(TESTFN, mode="w") as zipf: zipf.writestr("foo.txt\x00qqq", b"O, for a Muse of Fire!") self.assertEqual(zipf.namelist(), ['foo.txt']) def test_struct_sizes(self): - # check that ZIP internal structure sizes are calculated correctly + """Check that ZIP internal structure sizes are calculated correctly.""" self.assertEqual(zipfile.sizeEndCentDir, 22) self.assertEqual(zipfile.sizeCentralDir, 46) self.assertEqual(zipfile.sizeEndCentDir64, 56) self.assertEqual(zipfile.sizeEndCentDir64Locator, 20) def test_comments(self): - # This test checks that comments on the archive are handled properly + """Check that comments on the archive are handled properly.""" # check default comment is empty with zipfile.ZipFile(TESTFN, mode="w") as zipf: @@ -811,9 +809,9 @@ class DecryptionTests(unittest.TestCase): - # This test checks that ZIP decryption works. Since the library does not - # support encryption at the moment, we use a pre-generated encrypted - # ZIP file + """Check that ZIP decryption works. Since the library does not + support encryption at the moment, we use a pre-generated encrypted + ZIP file.""" data = ( b'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00' @@ -837,13 +835,11 @@ plain2 = b'\x00'*512 def setUp(self): - fp = open(TESTFN, "wb") - fp.write(self.data) - fp.close() + with open(TESTFN, "wb") as fp: + fp.write(self.data) self.zip = zipfile.ZipFile(TESTFN, "r") - fp = open(TESTFN2, "wb") - fp.write(self.data2) - fp.close() + with open(TESTFN2, "wb") as fp: + fp.write(self.data2) self.zip2 = zipfile.ZipFile(TESTFN2, "r") def tearDown(self): @@ -867,9 +863,9 @@ @skipUnless(zlib, "requires zlib") def test_good_password(self): self.zip.setpassword(b"python") - self.assertEquals(self.zip.read("test.txt"), self.plain) + self.assertEqual(self.zip.read("test.txt"), self.plain) self.zip2.setpassword(b"12345") - self.assertEquals(self.zip2.read("zero"), self.plain2) + self.assertEqual(self.zip2.read("zero"), self.plain2) class TestsWithRandomBinaryFiles(unittest.TestCase): @@ -879,9 +875,8 @@ for i in range(datacount)) # Make a source file with some lines - fp = open(TESTFN, "wb") - fp.write(self.data) - fp.close() + with open(TESTFN, "wb") as fp: + fp.write(self.data) def tearDown(self): unlink(TESTFN) @@ -933,8 +928,8 @@ self.assertEqual(testdata1, self.data) testdata2 = b''.join(zipdata2) - self.assertEqual(len(testdata1), len(self.data)) - self.assertEqual(testdata1, self.data) + self.assertEqual(len(testdata2), len(self.data)) + self.assertEqual(testdata2, self.data) def test_open_stored(self): for f in (TESTFN2, TemporaryFile(), io.BytesIO()): From python-checkins at python.org Thu Dec 31 14:27:41 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 31 Dec 2009 13:27:41 -0000 Subject: [Python-checkins] r77180 - python/trunk/Lib/test/test_zipfile.py Message-ID: Author: ezio.melotti Date: Thu Dec 31 14:27:41 2009 New Revision: 77180 Log: indentation and further alignment with py3k Modified: python/trunk/Lib/test/test_zipfile.py Modified: python/trunk/Lib/test/test_zipfile.py ============================================================================== --- python/trunk/Lib/test/test_zipfile.py (original) +++ python/trunk/Lib/test/test_zipfile.py Thu Dec 31 14:27:41 2009 @@ -562,10 +562,10 @@ os.mkdir(TESTFN2) try: with open(os.path.join(TESTFN2, "mod1.py"), "w") as fp: - fp.write("print 42\n") + fp.write("print(42)\n") with open(os.path.join(TESTFN2, "mod2.py"), "w") as fp: - fp.write("print 42 * 42\n") + fp.write("print(42 * 42)\n") with open(os.path.join(TESTFN2, "mod2.txt"), "w") as fp: fp.write("bla bla bla\n") @@ -869,7 +869,7 @@ def setUp(self): datacount = randint(16, 64)*1024 + randint(1, 1024) self.data = ''.join(struct.pack(' Author: ezio.melotti Date: Thu Dec 31 14:47:24 2009 New Revision: 77181 Log: #7613: missing ) in flmodule.c Modified: python/trunk/Modules/flmodule.c Modified: python/trunk/Modules/flmodule.c ============================================================================== --- python/trunk/Modules/flmodule.c (original) +++ python/trunk/Modules/flmodule.c Thu Dec 31 14:47:24 2009 @@ -156,7 +156,7 @@ } else { PyObject *a, *b; - if (!PyArg_UnpackTuple(args, "set_call_back", 2, 2, &a, &b) + if (!PyArg_UnpackTuple(args, "set_call_back", 2, 2, &a, &b)) return NULL; Py_XDECREF(g->ob_callback); Py_XDECREF(g->ob_callback_arg); From python-checkins at python.org Thu Dec 31 14:49:19 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 31 Dec 2009 13:49:19 -0000 Subject: [Python-checkins] r77182 - in python/branches/release26-maint: Modules/flmodule.c Message-ID: Author: ezio.melotti Date: Thu Dec 31 14:49:19 2009 New Revision: 77182 Log: Merged revisions 77181 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77181 | ezio.melotti | 2009-12-31 15:47:24 +0200 (Thu, 31 Dec 2009) | 1 line #7613: missing ) in flmodule.c ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Modules/flmodule.c Modified: python/branches/release26-maint/Modules/flmodule.c ============================================================================== --- python/branches/release26-maint/Modules/flmodule.c (original) +++ python/branches/release26-maint/Modules/flmodule.c Thu Dec 31 14:49:19 2009 @@ -156,7 +156,7 @@ } else { PyObject *a, *b; - if (!PyArg_UnpackTuple(args, "set_call_back", 2, 2, &a, &b) + if (!PyArg_UnpackTuple(args, "set_call_back", 2, 2, &a, &b)) return NULL; Py_XDECREF(g->ob_callback); Py_XDECREF(g->ob_callback_arg); From python-checkins at python.org Thu Dec 31 14:56:51 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 31 Dec 2009 13:56:51 -0000 Subject: [Python-checkins] r77183 - python/branches/py3k Message-ID: Author: ezio.melotti Date: Thu Dec 31 14:56:50 2009 New Revision: 77183 Log: Blocked revisions 77181 via svnmerge ........ r77181 | ezio.melotti | 2009-12-31 15:47:24 +0200 (Thu, 31 Dec 2009) | 1 line #7613: missing ) in flmodule.c ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Dec 31 14:58:03 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 31 Dec 2009 13:58:03 -0000 Subject: [Python-checkins] r77184 - python/branches/py3k Message-ID: Author: ezio.melotti Date: Thu Dec 31 14:58:03 2009 New Revision: 77184 Log: Blocked revisions 77180 via svnmerge ........ r77180 | ezio.melotti | 2009-12-31 15:27:41 +0200 (Thu, 31 Dec 2009) | 1 line indentation and further alignment with py3k ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Dec 31 17:17:05 2009 From: python-checkins at python.org (andrew.kuchling) Date: Thu, 31 Dec 2009 16:17:05 -0000 Subject: [Python-checkins] r77185 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: andrew.kuchling Date: Thu Dec 31 17:17:05 2009 New Revision: 77185 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 Thu Dec 31 17:17:05 2009 @@ -264,7 +264,9 @@ Windows, and on Unix platforms using the gcc, icc, or suncc compilers. There may be a small number of platforms where correct operation of this code cannot be guaranteed, so the code is not - used on such systems. + used on such systems. You can find out which code is being used + by checking :data:`sys.float_repr_style`, which will be ``short`` + if the new code is in use and ``legacy`` if it isn't. Implemented by Mark Dickinson, using David Gay's :file:`dtoa.c` library; :issue:`7117`. @@ -358,6 +360,10 @@ on the :exc:`IOError` exception when trying to open a directory on POSIX platforms. (Noted by Jan Kaliszewski; :issue:`4764`.) +* The Python tokenizer now translates line endings itself, so + the :func:`compile` built-in function can now accept code using + any line-ending convention + * Extra parentheses in function definitions are illegal in Python 3.x, meaning that you get a syntax error from ``def f((x)): pass``. In Python3-warning mode, Python 2.7 will now warn about this odd usage. @@ -1067,10 +1073,25 @@ (Fixed by Thomas Wouters; :issue:`1590864`.) +* The :cfunc:`Py_Finalize` function now calls the internal + :func:`threading._shutdown` function; this prevents some exceptions from + being raised when an interpreter shuts down. + (Patch by Adam Olsen; :issue:`1722344`.) + * Global symbols defined by the :mod:`ctypes` module are now prefixed with ``Py``, or with ``_ctypes``. (Implemented by Thomas Heller; :issue:`3102`.) +* New configure option: the :option:`--with-system-expat` switch allows + building the :mod:`pyexpat` module to use the system Expat library. + (Contributed by Arfrever Frehtes Taifersar Arahesis; :issue:`7609`.) + +* New configure option: Compiling Python with the + :option:`--with-valgrind` option will now disable the pymalloc + allocator, which is difficult for the Valgrind to analyze correctly. + Valgrind will therefore be better at detecting memory leaks and + overruns. (Contributed by James Henstridge; :issue:`2422`.) + * 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, @@ -1083,11 +1104,6 @@ * The build process now supports Subversion 1.7. (Contributed by Arfrever Frehtes Taifersar Arahesis; :issue:`6094`.) -* Compiling Python with the :option:`--with-valgrind` option will now - disable the pymalloc allocator, which is difficult for the Valgrind to - analyze correctly. Valgrind will therefore be better at detecting - memory leaks and overruns. (Contributed by James Henstridge; :issue:`2422`.) - .. ====================================================================== @@ -1139,12 +1155,14 @@ The :option:`-r` option also reports the seed that was used (Added by Collin Winter.) -* The :file:`regrtest.py` script now takes a :option:`-j` switch - that takes an integer specifying how many tests run in parallel. This +* Another :file:`regrtest.py` switch is :option:`-j`, which + takes an integer specifying how many tests run in parallel. This allows reducing the total runtime on multi-core machines. This option is compatible with several other options, including the :option:`-R` switch which is known to produce long runtimes. - (Added by Antoine Pitrou, :issue:`6152`.) + (Added by Antoine Pitrou, :issue:`6152`.) This can also be used + with a new :option:`-F` switch that runs selected tests in a loop + until they fail. (Added by Antoine Pitrou; :issue:`7312`.) .. ====================================================================== From python-checkins at python.org Thu Dec 31 17:28:25 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 31 Dec 2009 16:28:25 -0000 Subject: [Python-checkins] r77186 - python/trunk/setup.py Message-ID: Author: benjamin.peterson Date: Thu Dec 31 17:28:24 2009 New Revision: 77186 Log: update expat comment Modified: python/trunk/setup.py Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Thu Dec 31 17:28:24 2009 @@ -1211,12 +1211,12 @@ # Interface to the Expat XML parser # - # Expat was written by James Clark and is now maintained by a - # group of developers on SourceForge; see www.libexpat.org for - # more information. The pyexpat module was written by Paul - # Prescod after a prototype by Jack Jansen. The Expat source - # is included in Modules/expat/. Usage of a system - # shared libexpat.so/expat.dll is not advised. + # Expat was written by James Clark and is now maintained by a group of + # developers on SourceForge; see www.libexpat.org for more information. + # The pyexpat module was written by Paul Prescod after a prototype by + # Jack Jansen. The Expat source is included in Modules/expat/. Usage + # of a system shared libexpat.so is possible with --with-system-expat + # cofigure option. # # More information on Expat can be found at www.libexpat.org. # From python-checkins at python.org Thu Dec 31 17:38:53 2009 From: python-checkins at python.org (andrew.kuchling) Date: Thu, 31 Dec 2009 16:38:53 -0000 Subject: [Python-checkins] r77187 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: andrew.kuchling Date: Thu Dec 31 17:38:53 2009 New Revision: 77187 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 Thu Dec 31 17:38:53 2009 @@ -362,7 +362,7 @@ * The Python tokenizer now translates line endings itself, so the :func:`compile` built-in function can now accept code using - any line-ending convention + any line-ending convention. * Extra parentheses in function definitions are illegal in Python 3.x, meaning that you get a syntax error from ``def f((x)): pass``. In @@ -439,6 +439,8 @@ Various benchmarks show speedups of between 50% and 150% for long integer divisions and modulo operations. (Contributed by Mark Dickinson; :issue:`5512`.) + Bitwise operations are also significantly faster (initial patch by + Gregory Smith; :issue:`1087418`). * The implementation of ``%`` checks for the left-side operand being a Python string and special-cases it; this results in a 1-3% @@ -608,6 +610,10 @@ XXX link to file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata (Contributed by Tarek Ziade; :issue:`7457`.) + :file:`setup.py` files will now accept a :option:`--no-user-cfg` switch + to skip reading the :file:`~/.pydistutils.cfg` file. (Suggested by + by Michael Hoffman, and implemented by Paul Winkler; :issue:`1180`.) + * The :class:`Fraction` class now accepts two rational numbers as arguments to its constructor. (Implemented by Mark Dickinson; :issue:`5812`.) @@ -751,6 +757,10 @@ to store data. (Contributed by Tarek Ziade; :issue:`6693`.) +* The :mod:`socket` module's :class:`SSL` objects now support the + buffer API, which fixed a test suite failure. (Fixed by Antoine Pitrou; + :issue:`7133`.) + * The :mod:`SocketServer` module's :class:`TCPServer` class now has a :attr:`disable_nagle_algorithm` class attribute. The default value is False; if overridden to be True, @@ -864,6 +874,10 @@ whether the two values evaluate to the same object or not. (Added by Michael Foord; :issue:`2578`.) +* :meth:`assertIsInstance` and :meth:`assertNotIsInstance` check whether + the resulting object is an instance of a particular class, or of + one of a tuple of classes. (Added by Georg Brandl; :issue:`7031`.) + * :meth:`assertGreater`, :meth:`assertGreaterEqual`, :meth:`assertLess`, and :meth:`assertLessEqual` compare two quantities. @@ -1031,6 +1045,11 @@ a :ctype:`long`, an *overflow* flag is set and returned to the caller. (Contributed by Case Van Horsen; :issue:`7528`.) +* New function: stemming from the rewrite of string-to-float conversion, + a new :cfunc:`PyOS_string_to_double` function was added. The old + :cfunc:`PyOS_ascii_strtod` and :cfunc:`PyOS_ascii_atof` functions + are now deprecated. + * New macros: the Python header files now define the following macros: :cmacro:`Py_ISALNUM`, :cmacro:`Py_ISALPHA`, @@ -1193,6 +1212,12 @@ nothing when a negative length is requested, as other file-like objects do. (:issue:`7348`). +For C extensions: + +* Use the new :cfunc:`PyOS_string_to_double` function instead of the old + :cfunc:`PyOS_ascii_strtod` and :cfunc:`PyOS_ascii_atof` functions, + which are now deprecated. + .. ====================================================================== From python-checkins at python.org Thu Dec 31 17:49:37 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 31 Dec 2009 16:49:37 -0000 Subject: [Python-checkins] r77188 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: benjamin.peterson Date: Thu Dec 31 17:49:37 2009 New Revision: 77188 Log: add another advancement 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 Dec 31 17:49:37 2009 @@ -360,9 +360,10 @@ on the :exc:`IOError` exception when trying to open a directory on POSIX platforms. (Noted by Jan Kaliszewski; :issue:`4764`.) -* The Python tokenizer now translates line endings itself, so - the :func:`compile` built-in function can now accept code using - any line-ending convention. +* The Python tokenizer now translates line endings itself, so the + :func:`compile` built-in function can now accept code using any + line-ending convention. Additionally, it no longer requires that the + code end in a newline. * Extra parentheses in function definitions are illegal in Python 3.x, meaning that you get a syntax error from ``def f((x)): pass``. In From python-checkins at python.org Thu Dec 31 21:48:04 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 31 Dec 2009 20:48:04 -0000 Subject: [Python-checkins] r77189 - in python/trunk: configure configure.in Message-ID: Author: mark.dickinson Date: Thu Dec 31 21:48:04 2009 New Revision: 77189 Log: Add missing quotes. Modified: python/trunk/configure python/trunk/configure.in Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Thu Dec 31 21:48:04 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 77031 . +# From configure.in Revision: 77169 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -27376,7 +27376,7 @@ echo "${ECHO_T}$ac_cv_have_long_long_format" >&6; } fi -if test $ac_cv_have_long_long_format = yes +if test "$ac_cv_have_long_long_format" = yes then cat >>confdefs.h <<\_ACEOF Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Thu Dec 31 21:48:04 2009 @@ -4046,7 +4046,7 @@ AC_MSG_RESULT($ac_cv_have_long_long_format) fi -if test $ac_cv_have_long_long_format = yes +if test "$ac_cv_have_long_long_format" = yes then AC_DEFINE(PY_FORMAT_LONG_LONG, "ll", [Define to printf format modifier for long long type]) From python-checkins at python.org Thu Dec 31 21:50:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 31 Dec 2009 20:50:59 -0000 Subject: [Python-checkins] r77190 - in python/branches/py3k: configure configure.in Message-ID: Author: mark.dickinson Date: Thu Dec 31 21:50:59 2009 New Revision: 77190 Log: Merged revisions 77189 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77189 | mark.dickinson | 2009-12-31 20:48:04 +0000 (Thu, 31 Dec 2009) | 1 line Add missing quotes. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/configure python/branches/py3k/configure.in Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Thu Dec 31 21:50:59 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 77032 . +# From configure.in Revision: 77170 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -26665,7 +26665,7 @@ echo "${ECHO_T}$ac_cv_have_long_long_format" >&6; } fi -if test $ac_cv_have_long_long_format = yes +if test "$ac_cv_have_long_long_format" = yes then cat >>confdefs.h <<\_ACEOF Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Thu Dec 31 21:50:59 2009 @@ -3898,7 +3898,7 @@ AC_MSG_RESULT($ac_cv_have_long_long_format) fi -if test $ac_cv_have_long_long_format = yes +if test "$ac_cv_have_long_long_format" = yes then AC_DEFINE(PY_FORMAT_LONG_LONG, "ll", [Define to printf format modifier for long long type]) From python-checkins at python.org Thu Dec 31 21:51:54 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 31 Dec 2009 20:51:54 -0000 Subject: [Python-checkins] r77191 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Thu Dec 31 21:51:54 2009 New Revision: 77191 Log: Blocked revisions 77189 via svnmerge ........ r77189 | mark.dickinson | 2009-12-31 20:48:04 +0000 (Thu, 31 Dec 2009) | 1 line Add missing quotes. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Dec 31 21:52:48 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 31 Dec 2009 20:52:48 -0000 Subject: [Python-checkins] r77192 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Thu Dec 31 21:52:48 2009 New Revision: 77192 Log: Blocked revisions 77190 via svnmerge ................ r77190 | mark.dickinson | 2009-12-31 20:50:59 +0000 (Thu, 31 Dec 2009) | 9 lines Merged revisions 77189 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77189 | mark.dickinson | 2009-12-31 20:48:04 +0000 (Thu, 31 Dec 2009) | 1 line Add missing quotes. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Thu Dec 31 22:11:48 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 31 Dec 2009 21:11:48 -0000 Subject: [Python-checkins] r77193 - in python/trunk: configure configure.in Message-ID: Author: mark.dickinson Date: Thu Dec 31 22:11:48 2009 New Revision: 77193 Log: More configure fixes: avoid sh 'integer argument expected' error when 'long long' type doesn't exist. Modified: python/trunk/configure python/trunk/configure.in Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Thu Dec 31 22:11:48 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 77169 . +# From configure.in Revision: 77189 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -13465,8 +13465,9 @@ { echo "$as_me:$LINENO: checking whether to enable large file support" >&5 echo $ECHO_N "checking whether to enable large file support... $ECHO_C" >&6; } -if test "$have_long_long" = yes -a \ - "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ +if test "$have_long_long" = yes +then +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then cat >>confdefs.h <<\_ACEOF @@ -13479,6 +13480,10 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi { echo "$as_me:$LINENO: checking for time_t" >&5 echo $ECHO_N "checking for time_t... $ECHO_C" >&6; } @@ -21038,7 +21043,7 @@ fi -if test $have_getaddrinfo = no -o $ac_cv_buggy_getaddrinfo = yes +if test $have_getaddrinfo = no -o "$ac_cv_buggy_getaddrinfo" = yes then if test $ipv6 = yes then Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Thu Dec 31 22:11:48 2009 @@ -1457,8 +1457,9 @@ ]) AC_MSG_CHECKING(whether to enable large file support) -if test "$have_long_long" = yes -a \ - "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ +if test "$have_long_long" = yes +then +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, [Defined to enable large file support when an off_t is bigger than a long @@ -1469,6 +1470,9 @@ else AC_MSG_RESULT(no) fi +else + AC_MSG_RESULT(no) +fi AC_CHECK_SIZEOF(time_t, [], [ #ifdef HAVE_SYS_TYPES_H @@ -2967,7 +2971,7 @@ ac_cv_buggy_getaddrinfo=yes)) fi -if test $have_getaddrinfo = no -o $ac_cv_buggy_getaddrinfo = yes +if test $have_getaddrinfo = no -o "$ac_cv_buggy_getaddrinfo" = yes then if test $ipv6 = yes then From python-checkins at python.org Thu Dec 31 22:17:30 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 31 Dec 2009 21:17:30 -0000 Subject: [Python-checkins] r77194 - python/branches/release26-maint/configure Message-ID: Author: mark.dickinson Date: Thu Dec 31 22:17:29 2009 New Revision: 77194 Log: Regenerate configure using GNU autoconf 2.61. Modified: python/branches/release26-maint/configure Modified: python/branches/release26-maint/configure ============================================================================== --- python/branches/release26-maint/configure (original) +++ python/branches/release26-maint/configure Thu Dec 31 22:17:29 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 75747 . +# From configure.in Revision: 76404 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.6. # @@ -3855,7 +3855,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f -r conftest* +rm -f conftest* @@ -5394,7 +5394,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -5415,7 +5415,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -6513,7 +6513,7 @@ fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -7043,7 +7043,7 @@ else ac_cv_type_uid_t=no fi -rm -f -r conftest* +rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -14163,7 +14163,7 @@ else unistd_defines_pthreads=no fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -15777,7 +15777,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f -r conftest* +rm -f conftest* ;; kame) @@ -15800,7 +15800,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-glibc) @@ -15821,7 +15821,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-inet6) @@ -15859,7 +15859,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; v6d) @@ -15882,7 +15882,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f -r conftest* +rm -f conftest* ;; zeta) @@ -15904,7 +15904,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; esac @@ -23497,7 +23497,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -23516,7 +23516,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi @@ -23786,7 +23786,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi From python-checkins at python.org Thu Dec 31 22:20:06 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 31 Dec 2009 21:20:06 -0000 Subject: [Python-checkins] r77195 - in python/branches/release26-maint: configure configure.in Message-ID: Author: mark.dickinson Date: Thu Dec 31 22:20:06 2009 New Revision: 77195 Log: Merged revisions 77193 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77193 | mark.dickinson | 2009-12-31 21:11:48 +0000 (Thu, 31 Dec 2009) | 1 line More configure fixes: avoid sh 'integer argument expected' error when 'long long' type doesn't exist. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/configure python/branches/release26-maint/configure.in Modified: python/branches/release26-maint/configure ============================================================================== --- python/branches/release26-maint/configure (original) +++ python/branches/release26-maint/configure Thu Dec 31 22:20:06 2009 @@ -12696,8 +12696,9 @@ { echo "$as_me:$LINENO: checking whether to enable large file support" >&5 echo $ECHO_N "checking whether to enable large file support... $ECHO_C" >&6; } -if test "$have_long_long" = yes -a \ - "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ +if test "$have_long_long" = yes +then +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then cat >>confdefs.h <<\_ACEOF @@ -12710,6 +12711,10 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi # AC_CHECK_SIZEOF() doesn't include . { echo "$as_me:$LINENO: checking size of time_t" >&5 Modified: python/branches/release26-maint/configure.in ============================================================================== --- python/branches/release26-maint/configure.in (original) +++ python/branches/release26-maint/configure.in Thu Dec 31 22:20:06 2009 @@ -1448,8 +1448,9 @@ [The number of bytes in an off_t.]) AC_MSG_CHECKING(whether to enable large file support) -if test "$have_long_long" = yes -a \ - "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ +if test "$have_long_long" = yes +then +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, [Defined to enable large file support when an off_t is bigger than a long @@ -1460,6 +1461,9 @@ else AC_MSG_RESULT(no) fi +else + AC_MSG_RESULT(no) +fi # AC_CHECK_SIZEOF() doesn't include . AC_MSG_CHECKING(size of time_t) From python-checkins at python.org Thu Dec 31 22:22:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 31 Dec 2009 21:22:51 -0000 Subject: [Python-checkins] r77196 - in python/branches/py3k: configure configure.in Message-ID: Author: mark.dickinson Date: Thu Dec 31 22:22:50 2009 New Revision: 77196 Log: Merged revisions 77193 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77193 | mark.dickinson | 2009-12-31 21:11:48 +0000 (Thu, 31 Dec 2009) | 1 line More configure fixes: avoid sh 'integer argument expected' error when 'long long' type doesn't exist. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/configure python/branches/py3k/configure.in Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Thu Dec 31 22:22:50 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 77170 . +# From configure.in Revision: 77190 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -13391,8 +13391,9 @@ { echo "$as_me:$LINENO: checking whether to enable large file support" >&5 echo $ECHO_N "checking whether to enable large file support... $ECHO_C" >&6; } -if test "$have_long_long" = yes -a \ - "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ +if test "$have_long_long" = yes +then +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then cat >>confdefs.h <<\_ACEOF @@ -13405,6 +13406,10 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi { echo "$as_me:$LINENO: checking for time_t" >&5 echo $ECHO_N "checking for time_t... $ECHO_C" >&6; } @@ -20347,7 +20352,7 @@ fi -if test $have_getaddrinfo = no -o $ac_cv_buggy_getaddrinfo = yes +if test $have_getaddrinfo = no -o "$ac_cv_buggy_getaddrinfo" = yes then if test $ipv6 = yes then Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Thu Dec 31 22:22:50 2009 @@ -1396,8 +1396,9 @@ ]) AC_MSG_CHECKING(whether to enable large file support) -if test "$have_long_long" = yes -a \ - "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ +if test "$have_long_long" = yes +then +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, [Defined to enable large file support when an off_t is bigger than a long @@ -1408,6 +1409,9 @@ else AC_MSG_RESULT(no) fi +else + AC_MSG_RESULT(no) +fi AC_CHECK_SIZEOF(time_t, [], [ #ifdef HAVE_SYS_TYPES_H @@ -2837,7 +2841,7 @@ ac_cv_buggy_getaddrinfo=yes)) fi -if test $have_getaddrinfo = no -o $ac_cv_buggy_getaddrinfo = yes +if test $have_getaddrinfo = no -o "$ac_cv_buggy_getaddrinfo" = yes then if test $ipv6 = yes then From python-checkins at python.org Thu Dec 31 22:25:02 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 31 Dec 2009 21:25:02 -0000 Subject: [Python-checkins] r77197 - in python/branches/release31-maint: configure configure.in Message-ID: Author: mark.dickinson Date: Thu Dec 31 22:25:02 2009 New Revision: 77197 Log: Merged revisions 77196 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r77196 | mark.dickinson | 2009-12-31 21:22:50 +0000 (Thu, 31 Dec 2009) | 9 lines Merged revisions 77193 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r77193 | mark.dickinson | 2009-12-31 21:11:48 +0000 (Thu, 31 Dec 2009) | 1 line More configure fixes: avoid sh 'integer argument expected' error when 'long long' type doesn't exist. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/configure python/branches/release31-maint/configure.in Modified: python/branches/release31-maint/configure ============================================================================== --- python/branches/release31-maint/configure (original) +++ python/branches/release31-maint/configure Thu Dec 31 22:25:02 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76567 . +# From configure.in Revision: 76821 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -13033,8 +13033,9 @@ { echo "$as_me:$LINENO: checking whether to enable large file support" >&5 echo $ECHO_N "checking whether to enable large file support... $ECHO_C" >&6; } -if test "$have_long_long" = yes -a \ - "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ +if test "$have_long_long" = yes +then +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then cat >>confdefs.h <<\_ACEOF @@ -13047,6 +13048,10 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi # AC_CHECK_SIZEOF() doesn't include . { echo "$as_me:$LINENO: checking size of time_t" >&5 Modified: python/branches/release31-maint/configure.in ============================================================================== --- python/branches/release31-maint/configure.in (original) +++ python/branches/release31-maint/configure.in Thu Dec 31 22:25:02 2009 @@ -1415,8 +1415,9 @@ [The number of bytes in an off_t.]) AC_MSG_CHECKING(whether to enable large file support) -if test "$have_long_long" = yes -a \ - "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ +if test "$have_long_long" = yes +then +if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, [Defined to enable large file support when an off_t is bigger than a long @@ -1427,6 +1428,9 @@ else AC_MSG_RESULT(no) fi +else + AC_MSG_RESULT(no) +fi # AC_CHECK_SIZEOF() doesn't include . AC_MSG_CHECKING(size of time_t)