From python-checkins at python.org Tue Jun 1 00:57:25 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 1 Jun 2010 00:57:25 +0200 (CEST) Subject: [Python-checkins] r81626 - in python/branches/release26-maint: Doc/extending/newtypes.rst Message-ID: <20100531225725.28F08EE988@mail.python.org> Author: r.david.murray Date: Tue Jun 1 00:57:24 2010 New Revision: 81626 Log: Merged revisions 81586 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81586 | r.david.murray | 2010-05-28 14:08:11 -0400 (Fri, 28 May 2010) | 2 lines Make reference to Generic Attribute Management a hyperlink. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/extending/newtypes.rst Modified: python/branches/release26-maint/Doc/extending/newtypes.rst ============================================================================== --- python/branches/release26-maint/Doc/extending/newtypes.rst (original) +++ python/branches/release26-maint/Doc/extending/newtypes.rst Tue Jun 1 00:57:24 2010 @@ -446,7 +446,7 @@ Noddy_members, /* tp_members */ Each member definition has a member name, type, offset, access flags and -documentation string. See the "Generic Attribute Management" section below for +documentation string. See the :ref:`Generic-Attribute-Management` section below for details. A disadvantage of this approach is that it doesn't provide a way to restrict the @@ -1129,6 +1129,8 @@ not been updated to use some of the new generic mechanism that is available. +.. _generic-attribute-management: + Generic Attribute Management ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From python-checkins at python.org Tue Jun 1 01:06:41 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 1 Jun 2010 01:06:41 +0200 (CEST) Subject: [Python-checkins] r81627 - python/branches/release26-maint Message-ID: <20100531230641.AF813EE999@mail.python.org> Author: r.david.murray Date: Tue Jun 1 01:06:41 2010 New Revision: 81627 Log: Blocked revisions 81587 via svnmerge ........ r81587 | r.david.murray | 2010-05-28 14:17:20 -0400 (Fri, 28 May 2010) | 2 lines Make the ctl-C shutdown of serve.py prettier. ........ Modified: python/branches/release26-maint/ (props changed) From solipsis at pitrou.net Tue Jun 1 01:23:40 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 1 Jun 2010 01:23:40 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81625): sum=0 Message-ID: <20100531232340.506D11770A@ns6635.ovh.net> py3k results for svn r81625 (hg cset d3879c2afa33) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog2jS3Oo', '-x'] From python-checkins at python.org Tue Jun 1 01:23:50 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 1 Jun 2010 01:23:50 +0200 (CEST) Subject: [Python-checkins] r81628 - in python/branches/py3k: Tools/scripts/serve.py Message-ID: <20100531232350.5E030EE9F0@mail.python.org> Author: r.david.murray Date: Tue Jun 1 01:23:50 2010 New Revision: 81628 Log: Merged revisions 81587 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81587 | r.david.murray | 2010-05-28 14:17:20 -0400 (Fri, 28 May 2010) | 2 lines Make the ctl-C shutdown of serve.py prettier. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Tools/scripts/serve.py Modified: python/branches/py3k/Tools/scripts/serve.py ============================================================================== --- python/branches/py3k/Tools/scripts/serve.py (original) +++ python/branches/py3k/Tools/scripts/serve.py Tue Jun 1 01:23:50 2010 @@ -28,5 +28,8 @@ path = sys.argv[1] port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000 httpd = simple_server.make_server('', port, app) - print("Serving {} on port {}".format(path, port)) - httpd.serve_forever() + print("Serving {} on port {}, control-C to stop".format(path, port)) + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("\b\bShutting down.") From python-checkins at python.org Tue Jun 1 03:04:16 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 1 Jun 2010 03:04:16 +0200 (CEST) Subject: [Python-checkins] r81629 - python/branches/release31-maint Message-ID: <20100601010416.51DE9EE9B5@mail.python.org> Author: r.david.murray Date: Tue Jun 1 03:04:14 2010 New Revision: 81629 Log: Blocked revisions 81628 via svnmerge ................ r81628 | r.david.murray | 2010-05-31 19:23:50 -0400 (Mon, 31 May 2010) | 9 lines Merged revisions 81587 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81587 | r.david.murray | 2010-05-28 14:17:20 -0400 (Fri, 28 May 2010) | 2 lines Make the ctl-C shutdown of serve.py prettier. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Tue Jun 1 03:11:18 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 1 Jun 2010 03:11:18 +0200 (CEST) Subject: [Python-checkins] r81630 - in python/branches/py3k: Doc/extending/newtypes.rst Message-ID: <20100601011118.4163AEE9A4@mail.python.org> Author: r.david.murray Date: Tue Jun 1 03:11:18 2010 New Revision: 81630 Log: Merged revisions 81586 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81586 | r.david.murray | 2010-05-28 14:08:11 -0400 (Fri, 28 May 2010) | 2 lines Make reference to Generic Attribute Management a hyperlink. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/extending/newtypes.rst Modified: python/branches/py3k/Doc/extending/newtypes.rst ============================================================================== --- python/branches/py3k/Doc/extending/newtypes.rst (original) +++ python/branches/py3k/Doc/extending/newtypes.rst Tue Jun 1 03:11:18 2010 @@ -430,7 +430,7 @@ Noddy_members, /* tp_members */ Each member definition has a member name, type, offset, access flags and -documentation string. See the "Generic Attribute Management" section below for +documentation string. See the :ref:`Generic-Attribute-Management` section below for details. A disadvantage of this approach is that it doesn't provide a way to restrict the @@ -1078,6 +1078,8 @@ not been updated to use some of the new generic mechanism that is available. +.. _generic-attribute-management: + Generic Attribute Management ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From python-checkins at python.org Tue Jun 1 03:12:24 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 1 Jun 2010 03:12:24 +0200 (CEST) Subject: [Python-checkins] r81631 - in python/branches/release31-maint: Doc/extending/newtypes.rst Message-ID: <20100601011224.76AECEE9A4@mail.python.org> Author: r.david.murray Date: Tue Jun 1 03:12:24 2010 New Revision: 81631 Log: Merged revisions 81630 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81630 | r.david.murray | 2010-05-31 21:11:18 -0400 (Mon, 31 May 2010) | 9 lines Merged revisions 81586 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81586 | r.david.murray | 2010-05-28 14:08:11 -0400 (Fri, 28 May 2010) | 2 lines Make reference to Generic Attribute Management a hyperlink. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/extending/newtypes.rst Modified: python/branches/release31-maint/Doc/extending/newtypes.rst ============================================================================== --- python/branches/release31-maint/Doc/extending/newtypes.rst (original) +++ python/branches/release31-maint/Doc/extending/newtypes.rst Tue Jun 1 03:12:24 2010 @@ -430,7 +430,7 @@ Noddy_members, /* tp_members */ Each member definition has a member name, type, offset, access flags and -documentation string. See the "Generic Attribute Management" section below for +documentation string. See the :ref:`Generic-Attribute-Management` section below for details. A disadvantage of this approach is that it doesn't provide a way to restrict the @@ -1078,6 +1078,8 @@ not been updated to use some of the new generic mechanism that is available. +.. _generic-attribute-management: + Generic Attribute Management ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From python-checkins at python.org Tue Jun 1 03:32:12 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 1 Jun 2010 03:32:12 +0200 (CEST) Subject: [Python-checkins] r81632 - in python/branches/py3k: Doc/library/sqlite3.rst Doc/whatsnew/3.2.rst Lib/sqlite3/test/dbapi.py Misc/ACKS Misc/NEWS Modules/_sqlite/connection.c Message-ID: <20100601013212.5F6EBEE983@mail.python.org> Author: r.david.murray Date: Tue Jun 1 03:32:12 2010 New Revision: 81632 Log: #8845: expose sqlite3 inTransaction as RO in_transaction Connection attribute. Patch by R. David Murray, unit tests by Shashwat Anand. Modified: python/branches/py3k/Doc/library/sqlite3.rst python/branches/py3k/Doc/whatsnew/3.2.rst python/branches/py3k/Lib/sqlite3/test/dbapi.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_sqlite/connection.c Modified: python/branches/py3k/Doc/library/sqlite3.rst ============================================================================== --- python/branches/py3k/Doc/library/sqlite3.rst (original) +++ python/branches/py3k/Doc/library/sqlite3.rst Tue Jun 1 03:32:12 2010 @@ -227,6 +227,13 @@ one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". See section :ref:`sqlite3-controlling-transactions` for a more detailed explanation. +.. attribute:: Connection.in_transaction + + .. versionadded:: 3.2 + + :cont:`True` if a transaction is active (there are uncommitted changes), + :const:`False` otherwise. Read-only attribute. + .. method:: Connection.cursor([cursorClass]) @@ -806,7 +813,8 @@ before executing that command. There are two reasons for doing that. The first is that some of these commands don't work within transactions. The other reason is that sqlite3 needs to keep track of the transaction state (if a transaction -is active or not). +is active or not). The current transaction state is exposed through the +:attr:`Connection.in_transaction` attribute of the connection object. You can control which kind of ``BEGIN`` statements sqlite3 implicitly executes (or none at all) via the *isolation_level* parameter to the :func:`connect` Modified: python/branches/py3k/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.2.rst Tue Jun 1 03:32:12 2010 @@ -100,6 +100,18 @@ (Contributed by Tarek Ziade.) +* The *sqlite3* module has some new features: + + * XXX *enable_load_extension* + + * XXX *load_extension* + + * New :class:`~sqlite3.Connection` attribute + :attr:`~sqlite3.Connection.in_transaction` is :const:`True` when there + are uncommitted changes, and :const:`False` otherwise. (Contributed + by R. David Murray and Shashwat Anand, :issue:`8845`.) + + Multi-threading =============== Modified: python/branches/py3k/Lib/sqlite3/test/dbapi.py ============================================================================== --- python/branches/py3k/Lib/sqlite3/test/dbapi.py (original) +++ python/branches/py3k/Lib/sqlite3/test/dbapi.py Tue Jun 1 03:32:12 2010 @@ -84,6 +84,7 @@ "NotSupportedError is not a subclass of DatabaseError") class ConnectionTests(unittest.TestCase): + def setUp(self): self.cx = sqlite.connect(":memory:") cu = self.cx.cursor() @@ -140,6 +141,28 @@ self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError) self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError) + def CheckInTransaction(self): + # Can't use db from setUp because we want to test initial state. + cx = sqlite.connect(":memory:") + cu = cx.cursor() + self.assertEqual(cx.in_transaction, False) + cu.execute("create table transactiontest(id integer primary key, name text)") + self.assertEqual(cx.in_transaction, False) + cu.execute("insert into transactiontest(name) values (?)", ("foo",)) + self.assertEqual(cx.in_transaction, True) + cu.execute("select name from transactiontest where name=?", ["foo"]) + row = cu.fetchone() + self.assertEqual(cx.in_transaction, True) + cx.commit() + self.assertEqual(cx.in_transaction, False) + cu.execute("select name from transactiontest where name=?", ["foo"]) + row = cu.fetchone() + self.assertEqual(cx.in_transaction, False) + + def CheckInTransactionRO(self): + with self.assertRaises(AttributeError): + self.cx.in_transaction = True + class CursorTests(unittest.TestCase): def setUp(self): self.cx = sqlite.connect(":memory:") Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Tue Jun 1 03:32:12 2010 @@ -19,6 +19,7 @@ Kevin Altis Joe Amenta Mark Anacker +Shashwat Anand Anders Andersen John Anderson Erik Anders?n Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Jun 1 03:32:12 2010 @@ -398,6 +398,9 @@ Library ------- +- Issue #8845: sqlite3 Connection objects now have a read-only in_transaction + attribute that is True iff there are uncommitted changes. + - Issue #1289118: datetime.timedelta objects can now be multiplied by float and divided by float and int objects. Results are rounded to the nearest multiple of timedelta.resolution with ties resolved using round-half-to-even Modified: python/branches/py3k/Modules/_sqlite/connection.c ============================================================================== --- python/branches/py3k/Modules/_sqlite/connection.c (original) +++ python/branches/py3k/Modules/_sqlite/connection.c Tue Jun 1 03:32:12 2010 @@ -23,6 +23,7 @@ #include "cache.h" #include "module.h" +#include "structmember.h" #include "connection.h" #include "statement.h" #include "cursor.h" @@ -1551,6 +1552,7 @@ {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY}, {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, + {"in_transaction", T_BOOL, offsetof(pysqlite_Connection, inTransaction), READONLY}, {NULL} }; From python-checkins at python.org Tue Jun 1 03:33:31 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 1 Jun 2010 03:33:31 +0200 (CEST) Subject: [Python-checkins] r81633 - python/branches/release31-maint Message-ID: <20100601013331.6E871EE983@mail.python.org> Author: r.david.murray Date: Tue Jun 1 03:33:31 2010 New Revision: 81633 Log: Blocked revisions 81632 via svnmerge ........ r81632 | r.david.murray | 2010-05-31 21:32:12 -0400 (Mon, 31 May 2010) | 4 lines #8845: expose sqlite3 inTransaction as RO in_transaction Connection attribute. Patch by R. David Murray, unit tests by Shashwat Anand. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Tue Jun 1 03:42:41 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 1 Jun 2010 03:42:41 +0200 (CEST) Subject: [Python-checkins] r81634 - python/trunk/Doc/library/doctest.rst Message-ID: <20100601014241.D221DEE9AE@mail.python.org> Author: r.david.murray Date: Tue Jun 1 03:42:41 2010 New Revision: 81634 Log: #7583: clarify discussion of hard tab expansion in doctests. Modified: python/trunk/Doc/library/doctest.rst Modified: python/trunk/Doc/library/doctest.rst ============================================================================== --- python/trunk/Doc/library/doctest.rst (original) +++ python/trunk/Doc/library/doctest.rst Tue Jun 1 03:42:41 2010 @@ -299,15 +299,8 @@ How are Docstring Examples Recognized? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In most cases a copy-and-paste of an interactive console session works fine, but -doctest isn't trying to do an exact emulation of any specific Python shell. All -hard tab characters are expanded to spaces, using 8-column tab stops. If you -don't believe tabs should mean that, too bad: don't use hard tabs, or write -your own :class:`DocTestParser` class. - -.. versionchanged:: 2.4 - Expanding tabs to spaces is new; previous versions tried to preserve hard tabs, - with confusing results. +In most cases a copy-and-paste of an interactive console session works fine, +but doctest isn't trying to do an exact emulation of any specific Python shell. :: @@ -342,6 +335,21 @@ ```` was added; there was no way to use expected output containing empty lines in previous versions. +* All hard tab characters are expanded to spaces, using 8-column tab stops. + Tabs in output generated by the tested code are not modified. Because any + hard tabs in the sample output *are* expanded, this means that if the code + output includes hard tabs, the only way the doctest can pass is if the + :const:`NORMALIZE_WHITESPACE` option or directive is in effect. + Alternatively, the test can be rewritten to capture the output and compare it + to an expected value as part of the test. This handling of tabs in the + source was arrived at through trial and error, and has proven to be the least + error prone way of handling them. It is possible to use a different + algorithm for handling tabs by writing a custom :class:`DocTestParser` class. + + .. versionchanged:: 2.4 + Expanding tabs to spaces is new; previous versions tried to preserve hard tabs, + with confusing results. + * Output to stdout is captured, but not output to stderr (exception tracebacks are captured via a different means). @@ -1872,4 +1880,3 @@ .. [#] Examples containing both expected output and an exception are not supported. Trying to guess where one ends and the other begins is too error-prone, and that also makes for a confusing test. - From python-checkins at python.org Tue Jun 1 09:25:23 2010 From: python-checkins at python.org (georg.brandl) Date: Tue, 1 Jun 2010 09:25:23 +0200 (CEST) Subject: [Python-checkins] r81635 - python/trunk/Doc/library/re.rst Message-ID: <20100601072523.4F22EEE98C@mail.python.org> Author: georg.brandl Date: Tue Jun 1 09:25:23 2010 New Revision: 81635 Log: Put docs for RegexObject.search() before RegexObject.match() to mirror re.search() and re.match() order. Modified: python/trunk/Doc/library/re.rst Modified: python/trunk/Doc/library/re.rst ============================================================================== --- python/trunk/Doc/library/re.rst (original) +++ python/trunk/Doc/library/re.rst Tue Jun 1 09:25:23 2010 @@ -689,18 +689,12 @@ The :class:`RegexObject` class supports the following methods and attributes: + .. method:: RegexObject.search(string[, pos[, endpos]]) - .. method:: RegexObject.match(string[, pos[, endpos]]) - - If zero or more characters at the beginning of *string* match this regular - expression, return a corresponding :class:`MatchObject` instance. Return - ``None`` if the string does not match the pattern; note that this is different - from a zero-length match. - - .. note:: - - If you want to locate a match anywhere in *string*, use - :meth:`~RegexObject.search` instead. + Scan through *string* looking for a location where this regular expression + produces a match, and return a corresponding :class:`MatchObject` instance. + Return ``None`` if no position in the string matches the pattern; note that this + is different from finding a zero-length match at some point in the string. The optional second parameter *pos* gives an index in the string where the search is to start; it defaults to ``0``. This is not completely equivalent to @@ -712,24 +706,34 @@ will be as if the string is *endpos* characters long, so only the characters from *pos* to ``endpos - 1`` will be searched for a match. If *endpos* is less than *pos*, no match will be found, otherwise, if *rx* is a compiled regular - expression object, ``rx.match(string, 0, 50)`` is equivalent to - ``rx.match(string[:50], 0)``. + expression object, ``rx.search(string, 0, 50)`` is equivalent to + ``rx.search(string[:50], 0)``. - >>> pattern = re.compile("o") - >>> pattern.match("dog") # No match as "o" is not at the start of "dog." - >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog". - <_sre.SRE_Match object at ...> + >>> pattern = re.compile("d") + >>> pattern.search("dog") # Match at index 0 + <_sre.SRE_Match object at ...> + >>> pattern.search("dog", 1) # No match; search doesn't include the "d" - .. method:: RegexObject.search(string[, pos[, endpos]]) + .. method:: RegexObject.match(string[, pos[, endpos]]) - Scan through *string* looking for a location where this regular expression - produces a match, and return a corresponding :class:`MatchObject` instance. - Return ``None`` if no position in the string matches the pattern; note that this - is different from finding a zero-length match at some point in the string. + If zero or more characters at the *beginning* of *string* match this regular + expression, return a corresponding :class:`MatchObject` instance. Return + ``None`` if the string does not match the pattern; note that this is different + from a zero-length match. The optional *pos* and *endpos* parameters have the same meaning as for the - :meth:`~RegexObject.match` method. + :meth:`~RegexObject.search` method. + + .. note:: + + If you want to locate a match anywhere in *string*, use + :meth:`~RegexObject.search` instead. + + >>> pattern = re.compile("o") + >>> pattern.match("dog") # No match as "o" is not at the start of "dog". + >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog". + <_sre.SRE_Match object at ...> .. method:: RegexObject.split(string[, maxsplit=0]) From python-checkins at python.org Tue Jun 1 14:40:07 2010 From: python-checkins at python.org (senthil.kumaran) Date: Tue, 1 Jun 2010 14:40:07 +0200 (CEST) Subject: [Python-checkins] r81636 - in python/trunk/Lib: test/test_urllib2.py urllib2.py Message-ID: <20100601124007.DE6FBF004@mail.python.org> Author: senthil.kumaran Date: Tue Jun 1 14:40:07 2010 New Revision: 81636 Log: Fix Issue8797 - urllib2 basic authentication fix for wrong passwords. It fails after 5 retries. Modified: python/trunk/Lib/test/test_urllib2.py python/trunk/Lib/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 Tue Jun 1 14:40:07 2010 @@ -1143,7 +1143,6 @@ self.assertEqual(len(http_handler.requests), 1) self.assertFalse(http_handler.requests[0].has_header(auth_header)) - class MiscTests(unittest.TestCase): def test_build_opener(self): Modified: python/trunk/Lib/urllib2.py ============================================================================== --- python/trunk/Lib/urllib2.py (original) +++ python/trunk/Lib/urllib2.py Tue Jun 1 14:40:07 2010 @@ -819,12 +819,21 @@ password_mgr = HTTPPasswordMgr() self.passwd = password_mgr self.add_password = self.passwd.add_password + self.retried = 0 def http_error_auth_reqed(self, authreq, host, req, headers): # host may be an authority (without userinfo) or a URL with an # authority # XXX could be multiple headers authreq = headers.get(authreq, None) + + if self.retried > 5: + # retry sending the username:password 5 times before failing. + raise HTTPError(req.get_full_url(), 401, "basic auth failed", + headers, None) + else: + self.retried += 1 + if authreq: mo = AbstractBasicAuthHandler.rx.search(authreq) if mo: From python-checkins at python.org Tue Jun 1 14:42:45 2010 From: python-checkins at python.org (senthil.kumaran) Date: Tue, 1 Jun 2010 14:42:45 +0200 (CEST) Subject: [Python-checkins] r81637 - in python/branches/release26-maint: Lib/test/test_urllib2.py Lib/urllib2.py Message-ID: <20100601124245.244A6F079@mail.python.org> Author: senthil.kumaran Date: Tue Jun 1 14:42:44 2010 New Revision: 81637 Log: Merged revisions 81636 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81636 | senthil.kumaran | 2010-06-01 18:10:07 +0530 (Tue, 01 Jun 2010) | 3 lines Fix Issue8797 - urllib2 basic authentication fix for wrong passwords. It fails after 5 retries. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_urllib2.py python/branches/release26-maint/Lib/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 Tue Jun 1 14:42:44 2010 @@ -1145,7 +1145,6 @@ self.assertEqual(len(http_handler.requests), 1) self.assertFalse(http_handler.requests[0].has_header(auth_header)) - class MiscTests(unittest.TestCase): def test_build_opener(self): Modified: python/branches/release26-maint/Lib/urllib2.py ============================================================================== --- python/branches/release26-maint/Lib/urllib2.py (original) +++ python/branches/release26-maint/Lib/urllib2.py Tue Jun 1 14:42:44 2010 @@ -819,12 +819,21 @@ password_mgr = HTTPPasswordMgr() self.passwd = password_mgr self.add_password = self.passwd.add_password + self.retried = 0 def http_error_auth_reqed(self, authreq, host, req, headers): # host may be an authority (without userinfo) or a URL with an # authority # XXX could be multiple headers authreq = headers.get(authreq, None) + + if self.retried > 5: + # retry sending the username:password 5 times before failing. + raise HTTPError(req.get_full_url(), 401, "basic auth failed", + headers, None) + else: + self.retried += 1 + if authreq: mo = AbstractBasicAuthHandler.rx.search(authreq) if mo: From python-checkins at python.org Tue Jun 1 14:53:48 2010 From: python-checkins at python.org (senthil.kumaran) Date: Tue, 1 Jun 2010 14:53:48 +0200 (CEST) Subject: [Python-checkins] r81638 - in python/branches/py3k: Lib/test/test_urllib2.py Lib/urllib/request.py Message-ID: <20100601125348.613CDEE981@mail.python.org> Author: senthil.kumaran Date: Tue Jun 1 14:53:48 2010 New Revision: 81638 Log: Merged revisions 81636 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81636 | senthil.kumaran | 2010-06-01 18:10:07 +0530 (Tue, 01 Jun 2010) | 3 lines Fix Issue8797 - urllib2 basic authentication fix for wrong passwords. It fails after 5 retries. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_urllib2.py python/branches/py3k/Lib/urllib/request.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 Tue Jun 1 14:53:48 2010 @@ -1151,7 +1151,6 @@ self.assertEqual(len(http_handler.requests), 1) self.assertFalse(http_handler.requests[0].has_header(auth_header)) - class MiscTests(unittest.TestCase): def test_build_opener(self): Modified: python/branches/py3k/Lib/urllib/request.py ============================================================================== --- python/branches/py3k/Lib/urllib/request.py (original) +++ python/branches/py3k/Lib/urllib/request.py Tue Jun 1 14:53:48 2010 @@ -775,12 +775,21 @@ password_mgr = HTTPPasswordMgr() self.passwd = password_mgr self.add_password = self.passwd.add_password + self.retried = 0 def http_error_auth_reqed(self, authreq, host, req, headers): # host may be an authority (without userinfo) or a URL with an # authority # XXX could be multiple headers authreq = headers.get(authreq, None) + + if self.retried > 5: + # retry sending the username:password 5 times before failing. + raise HTTPError(req.get_full_url(), 401, "basic auth failed", + headers, None) + else: + self.retried += 1 + if authreq: mo = AbstractBasicAuthHandler.rx.search(authreq) if mo: From python-checkins at python.org Tue Jun 1 14:56:17 2010 From: python-checkins at python.org (senthil.kumaran) Date: Tue, 1 Jun 2010 14:56:17 +0200 (CEST) Subject: [Python-checkins] r81639 - in python/branches/release31-maint: Lib/test/test_urllib2.py Lib/urllib/request.py Message-ID: <20100601125617.D7E2CDCC3@mail.python.org> Author: senthil.kumaran Date: Tue Jun 1 14:56:17 2010 New Revision: 81639 Log: Merged revisions 81638 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81638 | senthil.kumaran | 2010-06-01 18:23:48 +0530 (Tue, 01 Jun 2010) | 9 lines Merged revisions 81636 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81636 | senthil.kumaran | 2010-06-01 18:10:07 +0530 (Tue, 01 Jun 2010) | 3 lines Fix Issue8797 - urllib2 basic authentication fix for wrong passwords. It fails after 5 retries. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_urllib2.py python/branches/release31-maint/Lib/urllib/request.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 Tue Jun 1 14:56:17 2010 @@ -1156,7 +1156,6 @@ self.assertEqual(len(http_handler.requests), 1) self.assertFalse(http_handler.requests[0].has_header(auth_header)) - class MiscTests(unittest.TestCase): def test_build_opener(self): 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 Tue Jun 1 14:56:17 2010 @@ -775,12 +775,21 @@ password_mgr = HTTPPasswordMgr() self.passwd = password_mgr self.add_password = self.passwd.add_password + self.retried = 0 def http_error_auth_reqed(self, authreq, host, req, headers): # host may be an authority (without userinfo) or a URL with an # authority # XXX could be multiple headers authreq = headers.get(authreq, None) + + if self.retried > 5: + # retry sending the username:password 5 times before failing. + raise HTTPError(req.get_full_url(), 401, "basic auth failed", + headers, None) + else: + self.retried += 1 + if authreq: mo = AbstractBasicAuthHandler.rx.search(authreq) if mo: From python-checkins at python.org Tue Jun 1 15:29:13 2010 From: python-checkins at python.org (brian.curtin) Date: Tue, 1 Jun 2010 15:29:13 +0200 (CEST) Subject: [Python-checkins] r81640 - python/trunk/Lib/test/test_winsound.py Message-ID: <20100601132913.B7398EE981@mail.python.org> Author: brian.curtin Date: Tue Jun 1 15:29:13 2010 New Revision: 81640 Log: Fix #8618. Ask the Windows mixer API if there are any playback devices configured before attempting to test PlaySound. Modified: python/trunk/Lib/test/test_winsound.py Modified: python/trunk/Lib/test/test_winsound.py ============================================================================== --- python/trunk/Lib/test/test_winsound.py (original) +++ python/trunk/Lib/test/test_winsound.py Tue Jun 1 15:29:13 2010 @@ -5,6 +5,7 @@ import time import os import subprocess +import ctypes winsound = test_support.import_module('winsound') import _winreg @@ -12,6 +13,11 @@ def has_sound(sound): """Find out if a particular event is configured with a default sound""" try: + # Ask the mixer API for the number of devices it knows about. + # When there are no devices, PlaySound will fail. + if ctypes.windll.winmm.mixerGetNumDevs() is 0: + return False + key = _winreg.OpenKeyEx(_winreg.HKEY_CURRENT_USER, "AppEvents\Schemes\Apps\.Default\{0}\.Default".format(sound)) value = _winreg.EnumValue(key, 0)[1] From python-checkins at python.org Tue Jun 1 15:42:48 2010 From: python-checkins at python.org (brian.curtin) Date: Tue, 1 Jun 2010 15:42:48 +0200 (CEST) Subject: [Python-checkins] r81641 - in python/branches/release26-maint: Lib/test/test_winsound.py Message-ID: <20100601134248.6AE5CEE981@mail.python.org> Author: brian.curtin Date: Tue Jun 1 15:42:48 2010 New Revision: 81641 Log: Merged revisions 81640 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81640 | brian.curtin | 2010-06-01 08:29:13 -0500 (Tue, 01 Jun 2010) | 3 lines Fix #8618. Ask the Windows mixer API if there are any playback devices configured before attempting to test PlaySound. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_winsound.py Modified: python/branches/release26-maint/Lib/test/test_winsound.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_winsound.py (original) +++ python/branches/release26-maint/Lib/test/test_winsound.py Tue Jun 1 15:42:48 2010 @@ -2,15 +2,23 @@ import unittest from test import test_support -import winsound, time +import time import os import subprocess +import ctypes + +winsound = test_support.import_module('winsound') import _winreg def has_sound(sound): """Find out if a particular event is configured with a default sound""" try: + # Ask the mixer API for the number of devices it knows about. + # When there are no devices, PlaySound will fail. + if ctypes.windll.winmm.mixerGetNumDevs() is 0: + return False + key = _winreg.OpenKeyEx(_winreg.HKEY_CURRENT_USER, "AppEvents\Schemes\Apps\.Default\{0}\.Default".format(sound)) value = _winreg.EnumValue(key, 0)[1] From python-checkins at python.org Tue Jun 1 15:49:19 2010 From: python-checkins at python.org (brian.curtin) Date: Tue, 1 Jun 2010 15:49:19 +0200 (CEST) Subject: [Python-checkins] r81642 - in python/branches/py3k: Lib/test/test_winsound.py Message-ID: <20100601134919.D87BEEE999@mail.python.org> Author: brian.curtin Date: Tue Jun 1 15:49:19 2010 New Revision: 81642 Log: Merged revisions 81640 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81640 | brian.curtin | 2010-06-01 08:29:13 -0500 (Tue, 01 Jun 2010) | 3 lines Fix #8618. Ask the Windows mixer API if there are any playback devices configured before attempting to test PlaySound. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_winsound.py Modified: python/branches/py3k/Lib/test/test_winsound.py ============================================================================== --- python/branches/py3k/Lib/test/test_winsound.py (original) +++ python/branches/py3k/Lib/test/test_winsound.py Tue Jun 1 15:49:19 2010 @@ -6,6 +6,7 @@ import time import os import subprocess +import ctypes winsound = support.import_module('winsound') import winreg @@ -13,6 +14,11 @@ def has_sound(sound): """Find out if a particular event is configured with a default sound""" try: + # Ask the mixer API for the number of devices it knows about. + # When there are no devices, PlaySound will fail. + if ctypes.windll.winmm.mixerGetNumDevs() is 0: + return False + key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, "AppEvents\Schemes\Apps\.Default\{0}\.Default".format(sound)) value = winreg.EnumValue(key, 0)[1] From python-checkins at python.org Tue Jun 1 15:52:18 2010 From: python-checkins at python.org (brian.curtin) Date: Tue, 1 Jun 2010 15:52:18 +0200 (CEST) Subject: [Python-checkins] r81643 - in python/branches/release31-maint: Lib/test/test_winsound.py Message-ID: <20100601135218.9FB9EEFE5@mail.python.org> Author: brian.curtin Date: Tue Jun 1 15:52:18 2010 New Revision: 81643 Log: Merged revisions 81642 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81642 | brian.curtin | 2010-06-01 08:49:19 -0500 (Tue, 01 Jun 2010) | 10 lines Merged revisions 81640 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81640 | brian.curtin | 2010-06-01 08:29:13 -0500 (Tue, 01 Jun 2010) | 3 lines Fix #8618. Ask the Windows mixer API if there are any playback devices configured before attempting to test PlaySound. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_winsound.py Modified: python/branches/release31-maint/Lib/test/test_winsound.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_winsound.py (original) +++ python/branches/release31-maint/Lib/test/test_winsound.py Tue Jun 1 15:52:18 2010 @@ -6,6 +6,7 @@ import time import os import subprocess +import ctypes winsound = support.import_module('winsound') import winreg @@ -13,6 +14,11 @@ def has_sound(sound): """Find out if a particular event is configured with a default sound""" try: + # Ask the mixer API for the number of devices it knows about. + # When there are no devices, PlaySound will fail. + if ctypes.windll.winmm.mixerGetNumDevs() is 0: + return False + key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, "AppEvents\Schemes\Apps\.Default\{0}\.Default".format(sound)) value = winreg.EnumValue(key, 0)[1] From python-checkins at python.org Wed Jun 2 01:18:23 2010 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Jun 2010 01:18:23 +0200 Subject: [Python-checkins] distutils2: Silence two py3k deprecation warnings and fix a bug. Message-ID: tarek.ziade pushed ce0d6be25d09 to distutils2: http://hg.python.org/distutils2/rev/ce0d6be25d09 changeset: 191:ce0d6be25d09 user: ?ric Araujo date: Mon May 31 23:03:46 2010 +0200 summary: Silence two py3k deprecation warnings and fix a bug. files: src/distutils2/tests/test_upload.py, src/distutils2/version.py diff --git a/src/distutils2/tests/test_upload.py b/src/distutils2/tests/test_upload.py --- a/src/distutils2/tests/test_upload.py +++ b/src/distutils2/tests/test_upload.py @@ -116,7 +116,7 @@ # what did we send ? self.assertIn('d??d??', self.last_open.req.data) headers = dict(self.last_open.req.headers) - self.assertTrue(headers['Content-length'] > 2000) + self.assertTrue(int(headers['Content-length']) < 2000) self.assertTrue(headers['Content-type'].startswith('multipart/form-data')) self.assertEquals(self.last_open.req.get_method(), 'POST') self.assertEquals(self.last_open.req.get_full_url(), diff --git a/src/distutils2/version.py b/src/distutils2/version.py --- a/src/distutils2/version.py +++ b/src/distutils2/version.py @@ -197,6 +197,9 @@ def __ge__(self, other): return self.__eq__(other) or self.__gt__(other) + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + def suggest_normalized_version(s): """Suggest a normalized version close to the given version string. -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Wed Jun 2 01:18:23 2010 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Jun 2010 01:18:23 +0200 Subject: [Python-checkins] distutils2: Use Mercurial command-line API instead of Python internals. Message-ID: tarek.ziade pushed 0e17b47e7ab2 to distutils2: http://hg.python.org/distutils2/rev/0e17b47e7ab2 changeset: 193:0e17b47e7ab2 user: ?ric Araujo date: Tue Jun 01 15:12:25 2010 +0200 summary: Use Mercurial command-line API instead of Python internals. files: src/setup.py diff --git a/src/setup.py b/src/setup.py --- a/src/setup.py +++ b/src/setup.py @@ -17,19 +17,17 @@ f.close() def get_tip_revision(path=os.getcwd()): + from subprocess import Popen, PIPE try: - from mercurial.hg import repository - from mercurial.ui import ui - from mercurial import node - from mercurial.error import RepoError - except ImportError: + cmd = Popen(['hg', 'tip', '--template', '{rev}', '-R', path], + stdout=PIPE, stderr=PIPE) + except OSError: return 0 - try: - repo = repository(ui(), path) - tip = repo.changelog.tip() - return repo.changelog.rev(tip) - except RepoError: + rev = cmd.stdout.read() + if rev == '': + # there has been an error in the command return 0 + return int(rev) DEV_SUFFIX = '.dev%d' % get_tip_revision('..') -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Wed Jun 2 01:18:23 2010 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Jun 2010 01:18:23 +0200 Subject: [Python-checkins] distutils2: Ignore default build dir Message-ID: tarek.ziade pushed 9b2bfeed1630 to distutils2: http://hg.python.org/distutils2/rev/9b2bfeed1630 changeset: 189:9b2bfeed1630 parent: 160:30ad3af43b5f user: ?ric Araujo date: Sat May 29 15:53:10 2010 +0200 summary: Ignore default build dir files: .hgignore diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,5 @@ .*\.pyc$ .*\.pyo$ +^src/build ^docs/build .*\.swp$ - -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Wed Jun 2 01:18:23 2010 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Jun 2010 01:18:23 +0200 Subject: [Python-checkins] distutils2: branch merge Message-ID: tarek.ziade pushed 90e7d3dd3d2e to distutils2: http://hg.python.org/distutils2/rev/90e7d3dd3d2e changeset: 192:90e7d3dd3d2e parent: 191:ce0d6be25d09 parent: 189:9b2bfeed1630 user: ?ric Araujo date: Mon May 31 23:06:57 2010 +0200 summary: branch merge files: diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,5 @@ .*\.pyc$ .*\.pyo$ +^src/build ^docs/build .*\.swp$ - -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Wed Jun 2 01:18:23 2010 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Jun 2010 01:18:23 +0200 Subject: [Python-checkins] distutils2: Use the same name everywhere. Message-ID: tarek.ziade pushed ccaea7a5f39d to distutils2: http://hg.python.org/distutils2/rev/ccaea7a5f39d changeset: 190:ccaea7a5f39d parent: 188:b7fd258b33e7 user: ?ric Araujo date: Mon May 31 21:58:31 2010 +0200 summary: Use the same name everywhere. files: src/distutils2/_backport/tests/test_sysconfig.py, src/distutils2/tests/test_check.py, src/distutils2/tests/test_metadata.py, src/distutils2/tests/test_upload.py diff --git a/src/distutils2/_backport/tests/test_sysconfig.py b/src/distutils2/_backport/tests/test_sysconfig.py --- a/src/distutils2/_backport/tests/test_sysconfig.py +++ b/src/distutils2/_backport/tests/test_sysconfig.py @@ -97,7 +97,7 @@ substitution key (which would be weird). """ - self.failUnlessEqual(_subst_vars('{py{version}}', {'version': '31'}), '{py31}') + self.assertEqual(_subst_vars('{py{version}}', {'version': '31'}), '{py31}') def test_get_paths(self): scheme = get_paths() diff --git a/src/distutils2/tests/test_check.py b/src/distutils2/tests/test_check.py --- a/src/distutils2/tests/test_check.py +++ b/src/distutils2/tests/test_check.py @@ -27,7 +27,7 @@ # by default, check is checking the metadata # should have some warnings cmd = self._run() - self.assert_(len(cmd._warnings) > 0) + self.assertTrue(len(cmd._warnings) > 0) # now let's add the required fields # and run it again, to make sure we don't get diff --git a/src/distutils2/tests/test_metadata.py b/src/distutils2/tests/test_metadata.py --- a/src/distutils2/tests/test_metadata.py +++ b/src/distutils2/tests/test_metadata.py @@ -64,7 +64,7 @@ res = res.read() f = open(PKG_INFO) wanted = f.read() - self.assert_('Keywords: keyring,password,crypt' in res) + self.assertTrue('Keywords: keyring,password,crypt' in res) f.close() def test_metadata_markers(self): diff --git a/src/distutils2/tests/test_upload.py b/src/distutils2/tests/test_upload.py --- a/src/distutils2/tests/test_upload.py +++ b/src/distutils2/tests/test_upload.py @@ -116,7 +116,7 @@ # what did we send ? self.assertIn('d??d??', self.last_open.req.data) headers = dict(self.last_open.req.headers) - self.assert_(headers['Content-length'] > 2000) + self.assertTrue(headers['Content-length'] > 2000) self.assertTrue(headers['Content-type'].startswith('multipart/form-data')) self.assertEquals(self.last_open.req.get_method(), 'POST') self.assertEquals(self.last_open.req.get_full_url(), -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Wed Jun 2 01:18:23 2010 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Jun 2010 01:18:23 +0200 Subject: [Python-checkins] distutils2: Restore 3.x-compatible syntax. Message-ID: tarek.ziade pushed 3050b9075187 to distutils2: http://hg.python.org/distutils2/rev/3050b9075187 changeset: 195:3050b9075187 user: ?ric Araujo date: Wed Jun 02 00:44:01 2010 +0200 summary: Restore 3.x-compatible syntax. files: src/runtests.py diff --git a/src/runtests.py b/src/runtests.py --- a/src/runtests.py +++ b/src/runtests.py @@ -28,7 +28,7 @@ try: from distutils2.tests.support import unittest except ImportError: - print >> sys.stderr, 'Error: You have to install unittest2' + print('Error: You have to install unittest2') sys.exit(1) sys.exit(test_main()) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Wed Jun 2 01:18:23 2010 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Jun 2010 01:18:23 +0200 Subject: [Python-checkins] distutils2: Add myself to contibutors. Message-ID: tarek.ziade pushed 67b757954d46 to distutils2: http://hg.python.org/distutils2/rev/67b757954d46 changeset: 196:67b757954d46 user: ?ric Araujo date: Wed Jun 02 01:07:34 2010 +0200 summary: Add myself to contibutors. files: src/CONTRIBUTORS.txt diff --git a/src/CONTRIBUTORS.txt b/src/CONTRIBUTORS.txt --- a/src/CONTRIBUTORS.txt +++ b/src/CONTRIBUTORS.txt @@ -9,6 +9,7 @@ Thanks to: +- ??ric Araujo - Pior Bastida - Titus Brown - Nicolas Cadou -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Wed Jun 2 01:18:23 2010 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Jun 2010 01:18:23 +0200 Subject: [Python-checkins] distutils2: Isolate import of unittest or unittest2 in one place. Message-ID: tarek.ziade pushed 30409c856689 to distutils2: http://hg.python.org/distutils2/rev/30409c856689 changeset: 194:30409c856689 user: ?ric Araujo date: Tue Jun 01 17:55:57 2010 +0200 summary: Isolate import of unittest or unittest2 in one place. files: src/distutils2/_backport/tests/__init__.py, src/distutils2/_backport/tests/test_pkgutil.py, src/distutils2/_backport/tests/test_sysconfig.py, src/distutils2/tests/__init__.py, src/distutils2/tests/support.py, src/distutils2/tests/test_bdist.py, src/distutils2/tests/test_bdist_dumb.py, src/distutils2/tests/test_bdist_msi.py, src/distutils2/tests/test_bdist_wininst.py, src/distutils2/tests/test_build.py, src/distutils2/tests/test_build_clib.py, src/distutils2/tests/test_build_ext.py, src/distutils2/tests/test_build_py.py, src/distutils2/tests/test_build_scripts.py, src/distutils2/tests/test_ccompiler.py, src/distutils2/tests/test_check.py, src/distutils2/tests/test_clean.py, src/distutils2/tests/test_cmd.py, src/distutils2/tests/test_config.py, src/distutils2/tests/test_config_cmd.py, src/distutils2/tests/test_converter.py, src/distutils2/tests/test_core.py, src/distutils2/tests/test_cygwinccompiler.py, src/distutils2/tests/test_dist.py, src/distutils2/tests/test_emxccompiler.py, src/distutils2/tests/test_extension.py, src/distutils2/tests/test_install.py, src/distutils2/tests/test_install_data.py, src/distutils2/tests/test_install_headers.py, src/distutils2/tests/test_install_lib.py, src/distutils2/tests/test_install_scripts.py, src/distutils2/tests/test_manifest.py, src/distutils2/tests/test_metadata.py, src/distutils2/tests/test_msvc9compiler.py, src/distutils2/tests/test_pypi_versions.py, src/distutils2/tests/test_register.py, src/distutils2/tests/test_sdist.py, src/distutils2/tests/test_spawn.py, src/distutils2/tests/test_unixccompiler.py, src/distutils2/tests/test_upload.py, src/distutils2/tests/test_util.py, src/distutils2/tests/test_version.py, src/runtests.py diff --git a/src/distutils2/_backport/tests/__init__.py b/src/distutils2/_backport/tests/__init__.py --- a/src/distutils2/_backport/tests/__init__.py +++ b/src/distutils2/_backport/tests/__init__.py @@ -1,12 +1,13 @@ import os import sys -import unittest2 + +from distutils2.tests.support import unittest here = os.path.dirname(__file__) def test_suite(): - suite = unittest2.TestSuite() + suite = unittest.TestSuite() for fn in os.listdir(here): if fn.startswith("test") and fn.endswith(".py"): modname = "distutils2._backport.tests." + fn[:-3] diff --git a/src/distutils2/_backport/tests/test_pkgutil.py b/src/distutils2/_backport/tests/test_pkgutil.py --- a/src/distutils2/_backport/tests/test_pkgutil.py +++ b/src/distutils2/_backport/tests/test_pkgutil.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """Tests for PEP 376 pkgutil functionality""" -import unittest2 import sys import os import csv @@ -12,13 +11,14 @@ from test.test_support import run_unittest, TESTFN import distutils2._backport.pkgutil +from distutils2.tests.support import unittest # TODO Add a test for getting a distribution that is provided by another # distribution. # TODO Add a test for absolute pathed RECORD items (e.g. /etc/myapp/config.ini) -class TestPkgUtilDistribution(unittest2.TestCase): +class TestPkgUtilDistribution(unittest.TestCase): """Tests the pkgutil.Distribution class""" def setUp(self): @@ -171,7 +171,7 @@ self.assertEqual(sorted(found), sorted(distinfo_record_paths)) -class TestPkgUtilFunctions(unittest2.TestCase): +class TestPkgUtilFunctions(unittest.TestCase): """Tests for the new functionality added in PEP 376.""" def setUp(self): @@ -371,8 +371,8 @@ def test_suite(): - suite = unittest2.TestSuite() - testcase_loader = unittest2.loader.defaultTestLoader.loadTestsFromTestCase + suite = unittest.TestSuite() + testcase_loader = unittest.loader.defaultTestLoader.loadTestsFromTestCase suite.addTest(testcase_loader(TestPkgUtilFunctions)) suite.addTest(testcase_loader(TestPkgUtilDistribution)) return suite @@ -384,8 +384,8 @@ test_main() def test_suite(): - suite = unittest2.TestSuite() - testcase_loader = unittest2.loader.defaultTestLoader.loadTestsFromTestCase + suite = unittest.TestSuite() + testcase_loader = unittest.loader.defaultTestLoader.loadTestsFromTestCase suite.addTest(testcase_loader(TestPkgUtilFunctions)) suite.addTest(testcase_loader(TestPkgUtilDistribution)) return suite diff --git a/src/distutils2/_backport/tests/test_sysconfig.py b/src/distutils2/_backport/tests/test_sysconfig.py --- a/src/distutils2/_backport/tests/test_sysconfig.py +++ b/src/distutils2/_backport/tests/test_sysconfig.py @@ -4,7 +4,6 @@ executing have not been removed. """ -import unittest2 import sys import os import shutil @@ -19,8 +18,9 @@ get_path, get_path_names, _get_default_scheme, _subst_vars, _expand_vars, get_scheme_names, _CONFIG_FILE) +from distutils2.tests.support import unittest -class TestSysConfig(unittest2.TestCase): +class TestSysConfig(unittest.TestCase): def setUp(self): """Make a copy of sys.path""" @@ -262,7 +262,7 @@ _expand_globals(config) def test_suite(): - return unittest2.makeSuite(TestSysConfig) + return unittest.makeSuite(TestSysConfig) def test_main(): run_unittest(test_suite()) diff --git a/src/distutils2/tests/__init__.py b/src/distutils2/tests/__init__.py --- a/src/distutils2/tests/__init__.py +++ b/src/distutils2/tests/__init__.py @@ -1,20 +1,25 @@ -"""Test suite for distutils. +"""Test suite for distutils2. This test suite consists of a collection of test modules in the -distutils.tests package. Each test module has a name starting with +distutils2.tests package. Each test module has a name starting with 'test' and contains a function test_suite(). The function is expected -to return an initialized unittest2.TestSuite instance. +to return an initialized unittest.TestSuite instance. -Tests for the command classes in the distutils.command package are -included in distutils.tests as well, instead of using a separate -distutils.command.tests package, since command identification is done +Tests for the command classes in the distutils2.command package are +included in distutils2.tests as well, instead of using a separate +distutils2.command.tests package, since command identification is done by import rather than matching pre-defined names. +Utility code is included in distutils2.tests.support. Always import +unittest from that module, it will be the right version (standard +library unittest for 2.7 and higher, third-party unittest2 release for +older versions). """ + import os import sys import warnings -import unittest2 +from distutils2.tests.support import unittest from test.test_support import TESTFN # use TESTFN from stdlib/test_support. @@ -23,7 +28,7 @@ verbose = 1 def test_suite(): - suite = unittest2.TestSuite() + suite = unittest.TestSuite() for fn in os.listdir(here): if fn.startswith("test") and fn.endswith(".py"): modname = "distutils2.tests." + fn[:-3] @@ -42,17 +47,17 @@ class BasicTestRunner: def run(self, test): - result = unittest2.TestResult() + result = unittest.TestResult() test(result) return result def _run_suite(suite, verbose_=1): - """Run tests from a unittest2.TestSuite-derived class.""" + """Run tests from a unittest.TestSuite-derived class.""" global verbose verbose = verbose_ if verbose_: - runner = unittest2.TextTestRunner(sys.stdout, verbosity=2) + runner = unittest.TextTestRunner(sys.stdout, verbosity=2) else: runner = BasicTestRunner() @@ -68,22 +73,22 @@ def run_unittest(classes, verbose_=1): - """Run tests from unittest2.TestCase-derived classes. + """Run tests from unittest.TestCase-derived classes. - Extracted from stdlib test.test_support and modified to support unittest2. + Extracted from stdlib test.test_support and modified to support unittest. """ - valid_types = (unittest2.TestSuite, unittest2.TestCase) - suite = unittest2.TestSuite() + valid_types = (unittest.TestSuite, unittest.TestCase) + suite = unittest.TestSuite() for cls in classes: if isinstance(cls, str): if cls in sys.modules: - suite.addTest(unittest2.findTestCases(sys.modules[cls])) + suite.addTest(unittest.findTestCases(sys.modules[cls])) else: raise ValueError("str arguments must be keys in sys.modules") elif isinstance(cls, valid_types): suite.addTest(cls) else: - suite.addTest(unittest2.makeSuite(cls)) + suite.addTest(unittest.makeSuite(cls)) _run_suite(suite, verbose_) @@ -128,4 +133,4 @@ if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/support.py b/src/distutils2/tests/support.py --- a/src/distutils2/tests/support.py +++ b/src/distutils2/tests/support.py @@ -1,5 +1,12 @@ -"""Support code for distutils test cases.""" +"""Support code for distutils2 test cases. + +Always import unittest from this module, it will be the right version +(standard library unittest for 2.7 and higher, third-party unittest2 +release for older versions). +""" + import os +import sys import shutil import tempfile from copy import deepcopy @@ -9,6 +16,13 @@ from distutils2.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils2.core import Distribution +if sys.version_info >= (2, 7): + # improved unittest package from 2.7's standard library + import unittest +else: + # external release of same package for older versions + import unittest2 as unittest + class LoggingSilencer(object): def setUp(self): diff --git a/src/distutils2/tests/test_bdist.py b/src/distutils2/tests/test_bdist.py --- a/src/distutils2/tests/test_bdist.py +++ b/src/distutils2/tests/test_bdist.py @@ -1,5 +1,4 @@ """Tests for distutils.command.bdist.""" -import unittest2 import sys import os import tempfile @@ -10,12 +9,13 @@ from distutils2.core import Distribution from distutils2.command.bdist import bdist from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.spawn import find_executable from distutils2 import spawn from distutils2.errors import DistutilsExecError class BuildTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def test_formats(self): @@ -38,7 +38,7 @@ self.assertEquals(founded, formats) def test_suite(): - return unittest2.makeSuite(BuildTestCase) + return unittest.makeSuite(BuildTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_bdist_dumb.py b/src/distutils2/tests/test_bdist_dumb.py --- a/src/distutils2/tests/test_bdist_dumb.py +++ b/src/distutils2/tests/test_bdist_dumb.py @@ -1,6 +1,5 @@ """Tests for distutils.command.bdist_dumb.""" -import unittest2 import sys import os @@ -12,6 +11,7 @@ zlib = None from distutils2.tests import run_unittest +from distutils2.tests.support import unittest from distutils2.core import Distribution from distutils2.command.bdist_dumb import bdist_dumb @@ -29,7 +29,7 @@ class BuildDumbTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(BuildDumbTestCase, self).setUp() @@ -42,7 +42,7 @@ sys.argv[:] = self.old_sys_argv[1] super(BuildDumbTestCase, self).tearDown() - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_simple_built(self): # let's create a simple package @@ -99,7 +99,7 @@ self.assertEquals(cmd.format, default) def test_suite(): - return unittest2.makeSuite(BuildDumbTestCase) + return unittest.makeSuite(BuildDumbTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_bdist_msi.py b/src/distutils2/tests/test_bdist_msi.py --- a/src/distutils2/tests/test_bdist_msi.py +++ b/src/distutils2/tests/test_bdist_msi.py @@ -1,16 +1,16 @@ """Tests for distutils.command.bdist_msi.""" -import unittest2 import sys from distutils2.tests import run_unittest from distutils2.tests import support +from distutils2.tests.support import unittest class BDistMSITestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): - @unittest2.skipUnless(sys.platform=="win32", "These tests are only for win32") + @unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") def test_minial(self): # minimal test XXX need more tests from distutils2.command.bdist_msi import bdist_msi @@ -19,7 +19,7 @@ cmd.ensure_finalized() def test_suite(): - return unittest2.makeSuite(BDistMSITestCase) + return unittest.makeSuite(BDistMSITestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_bdist_wininst.py b/src/distutils2/tests/test_bdist_wininst.py --- a/src/distutils2/tests/test_bdist_wininst.py +++ b/src/distutils2/tests/test_bdist_wininst.py @@ -1,14 +1,14 @@ """Tests for distutils.command.bdist_wininst.""" -import unittest2 from distutils2.tests import run_unittest from distutils2.command.bdist_wininst import bdist_wininst from distutils2.tests import support +from distutils2.tests.support import unittest class BuildWinInstTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_get_exe_bytes(self): @@ -26,7 +26,7 @@ self.assertTrue(len(exe_file) > 10) def test_suite(): - return unittest2.makeSuite(BuildWinInstTestCase) + return unittest.makeSuite(BuildWinInstTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_build.py b/src/distutils2/tests/test_build.py --- a/src/distutils2/tests/test_build.py +++ b/src/distutils2/tests/test_build.py @@ -1,10 +1,10 @@ """Tests for distutils.command.build.""" -import unittest2 import os import sys from distutils2.command.build import build from distutils2.tests import support +from distutils2.tests.support import unittest try: from sysconfig import get_platform except ImportError: @@ -12,7 +12,7 @@ class BuildTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_finalize_options(self): pkg_dir, dist = self.create_dist() @@ -51,7 +51,7 @@ self.assertEquals(cmd.executable, os.path.normpath(sys.executable)) def test_suite(): - return unittest2.makeSuite(BuildTestCase) + return unittest.makeSuite(BuildTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_build_clib.py b/src/distutils2/tests/test_build_clib.py --- a/src/distutils2/tests/test_build_clib.py +++ b/src/distutils2/tests/test_build_clib.py @@ -1,5 +1,4 @@ """Tests for distutils.command.build_clib.""" -import unittest2 import os import sys @@ -7,10 +6,11 @@ from distutils2.errors import DistutilsSetupError from distutils2.tests import support from distutils2.spawn import find_executable +from distutils2.tests.support import unittest class BuildCLibTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_check_library_dist(self): pkg_dir, dist = self.create_dist() @@ -137,7 +137,7 @@ self.assertTrue('libfoo.a' in os.listdir(build_temp)) def test_suite(): - return unittest2.makeSuite(BuildCLibTestCase) + return unittest.makeSuite(BuildCLibTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_build_ext.py b/src/distutils2/tests/test_build_ext.py --- a/src/distutils2/tests/test_build_ext.py +++ b/src/distutils2/tests/test_build_ext.py @@ -6,6 +6,7 @@ import warnings import distutils2.tests +from distutils2.tests.support import unittest from distutils2.core import Extension, Distribution from distutils2.command.build_ext import build_ext from distutils2.tests import support @@ -17,7 +18,6 @@ except ImportError: from distutils2._backport import sysconfig -import unittest2 # http://bugs.python.org/issue4373 # Don't load the xx module more than once. @@ -29,7 +29,7 @@ class BuildExtTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def setUp(self): # Create a simple test environment # Note that we're making changes to sys.path @@ -46,7 +46,7 @@ build_ext.USER_BASE = site.USER_BASE # XXX only works with 2.6 > -- dunno why yet - @unittest2.skipUnless(sys.version_info >= (2, 6,), 'works for >= 2.6') + @unittest.skipUnless(sys.version_info >= (2, 6,), 'works for >= 2.6') def test_build_ext(self): global ALREADY_TESTED xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') @@ -412,8 +412,8 @@ if distutils2.tests.verbose: print ('test_build_ext: Cannot find source code (test' ' must run in python build dir)') - return unittest2.TestSuite() - else: return unittest2.makeSuite(BuildExtTestCase) + return unittest.TestSuite() + else: return unittest.makeSuite(BuildExtTestCase) if __name__ == '__main__': distsutils2.tests.run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_build_py.py b/src/distutils2/tests/test_build_py.py --- a/src/distutils2/tests/test_build_py.py +++ b/src/distutils2/tests/test_build_py.py @@ -3,18 +3,18 @@ import os import sys import StringIO -import unittest2 from distutils2.command.build_py import build_py from distutils2.core import Distribution from distutils2.errors import DistutilsFileError from distutils2.tests import support +from distutils2.tests.support import unittest class BuildPyTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_package_data(self): sources = self.mkdtemp() @@ -90,7 +90,7 @@ os.chdir(cwd) sys.stdout = old_stdout - @unittest2.skipUnless(hasattr(sys, 'dont_write_bytecode'), + @unittest.skipUnless(hasattr(sys, 'dont_write_bytecode'), 'dont_write_bytecode support') def test_dont_write_bytecode(self): # makes sure byte_compile is not used @@ -109,7 +109,7 @@ self.assertTrue('byte-compiling is disabled' in self.logs[0][1]) def test_suite(): - return unittest2.makeSuite(BuildPyTestCase) + return unittest.makeSuite(BuildPyTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_build_scripts.py b/src/distutils2/tests/test_build_scripts.py --- a/src/distutils2/tests/test_build_scripts.py +++ b/src/distutils2/tests/test_build_scripts.py @@ -1,7 +1,6 @@ """Tests for distutils.command.build_scripts.""" import os -import unittest2 from distutils2.command.build_scripts import build_scripts from distutils2.core import Distribution @@ -11,11 +10,12 @@ from distutils2._backport import sysconfig from distutils2.tests import support +from distutils2.tests.support import unittest class BuildScriptsTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_default_settings(self): cmd = self.get_build_scripts_cmd("/foo/bar", []) @@ -106,7 +106,7 @@ self.assertTrue(name in built) def test_suite(): - return unittest2.makeSuite(BuildScriptsTestCase) + return unittest.makeSuite(BuildScriptsTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_ccompiler.py b/src/distutils2/tests/test_ccompiler.py --- a/src/distutils2/tests/test_ccompiler.py +++ b/src/distutils2/tests/test_ccompiler.py @@ -1,11 +1,11 @@ """Tests for distutils.ccompiler.""" import os -import unittest2 from distutils2.tests import captured_stdout from distutils2.compiler.ccompiler import (gen_lib_options, CCompiler, get_default_compiler, customize_compiler) from distutils2.tests import support +from distutils2.tests.support import unittest class FakeCompiler(object): def library_dir_option(self, dir): @@ -20,7 +20,7 @@ def library_option(self, lib): return "-l" + lib -class CCompilerTestCase(support.EnvironGuard, unittest2.TestCase): +class CCompilerTestCase(support.EnvironGuard, unittest.TestCase): def test_gen_lib_options(self): compiler = FakeCompiler() @@ -54,7 +54,7 @@ self.assertEquals(comp.exes['archiver'], 'my_ar -arflags') def test_suite(): - return unittest2.makeSuite(CCompilerTestCase) + return unittest.makeSuite(CCompilerTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_check.py b/src/distutils2/tests/test_check.py --- a/src/distutils2/tests/test_check.py +++ b/src/distutils2/tests/test_check.py @@ -1,14 +1,14 @@ """Tests for distutils.command.check.""" -import unittest2 from distutils2.command.check import check from distutils2.metadata import _HAS_DOCUTILS from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.errors import DistutilsSetupError class CheckTestCase(support.LoggingSilencer, support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def _run(self, metadata=None, **options): if metadata is None: @@ -79,7 +79,7 @@ 'restructuredtext': 1}) def test_suite(): - return unittest2.makeSuite(CheckTestCase) + return unittest.makeSuite(CheckTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_clean.py b/src/distutils2/tests/test_clean.py --- a/src/distutils2/tests/test_clean.py +++ b/src/distutils2/tests/test_clean.py @@ -1,15 +1,15 @@ """Tests for distutils.command.clean.""" import sys import os -import unittest2 import getpass from distutils2.command.clean import clean from distutils2.tests import support +from distutils2.tests.support import unittest class cleanTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_simple_run(self): pkg_dir, dist = self.create_dist() @@ -44,7 +44,7 @@ cmd.run() def test_suite(): - return unittest2.makeSuite(cleanTestCase) + return unittest.makeSuite(cleanTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_cmd.py b/src/distutils2/tests/test_cmd.py --- a/src/distutils2/tests/test_cmd.py +++ b/src/distutils2/tests/test_cmd.py @@ -1,17 +1,17 @@ """Tests for distutils.cmd.""" -import unittest2 import os from distutils2.tests import captured_stdout, run_unittest from distutils2.cmd import Command from distutils2.dist import Distribution from distutils2.errors import DistutilsOptionError +from distutils2.tests.support import unittest class MyCmd(Command): def initialize_options(self): pass -class CommandTestCase(unittest2.TestCase): +class CommandTestCase(unittest.TestCase): def setUp(self): dist = Distribution() @@ -104,7 +104,7 @@ self.assertRaises(DistutilsOptionError, cmd.ensure_dirname, 'option2') def test_suite(): - return unittest2.makeSuite(CommandTestCase) + return unittest.makeSuite(CommandTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_config.py b/src/distutils2/tests/test_config.py --- a/src/distutils2/tests/test_config.py +++ b/src/distutils2/tests/test_config.py @@ -1,7 +1,6 @@ """Tests for distutils.pypirc.pypirc.""" import sys import os -import unittest2 import tempfile import shutil @@ -11,6 +10,7 @@ from distutils2.log import WARN from distutils2.tests import support +from distutils2.tests.support import unittest PYPIRC = """\ [distutils] @@ -50,7 +50,7 @@ class PyPIRCCommandTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def setUp(self): """Patches the environment.""" @@ -112,7 +112,7 @@ self.assertEquals(content, WANTED) def test_suite(): - return unittest2.makeSuite(PyPIRCCommandTestCase) + return unittest.makeSuite(PyPIRCCommandTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_config_cmd.py b/src/distutils2/tests/test_config_cmd.py --- a/src/distutils2/tests/test_config_cmd.py +++ b/src/distutils2/tests/test_config_cmd.py @@ -1,15 +1,15 @@ """Tests for distutils.command.config.""" -import unittest2 import os import sys from distutils2.command.config import dump_file, config from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2 import log class ConfigTestCase(support.LoggingSilencer, support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def _info(self, msg, *args): for line in msg.splitlines(): @@ -83,7 +83,7 @@ self.assertTrue(not os.path.exists(f)) def test_suite(): - return unittest2.makeSuite(ConfigTestCase) + return unittest.makeSuite(ConfigTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_converter.py b/src/distutils2/tests/test_converter.py --- a/src/distutils2/tests/test_converter.py +++ b/src/distutils2/tests/test_converter.py @@ -1,8 +1,8 @@ """Tests for distutils.converter.""" import os import sys -import unittest2 from distutils2.converter import DistutilsRefactoringTool +from distutils2.tests.support import unittest _CURDIR = os.path.dirname(__file__) @@ -15,9 +15,9 @@ f.close() -class ConverterTestCase(unittest2.TestCase): +class ConverterTestCase(unittest.TestCase): - @unittest2.skipUnless(not sys.version < '2.6', 'Needs Python >=2.6') + @unittest.skipUnless(not sys.version < '2.6', 'Needs Python >=2.6') def test_conversions(self): # for all XX_before in the conversions/ dir # we run the refactoring tool @@ -33,7 +33,7 @@ self.assertEquals(str(res), wanted) def test_suite(): - return unittest2.makeSuite(ConverterTestCase) + return unittest.makeSuite(ConverterTestCase) if __name__ == '__main__': - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_core.py b/src/distutils2/tests/test_core.py --- a/src/distutils2/tests/test_core.py +++ b/src/distutils2/tests/test_core.py @@ -6,8 +6,8 @@ import shutil import sys from distutils2.tests import captured_stdout -import unittest2 from distutils2.tests import support +from distutils2.tests.support import unittest # setup script that uses __file__ setup_using___file__ = """\ @@ -28,7 +28,7 @@ """ -class CoreTestCase(support.EnvironGuard, unittest2.TestCase): +class CoreTestCase(support.EnvironGuard, unittest.TestCase): def setUp(self): super(CoreTestCase, self).setUp() @@ -92,7 +92,7 @@ self.assertEqual(cwd, output) def test_suite(): - return unittest2.makeSuite(CoreTestCase) + return unittest.makeSuite(CoreTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_cygwinccompiler.py b/src/distutils2/tests/test_cygwinccompiler.py --- a/src/distutils2/tests/test_cygwinccompiler.py +++ b/src/distutils2/tests/test_cygwinccompiler.py @@ -1,5 +1,4 @@ """Tests for distutils.cygwinccompiler.""" -import unittest2 import sys import os import warnings @@ -18,9 +17,10 @@ get_msvcr, RE_VERSION) from distutils2.util import get_compiler_versions from distutils2.tests import support +from distutils2.tests.support import unittest class CygwinCCompilerTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(CygwinCCompilerTestCase, self).setUp() @@ -94,7 +94,7 @@ def test_suite(): - return unittest2.makeSuite(CygwinCCompilerTestCase) + return unittest.makeSuite(CygwinCCompilerTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_dist.py b/src/distutils2/tests/test_dist.py --- a/src/distutils2/tests/test_dist.py +++ b/src/distutils2/tests/test_dist.py @@ -4,7 +4,6 @@ import os import StringIO import sys -import unittest2 import warnings import textwrap @@ -13,6 +12,7 @@ import distutils2.dist from distutils2.tests import TESTFN, captured_stdout from distutils2.tests import support +from distutils2.tests.support import unittest class test_dist(Command): """Sample distutils2 extension command.""" @@ -40,7 +40,7 @@ class DistributionTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(DistributionTestCase, self).setUp() @@ -242,7 +242,7 @@ class MetadataTestCase(support.TempdirManager, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(MetadataTestCase, self).setUp() @@ -422,10 +422,10 @@ self.assertEquals(metadata['requires-dist'], ['foo']) def test_suite(): - suite = unittest2.TestSuite() - suite.addTest(unittest2.makeSuite(DistributionTestCase)) - suite.addTest(unittest2.makeSuite(MetadataTestCase)) + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(DistributionTestCase)) + suite.addTest(unittest.makeSuite(MetadataTestCase)) return suite if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_emxccompiler.py b/src/distutils2/tests/test_emxccompiler.py --- a/src/distutils2/tests/test_emxccompiler.py +++ b/src/distutils2/tests/test_emxccompiler.py @@ -1,5 +1,4 @@ """Tests for distutils.emxccompiler.""" -import unittest2 import sys import os import warnings @@ -10,14 +9,15 @@ from distutils2.compiler.emxccompiler import get_versions from distutils2.util import get_compiler_versions from distutils2.tests import support +from distutils2.tests.support import unittest class EmxCCompilerTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): pass def test_suite(): - return unittest2.makeSuite(EmxCCompilerTestCase) + return unittest.makeSuite(EmxCCompilerTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_extension.py b/src/distutils2/tests/test_extension.py --- a/src/distutils2/tests/test_extension.py +++ b/src/distutils2/tests/test_extension.py @@ -1,16 +1,16 @@ """Tests for distutils.extension.""" -import unittest2 import os import warnings from distutils2.extension import Extension +from distutils2.tests.support import unittest -class ExtensionTestCase(unittest2.TestCase): +class ExtensionTestCase(unittest.TestCase): pass def test_suite(): - return unittest2.makeSuite(ExtensionTestCase) + return unittest.makeSuite(ExtensionTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install.py b/src/distutils2/tests/test_install.py --- a/src/distutils2/tests/test_install.py +++ b/src/distutils2/tests/test_install.py @@ -3,7 +3,6 @@ import os import os.path import sys -import unittest2 import site from distutils2._backport import sysconfig @@ -22,11 +21,12 @@ from distutils2.errors import DistutilsOptionError from distutils2.tests import support +from distutils2.tests.support import unittest class InstallTestCase(support.TempdirManager, support.EnvironGuard, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_home_installation_scheme(self): # This ensure two things: @@ -214,7 +214,7 @@ self.assertTrue(len(self.logs) > old_logs_len) def test_suite(): - return unittest2.makeSuite(InstallTestCase) + return unittest.makeSuite(InstallTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install_data.py b/src/distutils2/tests/test_install_data.py --- a/src/distutils2/tests/test_install_data.py +++ b/src/distutils2/tests/test_install_data.py @@ -1,16 +1,16 @@ """Tests for distutils.command.install_data.""" import sys import os -import unittest2 import getpass from distutils2.command.install_data import install_data from distutils2.tests import support +from distutils2.tests.support import unittest class InstallDataTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def test_simple_run(self): pkg_dir, dist = self.create_dist() @@ -70,7 +70,7 @@ self.assertTrue(os.path.exists(os.path.join(inst, rone))) def test_suite(): - return unittest2.makeSuite(InstallDataTestCase) + return unittest.makeSuite(InstallDataTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install_headers.py b/src/distutils2/tests/test_install_headers.py --- a/src/distutils2/tests/test_install_headers.py +++ b/src/distutils2/tests/test_install_headers.py @@ -1,16 +1,16 @@ """Tests for distutils.command.install_headers.""" import sys import os -import unittest2 import getpass from distutils2.command.install_headers import install_headers from distutils2.tests import support +from distutils2.tests.support import unittest class InstallHeadersTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def test_simple_run(self): # we have two headers @@ -34,7 +34,7 @@ self.assertEquals(len(cmd.get_outputs()), 2) def test_suite(): - return unittest2.makeSuite(InstallHeadersTestCase) + return unittest.makeSuite(InstallHeadersTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install_lib.py b/src/distutils2/tests/test_install_lib.py --- a/src/distutils2/tests/test_install_lib.py +++ b/src/distutils2/tests/test_install_lib.py @@ -1,12 +1,12 @@ """Tests for distutils.command.install_data.""" import sys import os -import unittest2 from distutils2.command.install_lib import install_lib from distutils2.extension import Extension from distutils2.tests import support from distutils2.errors import DistutilsOptionError +from distutils2.tests.support import unittest try: no_bytecode = sys.dont_write_bytecode @@ -18,7 +18,7 @@ class InstallLibTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def test_finalize_options(self): pkg_dir, dist = self.create_dist() @@ -38,7 +38,7 @@ cmd.finalize_options() self.assertEquals(cmd.optimize, 2) - @unittest2.skipIf(no_bytecode, 'byte-compile not supported') + @unittest.skipIf(no_bytecode, 'byte-compile not supported') def test_byte_compile(self): pkg_dir, dist = self.create_dist() cmd = install_lib(dist) @@ -84,7 +84,7 @@ # get_input should return 2 elements self.assertEquals(len(cmd.get_inputs()), 2) - @unittest2.skipUnless(bytecode_support, 'sys.dont_write_bytecode not supported') + @unittest.skipUnless(bytecode_support, 'sys.dont_write_bytecode not supported') def test_dont_write_bytecode(self): # makes sure byte_compile is not used pkg_dir, dist = self.create_dist() @@ -102,7 +102,7 @@ self.assertTrue('byte-compiling is disabled' in self.logs[0][1]) def test_suite(): - return unittest2.makeSuite(InstallLibTestCase) + return unittest.makeSuite(InstallLibTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install_scripts.py b/src/distutils2/tests/test_install_scripts.py --- a/src/distutils2/tests/test_install_scripts.py +++ b/src/distutils2/tests/test_install_scripts.py @@ -1,17 +1,17 @@ """Tests for distutils.command.install_scripts.""" import os -import unittest2 from distutils2.command.install_scripts import install_scripts from distutils2.core import Distribution from distutils2.tests import support +from distutils2.tests.support import unittest class InstallScriptsTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_default_settings(self): dist = Distribution() @@ -73,7 +73,7 @@ def test_suite(): - return unittest2.makeSuite(InstallScriptsTestCase) + return unittest.makeSuite(InstallScriptsTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_manifest.py b/src/distutils2/tests/test_manifest.py --- a/src/distutils2/tests/test_manifest.py +++ b/src/distutils2/tests/test_manifest.py @@ -1,10 +1,10 @@ """Tests for distutils.manifest.""" -import unittest2 import os import sys import logging from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.manifest import Manifest _MANIFEST = """\ @@ -18,7 +18,7 @@ """ class ManifestTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def test_manifest_reader(self): @@ -51,7 +51,7 @@ def test_suite(): - return unittest2.makeSuite(ManifestTestCase) + return unittest.makeSuite(ManifestTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_metadata.py b/src/distutils2/tests/test_metadata.py --- a/src/distutils2/tests/test_metadata.py +++ b/src/distutils2/tests/test_metadata.py @@ -1,13 +1,13 @@ """Tests for distutils.command.bdist.""" -import unittest2 import os import sys from StringIO import StringIO from distutils2.metadata import (DistributionMetadata, _interpret, PKG_INFO_PREFERRED_VERSION) +from distutils2.tests.support import unittest -class DistributionMetadataTestCase(unittest2.TestCase): +class DistributionMetadataTestCase(unittest.TestCase): def test_interpret(self): @@ -228,7 +228,7 @@ def test_suite(): - return unittest2.makeSuite(DistributionMetadataTestCase) + return unittest.makeSuite(DistributionMetadataTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_msvc9compiler.py b/src/distutils2/tests/test_msvc9compiler.py --- a/src/distutils2/tests/test_msvc9compiler.py +++ b/src/distutils2/tests/test_msvc9compiler.py @@ -1,10 +1,10 @@ """Tests for distutils.msvc9compiler.""" import sys -import unittest2 import os from distutils2.errors import DistutilsPlatformError from distutils2.tests import support +from distutils2.tests.support import unittest _MANIFEST = """\ @@ -62,9 +62,9 @@ class msvc9compilerTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): - @unittest2.skipUnless(sys.platform=="win32", "These tests are only for win32") + @unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") def test_no_compiler(self): # makes sure query_vcvarsall throws # a DistutilsPlatformError if the compiler @@ -86,7 +86,7 @@ finally: msvc9compiler.find_vcvarsall = old_find_vcvarsall - @unittest2.skipUnless(sys.platform=="win32", "These tests are only for win32") + @unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") def test_reg_class(self): from distutils2.msvccompiler import get_build_version if get_build_version() < 8.0: @@ -110,7 +110,7 @@ keys = Reg.read_keys(HKCU, r'Control Panel') self.assertTrue('Desktop' in keys) - @unittest2.skipUnless(sys.platform=="win32", "These tests are only for win32") + @unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") def test_remove_visual_c_ref(self): from distutils2.msvc9compiler import MSVCCompiler tempdir = self.mkdtemp() @@ -133,7 +133,7 @@ def test_suite(): - return unittest2.makeSuite(msvc9compilerTestCase) + return unittest.makeSuite(msvc9compilerTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_pypi_versions.py b/src/distutils2/tests/test_pypi_versions.py --- a/src/distutils2/tests/test_pypi_versions.py +++ b/src/distutils2/tests/test_pypi_versions.py @@ -17,9 +17,9 @@ import xmlrpclib import os.path -import unittest2 from distutils2.version import suggest_normalized_version +from distutils2.tests.support import unittest def test_pypi(): # @@ -121,11 +121,11 @@ print "Have Suggestion : ", have_sugg, pct % (have_sugg/total_versions*100,) print "No Suggestion : ", no_sugg, pct % (no_sugg/total_versions*100,) -class TestPyPI(unittest2.TestCase): +class TestPyPI(unittest.TestCase): pass def test_suite(): - return unittest2.makeSuite(TestPyPI) + return unittest.makeSuite(TestPyPI) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_register.py b/src/distutils2/tests/test_register.py --- a/src/distutils2/tests/test_register.py +++ b/src/distutils2/tests/test_register.py @@ -2,7 +2,6 @@ # -*- encoding: utf8 -*- import sys import os -import unittest2 import getpass import urllib2 import warnings @@ -19,6 +18,7 @@ from distutils2.errors import DistutilsSetupError from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.tests.test_config import PYPIRC, PyPIRCCommandTestCase PYPIRC_NOPASSWORD = """\ @@ -192,7 +192,7 @@ self.assertEquals(headers['Content-length'], '290') self.assertTrue('tarek' in req.data) - @unittest2.skipUnless(DOCUTILS_SUPPORT, 'needs docutils') + @unittest.skipUnless(DOCUTILS_SUPPORT, 'needs docutils') def test_strict(self): # testing the script option # when on, the register command stops if @@ -250,7 +250,7 @@ self.assertEquals(data['requires_dist'], ['lxml']) def test_suite(): - return unittest2.makeSuite(RegisterTestCase) + return unittest.makeSuite(RegisterTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_sdist.py b/src/distutils2/tests/test_sdist.py --- a/src/distutils2/tests/test_sdist.py +++ b/src/distutils2/tests/test_sdist.py @@ -1,6 +1,5 @@ """Tests for distutils.command.sdist.""" import os -import unittest2 import shutil import zipfile import tarfile @@ -29,6 +28,7 @@ from distutils2.command.sdist import sdist from distutils2.command.sdist import show_formats from distutils2.core import Distribution +from distutils2.tests.support import unittest from distutils2.tests.test_config import PyPIRCCommandTestCase from distutils2.errors import DistutilsExecError, DistutilsOptionError from distutils2.spawn import find_executable @@ -97,7 +97,7 @@ cmd.warn = _warn return dist, cmd - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_prune_file_list(self): # this test creates a package with some vcs dirs in it # and launch sdist to make sure they get pruned @@ -139,7 +139,7 @@ # making sure everything has been pruned correctly self.assertEquals(len(content), 4) - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_make_distribution(self): # check if tar and gzip are installed @@ -176,7 +176,7 @@ self.assertEquals(result, ['fake-1.0.tar', 'fake-1.0.tar.gz']) - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_add_defaults(self): # http://bugs.python.org/issue2279 @@ -238,7 +238,7 @@ manifest = open(join(self.tmp_dir, 'MANIFEST')).read() self.assertEquals(manifest, MANIFEST % {'sep': os.sep}) - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_metadata_check_option(self): # testing the `medata-check` option dist, cmd = self.get_cmd(metadata={}) @@ -293,8 +293,8 @@ cmd.formats = 'supazipa' self.assertRaises(DistutilsOptionError, cmd.finalize_options) - @unittest2.skipUnless(zlib, "requires zlib") - @unittest2.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") + @unittest.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") def test_make_distribution_owner_group(self): # check if tar and gzip are installed @@ -357,7 +357,7 @@ self.assertIn('MANIFEST.in', cmd.filelist.files) def test_suite(): - return unittest2.makeSuite(SDistTestCase) + return unittest.makeSuite(SDistTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_spawn.py b/src/distutils2/tests/test_spawn.py --- a/src/distutils2/tests/test_spawn.py +++ b/src/distutils2/tests/test_spawn.py @@ -1,5 +1,4 @@ """Tests for distutils.spawn.""" -import unittest2 import os import time from distutils2.tests import captured_stdout @@ -8,10 +7,11 @@ from distutils2.spawn import spawn, find_executable from distutils2.errors import DistutilsExecError from distutils2.tests import support +from distutils2.tests.support import unittest class SpawnTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_nt_quote_args(self): @@ -23,7 +23,7 @@ self.assertEquals(res, wanted) - @unittest2.skipUnless(os.name in ('nt', 'posix'), + @unittest.skipUnless(os.name in ('nt', 'posix'), 'Runs only under posix or nt') def test_spawn(self): tmpdir = self.mkdtemp() @@ -54,7 +54,7 @@ spawn([exe]) # should work without any error def test_suite(): - return unittest2.makeSuite(SpawnTestCase) + return unittest.makeSuite(SpawnTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_unixccompiler.py b/src/distutils2/tests/test_unixccompiler.py --- a/src/distutils2/tests/test_unixccompiler.py +++ b/src/distutils2/tests/test_unixccompiler.py @@ -1,6 +1,5 @@ """Tests for distutils.unixccompiler.""" import sys -import unittest2 try: import sysconfig @@ -8,8 +7,9 @@ from distutils2._backport import sysconfig from distutils2.compiler.unixccompiler import UnixCCompiler +from distutils2.tests.support import unittest -class UnixCCompilerTestCase(unittest2.TestCase): +class UnixCCompilerTestCase(unittest.TestCase): def setUp(self): self._backup_platform = sys.platform @@ -127,7 +127,7 @@ def test_suite(): - return unittest2.makeSuite(UnixCCompilerTestCase) + return unittest.makeSuite(UnixCCompilerTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_upload.py b/src/distutils2/tests/test_upload.py --- a/src/distutils2/tests/test_upload.py +++ b/src/distutils2/tests/test_upload.py @@ -2,13 +2,13 @@ # -*- encoding: utf8 -*- import sys import os -import unittest2 from distutils2.command import upload as upload_mod from distutils2.command.upload import upload from distutils2.core import Distribution from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.tests.test_config import PYPIRC, PyPIRCCommandTestCase PYPIRC_LONG_PASSWORD = """\ @@ -126,7 +126,7 @@ self.assertFalse('\n' in auth) def test_suite(): - return unittest2.makeSuite(uploadTestCase) + return unittest.makeSuite(uploadTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_util.py b/src/distutils2/tests/test_util.py --- a/src/distutils2/tests/test_util.py +++ b/src/distutils2/tests/test_util.py @@ -1,7 +1,6 @@ """Tests for distutils.util.""" import os import sys -import unittest2 from copy import copy from StringIO import StringIO import subprocess @@ -17,6 +16,7 @@ byte_compile, find_packages) from distutils2 import util from distutils2.tests import support +from distutils2.tests.support import unittest class FakePopen(object): test_class = None @@ -34,7 +34,7 @@ class UtilTestCase(support.EnvironGuard, support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(UtilTestCase, self).setUp() @@ -243,7 +243,7 @@ res = get_compiler_versions() self.assertEquals(res[2], None) - @unittest2.skipUnless(hasattr(sys, 'dont_write_bytecode'), + @unittest.skipUnless(hasattr(sys, 'dont_write_bytecode'), 'no dont_write_bytecode support') def test_dont_write_bytecode(self): # makes sure byte_compile raise a DistutilsError @@ -298,7 +298,7 @@ def test_suite(): - return unittest2.makeSuite(UtilTestCase) + return unittest.makeSuite(UtilTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_version.py b/src/distutils2/tests/test_version.py --- a/src/distutils2/tests/test_version.py +++ b/src/distutils2/tests/test_version.py @@ -1,5 +1,4 @@ """Tests for distutils.version.""" -import unittest import doctest import os @@ -7,6 +6,7 @@ from distutils2.version import IrrationalVersionError from distutils2.version import suggest_normalized_version as suggest from distutils2.version import VersionPredicate +from distutils2.tests.support import unittest class VersionTestCase(unittest.TestCase): diff --git a/src/runtests.py b/src/runtests.py --- a/src/runtests.py +++ b/src/runtests.py @@ -26,9 +26,9 @@ if __name__ == "__main__": try: - import unittest2 + from distutils2.tests.support import unittest except ImportError: - print('!!! You need to install unittest2') + print >> sys.stderr, 'Error: You have to install unittest2' sys.exit(1) sys.exit(test_main()) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Wed Jun 2 01:18:23 2010 From: python-checkins at python.org (tarek.ziade) Date: Wed, 02 Jun 2010 01:18:23 +0200 Subject: [Python-checkins] distutils2: moving cmd.py into command/ Message-ID: tarek.ziade pushed 8a30e3667a75 to distutils2: http://hg.python.org/distutils2/rev/8a30e3667a75 changeset: 197:8a30e3667a75 tag: tip user: Tarek Ziade date: Wed Jun 02 01:18:14 2010 +0200 summary: moving cmd.py into command/ files: src/distutils2/cmd.py, src/distutils2/command/cmd.py, src/distutils2/command/install_egg_info.py, src/distutils2/config.py, src/distutils2/core.py, src/distutils2/dist.py, src/distutils2/tests/test_cmd.py, src/distutils2/tests/test_dist.py diff --git a/src/distutils2/cmd.py b/src/distutils2/command/cmd.py rename from src/distutils2/cmd.py rename to src/distutils2/command/cmd.py diff --git a/src/distutils2/command/install_egg_info.py b/src/distutils2/command/install_egg_info.py --- a/src/distutils2/command/install_egg_info.py +++ b/src/distutils2/command/install_egg_info.py @@ -4,7 +4,7 @@ a package's PKG-INFO metadata.""" -from distutils2.cmd import Command +from distutils2.command.cmd import Command from distutils2 import log from distutils2._backport.shutil import rmtree import os, sys, re diff --git a/src/distutils2/config.py b/src/distutils2/config.py --- a/src/distutils2/config.py +++ b/src/distutils2/config.py @@ -6,7 +6,7 @@ import os from ConfigParser import ConfigParser -from distutils2.cmd import Command +from distutils2.command.cmd import Command DEFAULT_PYPIRC = """\ [distutils] diff --git a/src/distutils2/core.py b/src/distutils2/core.py --- a/src/distutils2/core.py +++ b/src/distutils2/core.py @@ -17,7 +17,7 @@ # Mainly import these so setup scripts can "from distutils2.core import" them. from distutils2.dist import Distribution -from distutils2.cmd import Command +from distutils2.command.cmd import Command from distutils2.config import PyPIRCCommand from distutils2.extension import Extension diff --git a/src/distutils2/dist.py b/src/distutils2/dist.py --- a/src/distutils2/dist.py +++ b/src/distutils2/dist.py @@ -493,7 +493,7 @@ None if the user asked for help on this command. """ # late import because of mutual dependence between these modules - from distutils2.cmd import Command + from distutils2.command.cmd import Command # Pull the current command from the head of the command line command = args[0] @@ -607,7 +607,7 @@ """ # late import because of mutual dependence between these modules from distutils2.core import gen_usage - from distutils2.cmd import Command + from distutils2.command.cmd import Command if global_options: if display_options: @@ -904,7 +904,7 @@ Returns the reinitialized command object. """ - from distutils2.cmd import Command + from distutils2.command.cmd import Command if not isinstance(command, Command): command_name = command command = self.get_command_obj(command_name) diff --git a/src/distutils2/tests/test_cmd.py b/src/distutils2/tests/test_cmd.py --- a/src/distutils2/tests/test_cmd.py +++ b/src/distutils2/tests/test_cmd.py @@ -2,7 +2,7 @@ import os from distutils2.tests import captured_stdout, run_unittest -from distutils2.cmd import Command +from distutils2.command.cmd import Command from distutils2.dist import Distribution from distutils2.errors import DistutilsOptionError from distutils2.tests.support import unittest diff --git a/src/distutils2/tests/test_dist.py b/src/distutils2/tests/test_dist.py --- a/src/distutils2/tests/test_dist.py +++ b/src/distutils2/tests/test_dist.py @@ -8,7 +8,7 @@ import textwrap from distutils2.dist import Distribution, fix_help_options, DistributionMetadata -from distutils2.cmd import Command +from distutils2.command.cmd import Command import distutils2.dist from distutils2.tests import TESTFN, captured_stdout from distutils2.tests import support -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Wed Jun 2 01:21:12 2010 From: python-checkins at python.org (georg.brandl) Date: Wed, 2 Jun 2010 01:21:12 +0200 (CEST) Subject: [Python-checkins] r81644 - in python/branches/release26-maint: Doc/library/re.rst Message-ID: <20100601232112.9BF95F107@mail.python.org> Author: georg.brandl Date: Wed Jun 2 01:21:12 2010 New Revision: 81644 Log: Merged revisions 81635 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81635 | georg.brandl | 2010-06-01 09:25:23 +0200 (Di, 01 Jun 2010) | 1 line Put docs for RegexObject.search() before RegexObject.match() to mirror re.search() and re.match() order. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/re.rst Modified: python/branches/release26-maint/Doc/library/re.rst ============================================================================== --- python/branches/release26-maint/Doc/library/re.rst (original) +++ python/branches/release26-maint/Doc/library/re.rst Wed Jun 2 01:21:12 2010 @@ -677,18 +677,12 @@ The :class:`RegexObject` class supports the following methods and attributes: + .. method:: RegexObject.search(string[, pos[, endpos]]) - .. method:: RegexObject.match(string[, pos[, endpos]]) - - If zero or more characters at the beginning of *string* match this regular - expression, return a corresponding :class:`MatchObject` instance. Return - ``None`` if the string does not match the pattern; note that this is different - from a zero-length match. - - .. note:: - - If you want to locate a match anywhere in *string*, use - :meth:`~RegexObject.search` instead. + Scan through *string* looking for a location where this regular expression + produces a match, and return a corresponding :class:`MatchObject` instance. + Return ``None`` if no position in the string matches the pattern; note that this + is different from finding a zero-length match at some point in the string. The optional second parameter *pos* gives an index in the string where the search is to start; it defaults to ``0``. This is not completely equivalent to @@ -700,24 +694,34 @@ will be as if the string is *endpos* characters long, so only the characters from *pos* to ``endpos - 1`` will be searched for a match. If *endpos* is less than *pos*, no match will be found, otherwise, if *rx* is a compiled regular - expression object, ``rx.match(string, 0, 50)`` is equivalent to - ``rx.match(string[:50], 0)``. + expression object, ``rx.search(string, 0, 50)`` is equivalent to + ``rx.search(string[:50], 0)``. - >>> pattern = re.compile("o") - >>> pattern.match("dog") # No match as "o" is not at the start of "dog." - >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog". - <_sre.SRE_Match object at ...> + >>> pattern = re.compile("d") + >>> pattern.search("dog") # Match at index 0 + <_sre.SRE_Match object at ...> + >>> pattern.search("dog", 1) # No match; search doesn't include the "d" - .. method:: RegexObject.search(string[, pos[, endpos]]) + .. method:: RegexObject.match(string[, pos[, endpos]]) - Scan through *string* looking for a location where this regular expression - produces a match, and return a corresponding :class:`MatchObject` instance. - Return ``None`` if no position in the string matches the pattern; note that this - is different from finding a zero-length match at some point in the string. + If zero or more characters at the *beginning* of *string* match this regular + expression, return a corresponding :class:`MatchObject` instance. Return + ``None`` if the string does not match the pattern; note that this is different + from a zero-length match. The optional *pos* and *endpos* parameters have the same meaning as for the - :meth:`~RegexObject.match` method. + :meth:`~RegexObject.search` method. + + .. note:: + + If you want to locate a match anywhere in *string*, use + :meth:`~RegexObject.search` instead. + + >>> pattern = re.compile("o") + >>> pattern.match("dog") # No match as "o" is not at the start of "dog". + >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog". + <_sre.SRE_Match object at ...> .. method:: RegexObject.split(string[, maxsplit=0]) From solipsis at pitrou.net Wed Jun 2 01:23:18 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 2 Jun 2010 01:23:18 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81642): sum=0 Message-ID: <20100601232318.A66871770A@ns6635.ovh.net> py3k results for svn r81642 (hg cset a5d9c6f86abc) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogkKBlc4', '-x'] From python-checkins at python.org Wed Jun 2 04:19:15 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 2 Jun 2010 04:19:15 +0200 (CEST) Subject: [Python-checkins] r81645 - python/trunk/Doc/library/urllib.rst Message-ID: <20100602021915.BA201EE983@mail.python.org> Author: senthil.kumaran Date: Wed Jun 2 04:19:15 2010 New Revision: 81645 Log: Fix issue8788 - description of doseq parameter in urllib.urlencode Modified: python/trunk/Doc/library/urllib.rst Modified: python/trunk/Doc/library/urllib.rst ============================================================================== --- python/trunk/Doc/library/urllib.rst (original) +++ python/trunk/Doc/library/urllib.rst Wed Jun 2 04:19:15 2010 @@ -236,17 +236,19 @@ .. function:: urlencode(query[, doseq]) - Convert a mapping object or a sequence of two-element tuples to a "url-encoded" - string, suitable to pass to :func:`urlopen` above as the optional *data* - argument. This is useful to pass a dictionary of form fields to a ``POST`` - request. The resulting string is a series of ``key=value`` pairs separated by - ``'&'`` characters, where both *key* and *value* are quoted using - :func:`quote_plus` above. If the optional parameter *doseq* is present and - evaluates to true, individual ``key=value`` pairs are generated for each element - of the sequence. When a sequence of two-element tuples is used as the *query* - argument, the first element of each tuple is a key and the second is a value. - The order of parameters in the encoded string will match the order of parameter - tuples in the sequence. The :mod:`urlparse` module provides the functions + Convert a mapping object or a sequence of two-element tuples to a + "url-encoded" string, suitable to pass to :func:`urlopen` above as the + optional *data* argument. This is useful to pass a dictionary of form + fields to a ``POST`` request. The resulting string is a series of + ``key=value`` pairs separated by ``'&'`` characters, where both *key* and + *value* are quoted using :func:`quote_plus` above. When a sequence of + two-element tuples is used as the *query* argument, the first element of + each tuple is a key and the second is a value. The value element in itself + can be a sequence and in that case, if the optional parameter *doseq* is + evaluates to *True*, individual ``key=value`` pairs separated by ``'&'``are + generated for each element of the value sequence for the key. The order of + parameters in the encoded string will match the order of parameter tuples in + the sequence. The :mod:`urlparse` module provides the functions :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings into Python data structures. From python-checkins at python.org Wed Jun 2 04:22:00 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 2 Jun 2010 04:22:00 +0200 (CEST) Subject: [Python-checkins] r81646 - in python/branches/release26-maint: Doc/library/urllib.rst Message-ID: <20100602022200.7F3BBEE983@mail.python.org> Author: senthil.kumaran Date: Wed Jun 2 04:22:00 2010 New Revision: 81646 Log: Merged revisions 81645 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81645 | senthil.kumaran | 2010-06-02 07:49:15 +0530 (Wed, 02 Jun 2010) | 3 lines Fix issue8788 - description of doseq parameter in urllib.urlencode ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/urllib.rst Modified: python/branches/release26-maint/Doc/library/urllib.rst ============================================================================== --- python/branches/release26-maint/Doc/library/urllib.rst (original) +++ python/branches/release26-maint/Doc/library/urllib.rst Wed Jun 2 04:22:00 2010 @@ -236,17 +236,19 @@ .. function:: urlencode(query[, doseq]) - Convert a mapping object or a sequence of two-element tuples to a "url-encoded" - string, suitable to pass to :func:`urlopen` above as the optional *data* - argument. This is useful to pass a dictionary of form fields to a ``POST`` - request. The resulting string is a series of ``key=value`` pairs separated by - ``'&'`` characters, where both *key* and *value* are quoted using - :func:`quote_plus` above. If the optional parameter *doseq* is present and - evaluates to true, individual ``key=value`` pairs are generated for each element - of the sequence. When a sequence of two-element tuples is used as the *query* - argument, the first element of each tuple is a key and the second is a value. - The order of parameters in the encoded string will match the order of parameter - tuples in the sequence. The :mod:`urlparse` module provides the functions + Convert a mapping object or a sequence of two-element tuples to a + "url-encoded" string, suitable to pass to :func:`urlopen` above as the + optional *data* argument. This is useful to pass a dictionary of form + fields to a ``POST`` request. The resulting string is a series of + ``key=value`` pairs separated by ``'&'`` characters, where both *key* and + *value* are quoted using :func:`quote_plus` above. When a sequence of + two-element tuples is used as the *query* argument, the first element of + each tuple is a key and the second is a value. The value element in itself + can be a sequence and in that case, if the optional parameter *doseq* is + evaluates to *True*, individual ``key=value`` pairs separated by ``'&'``are + generated for each element of the value sequence for the key. The order of + parameters in the encoded string will match the order of parameter tuples in + the sequence. The :mod:`urlparse` module provides the functions :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings into Python data structures. From python-checkins at python.org Wed Jun 2 04:29:00 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 2 Jun 2010 04:29:00 +0200 (CEST) Subject: [Python-checkins] r81647 - in python/branches/py3k: Doc/library/urllib.parse.rst Message-ID: <20100602022900.ABCBAEE990@mail.python.org> Author: senthil.kumaran Date: Wed Jun 2 04:29:00 2010 New Revision: 81647 Log: Merged revisions 81645 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81645 | senthil.kumaran | 2010-06-02 07:49:15 +0530 (Wed, 02 Jun 2010) | 3 lines Fix issue8788 - description of doseq parameter in urllib.urlencode ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/urllib.parse.rst Modified: python/branches/py3k/Doc/library/urllib.parse.rst ============================================================================== --- python/branches/py3k/Doc/library/urllib.parse.rst (original) +++ python/branches/py3k/Doc/library/urllib.parse.rst Wed Jun 2 04:29:00 2010 @@ -312,19 +312,21 @@ .. function:: urlencode(query, doseq=False) - Convert a mapping object or a sequence of two-element tuples to a "url-encoded" - string, suitable to pass to :func:`urlopen` above as the optional *data* - argument. This is useful to pass a dictionary of form fields to a ``POST`` - request. The resulting string is a series of ``key=value`` pairs separated by - ``'&'`` characters, where both *key* and *value* are quoted using - :func:`quote_plus` above. If the optional parameter *doseq* is present and - evaluates to true, individual ``key=value`` pairs are generated for each element - of the sequence. When a sequence of two-element tuples is used as the *query* - argument, the first element of each tuple is a key and the second is a value. - The order of parameters in the encoded string will match the order of parameter - tuples in the sequence. This module provides the functions - :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings - into Python data structures. + Convert a mapping object or a sequence of two-element tuples to a + "url-encoded" string, suitable to pass to :func:`urlopen` above as the + optional *data* argument. This is useful to pass a dictionary of form + fields to a ``POST`` request. The resulting string is a series of + ``key=value`` pairs separated by ``'&'`` characters, where both *key* and + *value* are quoted using :func:`quote_plus` above. When a sequence of + two-element tuples is used as the *query* argument, the first element of + each tuple is a key and the second is a value. The value element in itself + can be a sequence and in that case, if the optional parameter *doseq* is + evaluates to *True*, individual ``key=value`` pairs separated by ``'&'``are + generated for each element of the value sequence for the key. The order of + parameters in the encoded string will match the order of parameter tuples in + the sequence. This module provides the functions :func:`parse_qs` and + :func:`parse_qsl` which are used to parse query strings into Python data + structures. .. seealso:: From python-checkins at python.org Wed Jun 2 04:31:04 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 2 Jun 2010 04:31:04 +0200 (CEST) Subject: [Python-checkins] r81648 - in python/branches/release31-maint: Doc/library/urllib.parse.rst Message-ID: <20100602023104.7D70EEE9A5@mail.python.org> Author: senthil.kumaran Date: Wed Jun 2 04:31:04 2010 New Revision: 81648 Log: Merged revisions 81647 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81647 | senthil.kumaran | 2010-06-02 07:59:00 +0530 (Wed, 02 Jun 2010) | 9 lines Merged revisions 81645 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81645 | senthil.kumaran | 2010-06-02 07:49:15 +0530 (Wed, 02 Jun 2010) | 3 lines Fix issue8788 - description of doseq parameter in urllib.urlencode ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/urllib.parse.rst Modified: python/branches/release31-maint/Doc/library/urllib.parse.rst ============================================================================== --- python/branches/release31-maint/Doc/library/urllib.parse.rst (original) +++ python/branches/release31-maint/Doc/library/urllib.parse.rst Wed Jun 2 04:31:04 2010 @@ -309,19 +309,21 @@ .. function:: urlencode(query, doseq=False) - Convert a mapping object or a sequence of two-element tuples to a "url-encoded" - string, suitable to pass to :func:`urlopen` above as the optional *data* - argument. This is useful to pass a dictionary of form fields to a ``POST`` - request. The resulting string is a series of ``key=value`` pairs separated by - ``'&'`` characters, where both *key* and *value* are quoted using - :func:`quote_plus` above. If the optional parameter *doseq* is present and - evaluates to true, individual ``key=value`` pairs are generated for each element - of the sequence. When a sequence of two-element tuples is used as the *query* - argument, the first element of each tuple is a key and the second is a value. - The order of parameters in the encoded string will match the order of parameter - tuples in the sequence. This module provides the functions - :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings - into Python data structures. + Convert a mapping object or a sequence of two-element tuples to a + "url-encoded" string, suitable to pass to :func:`urlopen` above as the + optional *data* argument. This is useful to pass a dictionary of form + fields to a ``POST`` request. The resulting string is a series of + ``key=value`` pairs separated by ``'&'`` characters, where both *key* and + *value* are quoted using :func:`quote_plus` above. When a sequence of + two-element tuples is used as the *query* argument, the first element of + each tuple is a key and the second is a value. The value element in itself + can be a sequence and in that case, if the optional parameter *doseq* is + evaluates to *True*, individual ``key=value`` pairs separated by ``'&'``are + generated for each element of the value sequence for the key. The order of + parameters in the encoded string will match the order of parameter tuples in + the sequence. This module provides the functions :func:`parse_qs` and + :func:`parse_qsl` which are used to parse query strings into Python data + structures. .. seealso:: From python-checkins at python.org Wed Jun 2 05:47:14 2010 From: python-checkins at python.org (ronald.oussoren) Date: Wed, 2 Jun 2010 05:47:14 +0200 (CEST) Subject: [Python-checkins] r81649 - in python/trunk: Mac/Tools/pythonw.c Misc/NEWS Message-ID: <20100602034714.9975AEE990@mail.python.org> Author: ronald.oussoren Date: Wed Jun 2 05:47:14 2010 New Revision: 81649 Log: Fix for issue8868: without this patch 'MacOS.WMAvailable()' will return False on MacOSX 10.5 or earlier and scripts won't be able to access GUI functionality. Modified: python/trunk/Mac/Tools/pythonw.c python/trunk/Misc/NEWS Modified: python/trunk/Mac/Tools/pythonw.c ============================================================================== --- python/trunk/Mac/Tools/pythonw.c (original) +++ python/trunk/Mac/Tools/pythonw.c Wed Jun 2 05:47:14 2010 @@ -149,6 +149,14 @@ main(int argc, char **argv) { char* exec_path = get_python_path(); + /* + * Let argv[0] refer to the new interpreter. This is needed to + * get the effect we want on OSX 10.5 or earlier. That is, without + * changing argv[0] the real interpreter won't have access to + * the Window Server. + */ + argv[0] = exec_path; + #ifdef HAVE_SPAWN_H /* We're weak-linking to posix-spawnv to ensure that Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Jun 2 05:47:14 2010 @@ -32,6 +32,9 @@ - Issue #7079: Fix a possible crash when closing a file object while using it from another thread. Patch by Daniel Stutzbach. +- Issue #8868: Fix that ensures that python scripts have access to the + Window Server again in a framework build on MacOSX 10.5 or earlier. + C-API ----- From python-checkins at python.org Wed Jun 2 05:50:56 2010 From: python-checkins at python.org (ronald.oussoren) Date: Wed, 2 Jun 2010 05:50:56 +0200 (CEST) Subject: [Python-checkins] r81650 - in python/branches/py3k: Mac/Tools/pythonw.c Message-ID: <20100602035056.EFC74F3C4@mail.python.org> Author: ronald.oussoren Date: Wed Jun 2 05:50:56 2010 New Revision: 81650 Log: Merged revisions 81649 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81649 | ronald.oussoren | 2010-06-02 05:47:14 +0200 (Wed, 02 Jun 2010) | 5 lines Fix for issue8868: without this patch 'MacOS.WMAvailable()' will return False on MacOSX 10.5 or earlier and scripts won't be able to access GUI functionality. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Mac/Tools/pythonw.c Modified: python/branches/py3k/Mac/Tools/pythonw.c ============================================================================== --- python/branches/py3k/Mac/Tools/pythonw.c (original) +++ python/branches/py3k/Mac/Tools/pythonw.c Wed Jun 2 05:50:56 2010 @@ -151,6 +151,14 @@ main(int argc, char **argv) { char* exec_path = get_python_path(); + /* + * Let argv[0] refer to the new interpreter. This is needed to + * get the effect we want on OSX 10.5 or earlier. That is, without + * changing argv[0] the real interpreter won't have access to + * the Window Server. + */ + argv[0] = exec_path; + #ifdef HAVE_SPAWN_H /* We're weak-linking to posix-spawnv to ensure that * an executable build on 10.5 can work on 10.4. From python-checkins at python.org Wed Jun 2 12:05:31 2010 From: python-checkins at python.org (vinay.sajip) Date: Wed, 2 Jun 2010 12:05:31 +0200 (CEST) Subject: [Python-checkins] r81651 - python/trunk/Lib/logging/config.py Message-ID: <20100602100531.EE241EEA11@mail.python.org> Author: vinay.sajip Date: Wed Jun 2 12:05:31 2010 New Revision: 81651 Log: Logging: improved error reporting for BaseConfigurator.resolve(). Modified: python/trunk/Lib/logging/config.py Modified: python/trunk/Lib/logging/config.py ============================================================================== --- python/trunk/Lib/logging/config.py (original) +++ python/trunk/Lib/logging/config.py Wed Jun 2 12:05:31 2010 @@ -387,15 +387,21 @@ """ name = s.split('.') used = name.pop(0) - found = self.importer(used) - for frag in name: - used += '.' + frag - try: - found = getattr(found, frag) - except AttributeError: - self.importer(used) - found = getattr(found, frag) - return found + try: + found = self.importer(used) + for frag in name: + used += '.' + frag + try: + found = getattr(found, frag) + except AttributeError: + self.importer(used) + found = getattr(found, frag) + return found + except ImportError: + e, tb = sys.exc_info()[1:] + v = ValueError('Cannot resolve %r: %s' % (s, e)) + v.__cause__, v.__traceback__ = e, tb + raise v def ext_convert(self, value): """Default converter for the ext:// protocol.""" From nnorwitz at gmail.com Wed Jun 2 13:15:31 2010 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 2 Jun 2010 07:15:31 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20100602111531.GA10528@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [-84, 0, 0] references, sum=-84 Less important issues: ---------------------- From python-checkins at python.org Wed Jun 2 19:08:47 2010 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 2 Jun 2010 19:08:47 +0200 (CEST) Subject: [Python-checkins] r81652 - python/trunk/Doc/library/subprocess.rst Message-ID: <20100602170847.2DF41EEA87@mail.python.org> Author: antoine.pitrou Date: Wed Jun 2 19:08:47 2010 New Revision: 81652 Log: Issue #8873: add a documentation note about possible performance issues with the default of unbuffered IO in subprocess.Popen. 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 Wed Jun 2 19:08:47 2010 @@ -94,6 +94,12 @@ size. A negative *bufsize* means to use the system default, which usually means fully buffered. The default value for *bufsize* is :const:`0` (unbuffered). + .. note:: + + If you experience performance issues, it is recommended that you try to + enable buffering by setting *bufsize* to either -1 or a large enough + positive value (such as 4096). + The *executable* argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the *args* argument. If ``shell=True``, the *executable* argument specifies which shell to use. On Unix, From python-checkins at python.org Wed Jun 2 19:10:46 2010 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 2 Jun 2010 19:10:46 +0200 (CEST) Subject: [Python-checkins] r81653 - in python/branches/release26-maint: Doc/library/subprocess.rst Message-ID: <20100602171046.16090CA7D@mail.python.org> Author: antoine.pitrou Date: Wed Jun 2 19:10:45 2010 New Revision: 81653 Log: Merged revisions 81652 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81652 | antoine.pitrou | 2010-06-02 19:08:47 +0200 (mer., 02 juin 2010) | 4 lines Issue #8873: add a documentation note about possible performance issues with the default of unbuffered IO in subprocess.Popen. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/subprocess.rst Modified: python/branches/release26-maint/Doc/library/subprocess.rst ============================================================================== --- python/branches/release26-maint/Doc/library/subprocess.rst (original) +++ python/branches/release26-maint/Doc/library/subprocess.rst Wed Jun 2 19:10:45 2010 @@ -94,6 +94,12 @@ size. A negative *bufsize* means to use the system default, which usually means fully buffered. The default value for *bufsize* is :const:`0` (unbuffered). + .. note:: + + If you experience performance issues, it is recommended that you try to + enable buffering by setting *bufsize* to either -1 or a large enough + positive value (such as 4096). + The *executable* argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the *args* argument. If ``shell=True``, the *executable* argument specifies which shell to use. On Unix, From python-checkins at python.org Wed Jun 2 19:10:49 2010 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 2 Jun 2010 19:10:49 +0200 (CEST) Subject: [Python-checkins] r81654 - in python/branches/py3k: Doc/library/subprocess.rst Message-ID: <20100602171049.402A1EEAB6@mail.python.org> Author: antoine.pitrou Date: Wed Jun 2 19:10:49 2010 New Revision: 81654 Log: Merged revisions 81652 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81652 | antoine.pitrou | 2010-06-02 19:08:47 +0200 (mer., 02 juin 2010) | 4 lines Issue #8873: add a documentation note about possible performance issues with the default of unbuffered IO in subprocess.Popen. ........ 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 Wed Jun 2 19:10:49 2010 @@ -89,6 +89,12 @@ size. A negative *bufsize* means to use the system default, which usually means fully buffered. The default value for *bufsize* is :const:`0` (unbuffered). + .. note:: + + If you experience performance issues, it is recommended that you try to + enable buffering by setting *bufsize* to either -1 or a large enough + positive value (such as 4096). + The *executable* argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the *args* argument. If ``shell=True``, the *executable* argument specifies which shell to use. On Unix, From python-checkins at python.org Wed Jun 2 19:11:32 2010 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 2 Jun 2010 19:11:32 +0200 (CEST) Subject: [Python-checkins] r81655 - in python/branches/release31-maint: Doc/library/subprocess.rst Message-ID: <20100602171132.561D0EEAC1@mail.python.org> Author: antoine.pitrou Date: Wed Jun 2 19:11:32 2010 New Revision: 81655 Log: Merged revisions 81654 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81654 | antoine.pitrou | 2010-06-02 19:10:49 +0200 (mer., 02 juin 2010) | 10 lines Merged revisions 81652 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81652 | antoine.pitrou | 2010-06-02 19:08:47 +0200 (mer., 02 juin 2010) | 4 lines Issue #8873: add a documentation note about possible performance issues with the default of unbuffered IO in subprocess.Popen. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/subprocess.rst Modified: python/branches/release31-maint/Doc/library/subprocess.rst ============================================================================== --- python/branches/release31-maint/Doc/library/subprocess.rst (original) +++ python/branches/release31-maint/Doc/library/subprocess.rst Wed Jun 2 19:11:32 2010 @@ -88,6 +88,12 @@ size. A negative *bufsize* means to use the system default, which usually means fully buffered. The default value for *bufsize* is :const:`0` (unbuffered). + .. note:: + + If you experience performance issues, it is recommended that you try to + enable buffering by setting *bufsize* to either -1 or a large enough + positive value (such as 4096). + The *executable* argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the *args* argument. If ``shell=True``, the *executable* argument specifies which shell to use. On Unix, From python-checkins at python.org Wed Jun 2 20:10:09 2010 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 2 Jun 2010 20:10:09 +0200 (CEST) Subject: [Python-checkins] r81656 - python/branches/py3k/Doc/library/dis.rst Message-ID: <20100602181009.4D524EEA98@mail.python.org> Author: benjamin.peterson Date: Wed Jun 2 20:10:09 2010 New Revision: 81656 Log: remove description of LOAD_LOCALS #8874 Modified: python/branches/py3k/Doc/library/dis.rst Modified: python/branches/py3k/Doc/library/dis.rst ============================================================================== --- python/branches/py3k/Doc/library/dis.rst (original) +++ python/branches/py3k/Doc/library/dis.rst Wed Jun 2 20:10:09 2010 @@ -383,13 +383,6 @@ the stack so that it is available for further iterations of the loop. -.. opcode:: LOAD_LOCALS () - - Pushes a reference to the locals of the current scope on the stack. This is used - in the code for a class definition: After the class body is evaluated, the - locals are passed to the class definition. - - .. opcode:: RETURN_VALUE () Returns with TOS to the caller of the function. From python-checkins at python.org Wed Jun 2 20:47:26 2010 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 2 Jun 2010 20:47:26 +0200 (CEST) Subject: [Python-checkins] r81657 - in python/branches/release31-maint: Doc/library/dis.rst Message-ID: <20100602184726.55B34EEA20@mail.python.org> Author: benjamin.peterson Date: Wed Jun 2 20:47:26 2010 New Revision: 81657 Log: Merged revisions 81656 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81656 | benjamin.peterson | 2010-06-02 13:10:09 -0500 (Wed, 02 Jun 2010) | 1 line remove description of LOAD_LOCALS #8874 ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/dis.rst Modified: python/branches/release31-maint/Doc/library/dis.rst ============================================================================== --- python/branches/release31-maint/Doc/library/dis.rst (original) +++ python/branches/release31-maint/Doc/library/dis.rst Wed Jun 2 20:47:26 2010 @@ -383,13 +383,6 @@ the stack so that it is available for further iterations of the loop. -.. opcode:: LOAD_LOCALS () - - Pushes a reference to the locals of the current scope on the stack. This is used - in the code for a class definition: After the class body is evaluated, the - locals are passed to the class definition. - - .. opcode:: RETURN_VALUE () Returns with TOS to the caller of the function. From python-checkins at python.org Thu Jun 3 00:03:15 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 3 Jun 2010 00:03:15 +0200 (CEST) Subject: [Python-checkins] r81658 - in python/trunk: Doc/library/email.message.rst Doc/library/email.mime.rst Lib/email/message.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20100602220315.E4AF6EEA78@mail.python.org> Author: r.david.murray Date: Thu Jun 3 00:03:15 2010 New Revision: 81658 Log: #1368247: make set_charset/MIMEText automatically encode unicode _payload. Fixes (mysterious, to the end user) UnicodeErrors when using utf-8 as the charset and unicode as the _text argument. Also makes the way in which unicode gets encoded to quoted printable for other charsets more sane (it only worked by accident previously). The _payload now is encoded to the charset.output_charset if it is unicode. Modified: python/trunk/Doc/library/email.message.rst python/trunk/Doc/library/email.mime.rst python/trunk/Lib/email/message.py python/trunk/Lib/email/test/test_email.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/email.message.rst ============================================================================== --- python/trunk/Doc/library/email.message.rst (original) +++ python/trunk/Doc/library/email.message.rst Thu Jun 3 00:03:15 2010 @@ -136,9 +136,10 @@ :mailheader:`Content-Type` header. Anything else will generate a :exc:`TypeError`. - The message will be assumed to be of type :mimetype:`text/\*` encoded with - *charset.input_charset*. It will be converted to *charset.output_charset* - and encoded properly, if needed, when generating the plain text + The message will be assumed to be of type :mimetype:`text/\*`, with the + payload either in unicode or encoded with *charset.input_charset*. + It will be encoded or converted to *charset.output_charset* + and transfer encoded properly, if needed, when generating the plain text representation of the message. MIME headers (:mailheader:`MIME-Version`, :mailheader:`Content-Type`, :mailheader:`Content-Transfer-Encoding`) will be added as needed. Modified: python/trunk/Doc/library/email.mime.rst ============================================================================== --- python/trunk/Doc/library/email.mime.rst (original) +++ python/trunk/Doc/library/email.mime.rst Thu Jun 3 00:03:15 2010 @@ -191,9 +191,11 @@ minor type and defaults to :mimetype:`plain`. *_charset* is the character set of the text and is passed as a parameter to the :class:`~email.mime.nonmultipart.MIMENonMultipart` constructor; it defaults - to ``us-ascii``. No guessing or encoding is performed on the text data. + to ``us-ascii``. If *_text* is unicode, it is encoded using the + *output_charset* of *_charset*, otherwise it is used as-is. .. versionchanged:: 2.4 - The previously deprecated *_encoding* argument has been removed. Encoding - happens implicitly based on the *_charset* argument. + The previously deprecated *_encoding* argument has been removed. Content + Transfer Encoding now happens happens implicitly based on the *_charset* + argument. Modified: python/trunk/Lib/email/message.py ============================================================================== --- python/trunk/Lib/email/message.py (original) +++ python/trunk/Lib/email/message.py Thu Jun 3 00:03:15 2010 @@ -256,6 +256,8 @@ charset=charset.get_output_charset()) else: self.set_param('charset', charset.get_output_charset()) + if isinstance(self._payload, unicode): + self._payload = self._payload.encode(charset.output_charset) if str(charset) != charset.get_output_charset(): self._payload = charset.body_encode(self._payload) if 'Content-Transfer-Encoding' not in self: Modified: python/trunk/Lib/email/test/test_email.py ============================================================================== --- python/trunk/Lib/email/test/test_email.py (original) +++ python/trunk/Lib/email/test/test_email.py Thu Jun 3 00:03:15 2010 @@ -1045,6 +1045,31 @@ eq(msg.get_charset().input_charset, 'us-ascii') eq(msg['content-type'], 'text/plain; charset="us-ascii"') + def test_7bit_unicode_input(self): + eq = self.assertEqual + msg = MIMEText(u'hello there', _charset='us-ascii') + eq(msg.get_charset().input_charset, 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + + def test_7bit_unicode_input_no_charset(self): + eq = self.assertEqual + msg = MIMEText(u'hello there') + eq(msg.get_charset(), 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + self.assertTrue('hello there' in msg.as_string()) + + def test_8bit_unicode_input(self): + teststr = u'\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + eq = self.assertEqual + msg = MIMEText(teststr, _charset='utf-8') + eq(msg.get_charset().output_charset, 'utf-8') + eq(msg['content-type'], 'text/plain; charset="utf-8"') + eq(msg.get_payload(decode=True), teststr.encode('utf-8')) + + def test_8bit_unicode_input_no_charset(self): + teststr = u'\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + self.assertRaises(UnicodeEncodeError, MIMEText, teststr) + # Test complicated multipart/* messages Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Jun 3 00:03:15 2010 @@ -46,6 +46,9 @@ Library ------- +- Issue #1368247: set_charset (and therefore MIMEText) now automatically + encodes a unicode _payload to the output_charset. + - Issue #7150: Raise OverflowError if the result of adding or subtracting timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range. From python-checkins at python.org Thu Jun 3 00:11:01 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 3 Jun 2010 00:11:01 +0200 (CEST) Subject: [Python-checkins] r81659 - in python/branches/release26-maint: Doc/library/email.message.rst Doc/library/email.mime.rst Lib/email/message.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20100602221101.4325BEEA7C@mail.python.org> Author: r.david.murray Date: Thu Jun 3 00:11:01 2010 New Revision: 81659 Log: Merged revisions 81658 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81658 | r.david.murray | 2010-06-02 18:03:15 -0400 (Wed, 02 Jun 2010) | 9 lines #1368247: make set_charset/MIMEText automatically encode unicode _payload. Fixes (mysterious, to the end user) UnicodeErrors when using utf-8 as the charset and unicode as the _text argument. Also makes the way in which unicode gets encoded to quoted printable for other charsets more sane (it only worked by accident previously). The _payload now is encoded to the charset.output_charset if it is unicode. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/email.message.rst python/branches/release26-maint/Doc/library/email.mime.rst python/branches/release26-maint/Lib/email/message.py python/branches/release26-maint/Lib/email/test/test_email.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Doc/library/email.message.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.message.rst (original) +++ python/branches/release26-maint/Doc/library/email.message.rst Thu Jun 3 00:11:01 2010 @@ -136,9 +136,10 @@ :mailheader:`Content-Type` header. Anything else will generate a :exc:`TypeError`. - The message will be assumed to be of type :mimetype:`text/\*` encoded with - *charset.input_charset*. It will be converted to *charset.output_charset* - and encoded properly, if needed, when generating the plain text + The message will be assumed to be of type :mimetype:`text/\*`, with the + payload either in unicode or encoded with *charset.input_charset*. + It will be encoded or converted to *charset.output_charset* + and transfer encoded properly, if needed, when generating the plain text representation of the message. MIME headers (:mailheader:`MIME-Version`, :mailheader:`Content-Type`, :mailheader:`Content-Transfer-Encoding`) will be added as needed. Modified: python/branches/release26-maint/Doc/library/email.mime.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.mime.rst (original) +++ python/branches/release26-maint/Doc/library/email.mime.rst Thu Jun 3 00:11:01 2010 @@ -191,9 +191,11 @@ minor type and defaults to :mimetype:`plain`. *_charset* is the character set of the text and is passed as a parameter to the :class:`~email.mime.nonmultipart.MIMENonMultipart` constructor; it defaults - to ``us-ascii``. No guessing or encoding is performed on the text data. + to ``us-ascii``. If *_text* is unicode, it is encoded using the + *output_charset* of *_charset*, otherwise it is used as-is. .. versionchanged:: 2.4 - The previously deprecated *_encoding* argument has been removed. Encoding - happens implicitly based on the *_charset* argument. + The previously deprecated *_encoding* argument has been removed. Content + Transfer Encoding now happens happens implicitly based on the *_charset* + argument. Modified: python/branches/release26-maint/Lib/email/message.py ============================================================================== --- python/branches/release26-maint/Lib/email/message.py (original) +++ python/branches/release26-maint/Lib/email/message.py Thu Jun 3 00:11:01 2010 @@ -256,6 +256,8 @@ charset=charset.get_output_charset()) else: self.set_param('charset', charset.get_output_charset()) + if isinstance(self._payload, unicode): + self._payload = self._payload.encode(charset.output_charset) if str(charset) != charset.get_output_charset(): self._payload = charset.body_encode(self._payload) if not self.has_key('Content-Transfer-Encoding'): Modified: python/branches/release26-maint/Lib/email/test/test_email.py ============================================================================== --- python/branches/release26-maint/Lib/email/test/test_email.py (original) +++ python/branches/release26-maint/Lib/email/test/test_email.py Thu Jun 3 00:11:01 2010 @@ -1025,6 +1025,31 @@ eq(msg.get_charset().input_charset, 'us-ascii') eq(msg['content-type'], 'text/plain; charset="us-ascii"') + def test_7bit_unicode_input(self): + eq = self.assertEqual + msg = MIMEText(u'hello there', _charset='us-ascii') + eq(msg.get_charset().input_charset, 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + + def test_7bit_unicode_input_no_charset(self): + eq = self.assertEqual + msg = MIMEText(u'hello there') + eq(msg.get_charset(), 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + self.assertTrue('hello there' in msg.as_string()) + + def test_8bit_unicode_input(self): + teststr = u'\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + eq = self.assertEqual + msg = MIMEText(teststr, _charset='utf-8') + eq(msg.get_charset().output_charset, 'utf-8') + eq(msg['content-type'], 'text/plain; charset="utf-8"') + eq(msg.get_payload(decode=True), teststr.encode('utf-8')) + + def test_8bit_unicode_input_no_charset(self): + teststr = u'\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + self.assertRaises(UnicodeEncodeError, MIMEText, teststr) + # Test complicated multipart/* messages Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Jun 3 00:11:01 2010 @@ -58,6 +58,9 @@ Library ------- +- Issue #1368247: set_charset (and therefore MIMEText) now automatically + encodes a unicode _payload to the output_charset. + - Issue #7150: Raise OverflowError if the result of adding or subtracting timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range. From solipsis at pitrou.net Thu Jun 3 01:23:54 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 3 Jun 2010 01:23:54 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81656): sum=0 Message-ID: <20100602232354.AA63E1770A@ns6635.ovh.net> py3k results for svn r81656 (hg cset a3a8e8822cf8) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogdMwVjq', '-x'] From python-checkins at python.org Thu Jun 3 03:58:29 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 3 Jun 2010 03:58:29 +0200 (CEST) Subject: [Python-checkins] r81660 - in python/branches/py3k: Lib/email/charset.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20100603015829.3C9D3EE9B3@mail.python.org> Author: r.david.murray Date: Thu Jun 3 03:58:28 2010 New Revision: 81660 Log: Fix Charset.body_encode to encode to output_charset before calling base64mime. This means that what gets encoded in base64 is the encoded version of the unicode payload. This bug was revealed by a forward port of the tests from Issue 1368247, but the fix was completely different. Note that the merge is only of the tests, the doc changes were inappropriate since email5 expects unicode, not bytes. I'm also not convinced that quopri works correctly in email5, but that's a different issue. Merged revisions 81658 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81658 | r.david.murray | 2010-06-02 18:03:15 -0400 (Wed, 02 Jun 2010) | 9 lines #1368247: make set_charset/MIMEText automatically encode unicode _payload. Fixes (mysterious, to the end user) UnicodeErrors when using utf-8 as the charset and unicode as the _text argument. Also makes the way in which unicode gets encoded to quoted printable for other charsets more sane (it only worked by accident previously). The _payload now is encoded to the charset.output_charset if it is unicode. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/email/charset.py python/branches/py3k/Lib/email/test/test_email.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/email/charset.py ============================================================================== --- python/branches/py3k/Lib/email/charset.py (original) +++ python/branches/py3k/Lib/email/charset.py Thu Jun 3 03:58:28 2010 @@ -377,6 +377,8 @@ """ # 7bit/8bit encodings return the string unchanged (module conversions) if self.body_encoding is BASE64: + if isinstance(string, str): + string = string.encode(self.output_charset) return email.base64mime.body_encode(string) elif self.body_encoding is QP: return email.quoprimime.body_encode(string) Modified: python/branches/py3k/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k/Lib/email/test/test_email.py (original) +++ python/branches/py3k/Lib/email/test/test_email.py Thu Jun 3 03:58:28 2010 @@ -535,7 +535,7 @@ # whose output character set is 7bit gets a transfer-encoding # of 7bit. eq = self.assertEqual - msg = MIMEText('\xca\xb8', _charset='euc-jp') + msg = MIMEText('?', _charset='euc-jp') eq(msg['content-transfer-encoding'], '7bit') @@ -1080,6 +1080,33 @@ eq(msg.get_charset().input_charset, 'us-ascii') eq(msg['content-type'], 'text/plain; charset="us-ascii"') + def test_7bit_input(self): + eq = self.assertEqual + msg = MIMEText('hello there', _charset='us-ascii') + eq(msg.get_charset().input_charset, 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + + def test_7bit_input_no_charset(self): + eq = self.assertEqual + msg = MIMEText('hello there') + eq(msg.get_charset(), 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + self.assertTrue('hello there' in msg.as_string()) + + def test_utf8_input(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + eq = self.assertEqual + msg = MIMEText(teststr, _charset='utf-8') + eq(msg.get_charset().output_charset, 'utf-8') + eq(msg['content-type'], 'text/plain; charset="utf-8"') + eq(msg.get_payload(decode=True), teststr.encode('utf-8')) + + @unittest.skip("can't fix because of backward compat in email5, " + "will fix in email6") + def test_utf8_input_no_charset(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + self.assertRaises(UnicodeEncodeError, MIMEText, teststr) + # Test complicated multipart/* messages Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 3 03:58:28 2010 @@ -398,6 +398,10 @@ Library ------- +- Charset.body_encode now correctly handles base64 encoding by encoding + with the output_charset before calling base64mime.encode. Passes the + tests from 2.x issue 1368247. + - Issue #8845: sqlite3 Connection objects now have a read-only in_transaction attribute that is True iff there are uncommitted changes. From python-checkins at python.org Thu Jun 3 04:05:47 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 3 Jun 2010 04:05:47 +0200 (CEST) Subject: [Python-checkins] r81661 - in python/branches/release31-maint: Lib/email/charset.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20100603020547.BD821EE9A0@mail.python.org> Author: r.david.murray Date: Thu Jun 3 04:05:47 2010 New Revision: 81661 Log: Merged revisions 81660 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81660 | r.david.murray | 2010-06-02 21:58:28 -0400 (Wed, 02 Jun 2010) | 25 lines Fix Charset.body_encode to encode to output_charset before calling base64mime. This means that what gets encoded in base64 is the encoded version of the unicode payload. This bug was revealed by a forward port of the tests from Issue 1368247, but the fix was completely different. Note that the merge is only of the tests, the doc changes were inappropriate since email5 expects unicode, not bytes. I'm also not convinced that quopri works correctly in email5, but that's a different issue. Merged revisions 81658 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81658 | r.david.murray | 2010-06-02 18:03:15 -0400 (Wed, 02 Jun 2010) | 9 lines #1368247: make set_charset/MIMEText automatically encode unicode _payload. Fixes (mysterious, to the end user) UnicodeErrors when using utf-8 as the charset and unicode as the _text argument. Also makes the way in which unicode gets encoded to quoted printable for other charsets more sane (it only worked by accident previously). The _payload now is encoded to the charset.output_charset if it is unicode. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/email/charset.py python/branches/release31-maint/Lib/email/test/test_email.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/email/charset.py ============================================================================== --- python/branches/release31-maint/Lib/email/charset.py (original) +++ python/branches/release31-maint/Lib/email/charset.py Thu Jun 3 04:05:47 2010 @@ -377,6 +377,8 @@ """ # 7bit/8bit encodings return the string unchanged (module conversions) if self.body_encoding is BASE64: + if isinstance(string, str): + string = string.encode(self.output_charset) return email.base64mime.body_encode(string) elif self.body_encoding is QP: return email.quoprimime.body_encode(string) Modified: python/branches/release31-maint/Lib/email/test/test_email.py ============================================================================== --- python/branches/release31-maint/Lib/email/test/test_email.py (original) +++ python/branches/release31-maint/Lib/email/test/test_email.py Thu Jun 3 04:05:47 2010 @@ -531,7 +531,7 @@ # whose output character set is 7bit gets a transfer-encoding # of 7bit. eq = self.assertEqual - msg = MIMEText('\xca\xb8', _charset='euc-jp') + msg = MIMEText('?', _charset='euc-jp') eq(msg['content-transfer-encoding'], '7bit') @@ -1076,6 +1076,33 @@ eq(msg.get_charset().input_charset, 'us-ascii') eq(msg['content-type'], 'text/plain; charset="us-ascii"') + def test_7bit_input(self): + eq = self.assertEqual + msg = MIMEText('hello there', _charset='us-ascii') + eq(msg.get_charset().input_charset, 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + + def test_7bit_input_no_charset(self): + eq = self.assertEqual + msg = MIMEText('hello there') + eq(msg.get_charset(), 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + self.assertTrue('hello there' in msg.as_string()) + + def test_utf8_input(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + eq = self.assertEqual + msg = MIMEText(teststr, _charset='utf-8') + eq(msg.get_charset().output_charset, 'utf-8') + eq(msg['content-type'], 'text/plain; charset="utf-8"') + eq(msg.get_payload(decode=True), teststr.encode('utf-8')) + + @unittest.skip("can't fix because of backward compat in email5, " + "will fix in email6") + def test_utf8_input_no_charset(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + self.assertRaises(UnicodeEncodeError, MIMEText, teststr) + # Test complicated multipart/* messages Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Jun 3 04:05:47 2010 @@ -54,6 +54,10 @@ Library ------- +- Charset.body_encode now correctly handles base64 encoding by encoding + with the output_charset before calling base64mime.encode. Passes the + tests from 2.x issue 1368247. + - Issue #7150: Raise OverflowError if the result of adding or subtracting timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range. From python-checkins at python.org Thu Jun 3 11:47:22 2010 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 3 Jun 2010 11:47:22 +0200 (CEST) Subject: [Python-checkins] r81662 - in python/trunk: Lib/distutils/unixccompiler.py setup.py Message-ID: <20100603094722.03CC3EE9B3@mail.python.org> Author: ronald.oussoren Date: Thu Jun 3 11:47:21 2010 New Revision: 81662 Log: Fix for issue #7724: ensure that distutils and python's own setup.py honor the MacOSX SDK when one is specified. This is needed to be able to build using the 10.4u SDK while running on OSX 10.6. This is a fixed version of the patch in r80963, I've tested this patch on OSX and Linux. Modified: python/trunk/Lib/distutils/unixccompiler.py python/trunk/setup.py Modified: python/trunk/Lib/distutils/unixccompiler.py ============================================================================== --- python/trunk/Lib/distutils/unixccompiler.py (original) +++ python/trunk/Lib/distutils/unixccompiler.py Thu Jun 3 11:47:21 2010 @@ -15,7 +15,7 @@ __revision__ = "$Id$" -import os, sys +import os, sys, re from types import StringType, NoneType from distutils import sysconfig @@ -305,10 +305,30 @@ dylib_f = self.library_filename(lib, lib_type='dylib') static_f = self.library_filename(lib, lib_type='static') + if sys.platform == 'darwin': + # On OSX users can specify an alternate SDK using + # '-isysroot', calculate the SDK root if it is specified + # (and use it further on) + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + + + for dir in dirs: shared = os.path.join(dir, shared_f) dylib = os.path.join(dir, dylib_f) static = os.path.join(dir, static_f) + + if sys.platform == 'darwin' and ( + dir.startswith('/System/') or dir.startswith('/usr/')): + shared = os.path.join(sysroot, dir[1:], shared_f) + dylib = os.path.join(sysroot, dir[1:], dylib_f) + static = os.path.join(sysroot, dir[1:], static_f) + # We're second-guessing the linker here, with not much hard # data to go on: GCC seems to prefer the shared library, so I'm # assuming that *all* Unix C compilers do. And of course I'm Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Thu Jun 3 11:47:21 2010 @@ -29,6 +29,25 @@ if dir is not None and os.path.isdir(dir) and dir not in dirlist: dirlist.insert(0, dir) +def macosx_sdk_root(): + """ + Return the directory of the current OSX SDK, + or '/' if no SDK was specified. + """ + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + return sysroot + +def is_macosx_sdk_path(path): + """ + Returns True if 'path' can be located in an OSX SDK + """ + return path.startswith('/usr/') or path.startswith('/System/') + def find_file(filename, std_dirs, paths): """Searches for the directory where a given file is located, and returns a possibly-empty list of additional directories, or None @@ -40,15 +59,28 @@ 'paths' is a list of additional locations to check; if the file is found in one of them, the resulting list will contain the directory. """ + if sys.platform == 'darwin': + # Honor the MacOSX SDK setting when one was specified. + # An SDK is a directory with the same structure as a real + # system, but with only header files and libraries. + sysroot = macosx_sdk_root() # Check the standard locations for dir in std_dirs: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [] # Check the additional directories for dir in paths: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [dir] @@ -60,11 +92,19 @@ if result is None: return None + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + # Check whether the found file is in one of the standard directories dirname = os.path.dirname(result) for p in std_dirs: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ ] + if p == dirname: return [ ] @@ -73,6 +113,11 @@ for p in paths: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ p ] + if p == dirname: return [p] else: @@ -560,7 +605,7 @@ # library and then a static library, instead of first looking # for dynamic libraries on the entiry path. # This way a staticly linked custom readline gets picked up - # before the (broken) dynamic library in /usr/lib. + # before the (possibly broken) dynamic library in /usr/lib. readline_extra_link_args = ('-Wl,-search_paths_first',) else: readline_extra_link_args = () @@ -631,24 +676,24 @@ openssl_ver = 0 openssl_ver_re = re.compile( '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' ) - for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in: - name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h') - if os.path.isfile(name): - try: - incfile = open(name, 'r') - for line in incfile: - m = openssl_ver_re.match(line) - if m: - openssl_ver = eval(m.group(1)) - break - except IOError: - pass - # first version found is what we'll use (as the compiler should) - if openssl_ver: - break + # look for the openssl version header on the compiler search path. + opensslv_h = find_file('openssl/opensslv.h', [], + inc_dirs + search_for_ssl_incs_in) + if opensslv_h: + name = os.path.join(opensslv_h[0], 'openssl/opensslv.h') + if sys.platform == 'darwin' and is_macosx_sdk_path(name): + name = os.path.join(macosx_sdk_root(), name[1:]) + try: + incfile = open(name, 'r') + for line in incfile: + m = openssl_ver_re.match(line) + if m: + openssl_ver = eval(m.group(1)) + except IOError, msg: + print "IOError while reading opensshv.h:", msg + pass - #print 'openssl_ver = 0x%08x' % openssl_ver min_openssl_ver = 0x00907000 have_any_openssl = ssl_incs is not None and ssl_libs is not None have_usable_openssl = (have_any_openssl and @@ -781,12 +826,19 @@ db_ver_inc_map = {} + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + class db_found(Exception): pass try: # See whether there is a Sleepycat header in the standard # search path. for d in inc_dirs + db_inc_paths: f = os.path.join(d, "db.h") + + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "db.h") + if db_setup_debug: print "db: looking for db.h in", f if os.path.exists(f): f = open(f).read() @@ -833,7 +885,20 @@ db_incdir.replace("include", 'lib64'), db_incdir.replace("include", 'lib'), ] - db_dirs_to_check = filter(os.path.isdir, db_dirs_to_check) + + if sys.platform != 'darwin': + db_dirs_to_check = filter(os.path.isdir, db_dirs_to_check) + + else: + # Same as other branch, but takes OSX SDK into account + tmp = [] + for dn in db_dirs_to_check: + if is_macosx_sdk_path(dn): + if os.path.isdir(os.path.join(sysroot, dn[1:])): + tmp.append(dn) + else: + if os.path.isdir(dn): + tmp.append(dn) # Look for a version specific db-X.Y before an ambiguoius dbX # XXX should we -ever- look for a dbX name? Do any @@ -895,8 +960,15 @@ # Scan the default include directories before the SQLite specific # ones. This allows one to override the copy of sqlite on OSX, # where /usr/include contains an old version of sqlite. + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + for d in inc_dirs + sqlite_inc_paths: f = os.path.join(d, "sqlite3.h") + + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "sqlite3.h") + if os.path.exists(f): if sqlite_setup_debug: print "sqlite: found %s"%f incf = open(f).read() @@ -984,6 +1056,12 @@ # the more recent berkeleydb's db.h file first in the include path # when attempting to compile and it will fail. f = "/usr/include/db.h" + + if sys.platform == 'darwin': + if is_macosx_sdk_path(f): + sysroot = macosx_sdk_root() + f = os.path.join(sysroot, f[1:]) + if os.path.exists(f) and not db_incs: data = open(f).read() m = re.search(r"#s*define\s+HASHVERSION\s+2\s*", data) @@ -1490,14 +1568,22 @@ join(os.getenv('HOME'), '/Library/Frameworks') ] + sysroot = macosx_sdk_root() + # Find the directory that contains the Tcl.framework and Tk.framework # bundles. # XXX distutils should support -F! for F in framework_dirs: # both Tcl.framework and Tk.framework should be present + + for fw in 'Tcl', 'Tk': - if not exists(join(F, fw + '.framework')): - break + if is_macosx_sdk_path(F): + if not exists(join(sysroot, F[1:], fw + '.framework')): + break + else: + if not exists(join(F, fw + '.framework')): + break else: # ok, F is now directory with both frameworks. Continure # building @@ -1527,7 +1613,12 @@ # architectures. cflags = sysconfig.get_config_vars('CFLAGS')[0] archs = re.findall('-arch\s+(\w+)', cflags) - fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,)) + + if is_macosx_sdk_path(F): + fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(os.path.join(sysroot, F[1:]),)) + else: + fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,)) + detected_archs = [] for ln in fp: a = ln.split()[-1] From python-checkins at python.org Thu Jun 3 11:56:22 2010 From: python-checkins at python.org (lars.gustaebel) Date: Thu, 3 Jun 2010 11:56:22 +0200 (CEST) Subject: [Python-checkins] r81663 - in python/trunk: Lib/tarfile.py Lib/test/test_tarfile.py Misc/NEWS Message-ID: <20100603095622.DC4A4EE9B3@mail.python.org> Author: lars.gustaebel Date: Thu Jun 3 11:56:22 2010 New Revision: 81663 Log: Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. The associated testcase did not expose this bug because it was broken too. Modified: python/trunk/Lib/tarfile.py python/trunk/Lib/test/test_tarfile.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/tarfile.py ============================================================================== --- python/trunk/Lib/tarfile.py (original) +++ python/trunk/Lib/tarfile.py Thu Jun 3 11:56:22 2010 @@ -1884,7 +1884,7 @@ tarinfo.mode = stmd tarinfo.uid = statres.st_uid tarinfo.gid = statres.st_gid - if stat.S_ISREG(stmd): + if type == REGTYPE: tarinfo.size = statres.st_size else: tarinfo.size = 0L Modified: python/trunk/Lib/test/test_tarfile.py ============================================================================== --- python/trunk/Lib/test/test_tarfile.py (original) +++ python/trunk/Lib/test/test_tarfile.py Thu Jun 3 11:56:22 2010 @@ -662,10 +662,14 @@ if hasattr(os, "link"): link = os.path.join(TEMPDIR, "link") target = os.path.join(TEMPDIR, "link_target") - open(target, "wb").close() + fobj = open(target, "wb") + fobj.write("aaa") + fobj.close() os.link(target, link) try: tar = tarfile.open(tmpname, self.mode) + # Record the link target in the inodes list. + tar.gettarinfo(target) tarinfo = tar.gettarinfo(link) self.assertEqual(tarinfo.size, 0) finally: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Jun 3 11:56:22 2010 @@ -46,6 +46,9 @@ Library ------- +- Issue #8833: tarfile created hard link entries with a size field != 0 by + mistake. + - Issue #1368247: set_charset (and therefore MIMEText) now automatically encodes a unicode _payload to the output_charset. From python-checkins at python.org Thu Jun 3 12:07:09 2010 From: python-checkins at python.org (lars.gustaebel) Date: Thu, 3 Jun 2010 12:07:09 +0200 (CEST) Subject: [Python-checkins] r81664 - in python/branches/release26-maint: Lib/tarfile.py Lib/test/test_tarfile.py Misc/NEWS Message-ID: <20100603100709.09018EE9A4@mail.python.org> Author: lars.gustaebel Date: Thu Jun 3 12:07:08 2010 New Revision: 81664 Log: Merged revisions 81663 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81663 | lars.gustaebel | 2010-06-03 11:56:22 +0200 (Thu, 03 Jun 2010) | 4 lines Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. The associated testcase did not expose this bug because it was broken too. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/tarfile.py python/branches/release26-maint/Lib/test/test_tarfile.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/tarfile.py ============================================================================== --- python/branches/release26-maint/Lib/tarfile.py (original) +++ python/branches/release26-maint/Lib/tarfile.py Thu Jun 3 12:07:08 2010 @@ -1880,7 +1880,7 @@ tarinfo.mode = stmd tarinfo.uid = statres.st_uid tarinfo.gid = statres.st_gid - if stat.S_ISREG(stmd): + if type == REGTYPE: tarinfo.size = statres.st_size else: tarinfo.size = 0L Modified: python/branches/release26-maint/Lib/test/test_tarfile.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_tarfile.py (original) +++ python/branches/release26-maint/Lib/test/test_tarfile.py Thu Jun 3 12:07:08 2010 @@ -617,10 +617,14 @@ if hasattr(os, "link"): link = os.path.join(TEMPDIR, "link") target = os.path.join(TEMPDIR, "link_target") - open(target, "wb").close() + fobj = open(target, "wb") + fobj.write("aaa") + fobj.close() os.link(target, link) try: tar = tarfile.open(tmpname, self.mode) + # Record the link target in the inodes list. + tar.gettarinfo(target) tarinfo = tar.gettarinfo(link) self.assertEqual(tarinfo.size, 0) finally: Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Jun 3 12:07:08 2010 @@ -58,6 +58,9 @@ Library ------- +- Issue #8833: tarfile created hard link entries with a size field != 0 by + mistake. + - Issue #1368247: set_charset (and therefore MIMEText) now automatically encodes a unicode _payload to the output_charset. From python-checkins at python.org Thu Jun 3 12:11:52 2010 From: python-checkins at python.org (lars.gustaebel) Date: Thu, 3 Jun 2010 12:11:52 +0200 (CEST) Subject: [Python-checkins] r81665 - in python/branches/py3k: Lib/tarfile.py Lib/test/test_tarfile.py Misc/NEWS Message-ID: <20100603101152.A9B60EE986@mail.python.org> Author: lars.gustaebel Date: Thu Jun 3 12:11:52 2010 New Revision: 81665 Log: Merged revisions 81663 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81663 | lars.gustaebel | 2010-06-03 11:56:22 +0200 (Thu, 03 Jun 2010) | 4 lines Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. The associated testcase did not expose this bug because it was broken too. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/tarfile.py python/branches/py3k/Lib/test/test_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 Thu Jun 3 12:11:52 2010 @@ -1920,7 +1920,7 @@ tarinfo.mode = stmd tarinfo.uid = statres.st_uid tarinfo.gid = statres.st_gid - if stat.S_ISREG(stmd): + if type == REGTYPE: tarinfo.size = statres.st_size else: tarinfo.size = 0 Modified: python/branches/py3k/Lib/test/test_tarfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_tarfile.py (original) +++ python/branches/py3k/Lib/test/test_tarfile.py Thu Jun 3 12:11:52 2010 @@ -661,10 +661,14 @@ if hasattr(os, "link"): link = os.path.join(TEMPDIR, "link") target = os.path.join(TEMPDIR, "link_target") - open(target, "wb").close() + fobj = open(target, "wb") + fobj.write(b"aaa") + fobj.close() os.link(target, link) try: tar = tarfile.open(tmpname, self.mode) + # Record the link target in the inodes list. + tar.gettarinfo(target) tarinfo = tar.gettarinfo(link) self.assertEqual(tarinfo.size, 0) finally: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 3 12:11:52 2010 @@ -398,6 +398,9 @@ Library ------- +- Issue #8833: tarfile created hard link entries with a size field != 0 by + mistake. + - Charset.body_encode now correctly handles base64 encoding by encoding with the output_charset before calling base64mime.encode. Passes the tests from 2.x issue 1368247. From python-checkins at python.org Thu Jun 3 12:15:18 2010 From: python-checkins at python.org (lars.gustaebel) Date: Thu, 3 Jun 2010 12:15:18 +0200 (CEST) Subject: [Python-checkins] r81666 - in python/branches/release31-maint: Lib/tarfile.py Lib/test/test_tarfile.py Misc/NEWS Message-ID: <20100603101518.E86B4EEAE6@mail.python.org> Author: lars.gustaebel Date: Thu Jun 3 12:15:18 2010 New Revision: 81666 Log: Merged revisions 81665 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81665 | lars.gustaebel | 2010-06-03 12:11:52 +0200 (Thu, 03 Jun 2010) | 11 lines Merged revisions 81663 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81663 | lars.gustaebel | 2010-06-03 11:56:22 +0200 (Thu, 03 Jun 2010) | 4 lines Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. The associated testcase did not expose this bug because it was broken too. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/tarfile.py python/branches/release31-maint/Lib/test/test_tarfile.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/tarfile.py ============================================================================== --- python/branches/release31-maint/Lib/tarfile.py (original) +++ python/branches/release31-maint/Lib/tarfile.py Thu Jun 3 12:15:18 2010 @@ -1857,7 +1857,7 @@ tarinfo.mode = stmd tarinfo.uid = statres.st_uid tarinfo.gid = statres.st_gid - if stat.S_ISREG(stmd): + if type == REGTYPE: tarinfo.size = statres.st_size else: tarinfo.size = 0 Modified: python/branches/release31-maint/Lib/test/test_tarfile.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_tarfile.py (original) +++ python/branches/release31-maint/Lib/test/test_tarfile.py Thu Jun 3 12:15:18 2010 @@ -616,10 +616,14 @@ if hasattr(os, "link"): link = os.path.join(TEMPDIR, "link") target = os.path.join(TEMPDIR, "link_target") - open(target, "wb").close() + fobj = open(target, "wb") + fobj.write(b"aaa") + fobj.close() os.link(target, link) try: tar = tarfile.open(tmpname, self.mode) + # Record the link target in the inodes list. + tar.gettarinfo(target) tarinfo = tar.gettarinfo(link) self.assertEqual(tarinfo.size, 0) finally: Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Jun 3 12:15:18 2010 @@ -54,6 +54,9 @@ Library ------- +- Issue #8833: tarfile created hard link entries with a size field != 0 by + mistake. + - Charset.body_encode now correctly handles base64 encoding by encoding with the output_charset before calling base64mime.encode. Passes the tests from 2.x issue 1368247. From nnorwitz at gmail.com Thu Jun 3 14:06:26 2010 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 3 Jun 2010 08:06:26 -0400 Subject: [Python-checkins] Python Regression Test Failures all (1) Message-ID: <20100603120626.GA10422@kbk-i386-bb.psfb.org> 352 tests OK. 1 test failed: test_smtplib 28 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gdb test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_winreg test_winsound test_zipfile64 7 skips unexpected on linux2: test_epoll test_gdb test_ioctl test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly == CPython 2.7b2+ (trunk:81661M, Jun 3 2010, 04:01:39) [GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)] == Linux-2.6.9-gentoo-r1-i686-AMD_Athlon-tm-_XP_3000+-with-gentoo-1.4.16 little-endian == /tmp/test_python_5552 test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_argparse test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 Sleepycat Software: Berkeley DB 4.1.25: (December 19, 2002) Test path prefix: /tmp/z-test_bsddb3-5552 test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler testCompileLibrary still working, be patient... testCompileLibrary still working, be patient... test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_dictcomps test_dictviews test_difflib test_dircache test_dis test_distutils [20673 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdb test_gdb skipped -- gdb versions before 7.0 didn't support python embedding Saw: GNU gdb 6.2.1 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-pc-linux-gnu". test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [16678 refs] [16678 refs] [16678 refs] [26966 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os [16678 refs] [16678 refs] test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- only NT+ and systems with Unicode-friendly filesystem encoding test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [18074 refs] [18074 refs] test_plistlib test_poll test_popen [16683 refs] [16683 refs] [16683 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 [21890 refs] [21890 refs] [21890 refs] [21890 refs] [21890 refs] [21889 refs] [21889 refs] test_pyexpat test_queue test_quopri [19507 refs] [19507 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_setcomps test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [16678 refs] [16678 refs] [16678 refs] [16678 refs] test_slice test_smtplib test test_smtplib failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_smtplib.py", line 235, in testSend smtp.quit() File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 733, in quit res = self.docmd("quit") File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 366, in docmd return self.getreply() File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 343, in getreply raise SMTPServerDisconnected("Connection unexpectedly closed") SMTPServerDisconnected: Connection unexpectedly closed Re-running test 'test_smtplib' in verbose mode testBasic1 (test.test_smtplib.GeneralTests) ... ok testBasic2 (test.test_smtplib.GeneralTests) ... ok testLocalHostName (test.test_smtplib.GeneralTests) ... ok testTimeoutDefault (test.test_smtplib.GeneralTests) ... ok testTimeoutNone (test.test_smtplib.GeneralTests) ... ok testTimeoutValue (test.test_smtplib.GeneralTests) ... ok testBasic (test.test_smtplib.DebuggingServerTests) ... ok testHELP (test.test_smtplib.DebuggingServerTests) ... ERROR testNOOP (test.test_smtplib.DebuggingServerTests) ... ok testNotImplemented (test.test_smtplib.DebuggingServerTests) ... ok testRSET (test.test_smtplib.DebuggingServerTests) ... ok testSecondHELO (test.test_smtplib.DebuggingServerTests) ... ok testSend (test.test_smtplib.DebuggingServerTests) ... ok testVRFY (test.test_smtplib.DebuggingServerTests) ... ok testNonnumericPort (test.test_smtplib.NonConnectingTests) ... ok testNotConnected (test.test_smtplib.NonConnectingTests) ... ok testFailingHELO (test.test_smtplib.BadHELOServerTests) ... ok testAUTH_CRAM_MD5 (test.test_smtplib.SMTPSimTests) ... ok testAUTH_LOGIN (test.test_smtplib.SMTPSimTests) ... ok testAUTH_PLAIN (test.test_smtplib.SMTPSimTests) ... ok testBasic (test.test_smtplib.SMTPSimTests) ... ok testEHLO (test.test_smtplib.SMTPSimTests) ... ok testEXPN (test.test_smtplib.SMTPSimTests) ... ok testVRFY (test.test_smtplib.SMTPSimTests) ... ok ====================================================================== ERROR: testHELP (test.test_smtplib.DebuggingServerTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_smtplib.py", line 222, in testHELP smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 239, in __init__ (code, msg) = self.connect(host, port) File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 296, in connect (code, msg) = self.getreply() File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 343, in getreply raise SMTPServerDisconnected("Connection unexpectedly closed") SMTPServerDisconnected: Connection unexpectedly closed ---------------------------------------------------------------------- Ran 24 tests in 16.683s FAILED (errors=1) test test_smtplib failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_smtplib.py", line 222, in testHELP smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 239, in __init__ (code, msg) = self.connect(host, port) File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 296, in connect (code, msg) = self.getreply() File "/tmp/python-test/local/lib/python2.7/smtplib.py", line 343, in getreply raise SMTPServerDisconnected("Connection unexpectedly closed") SMTPServerDisconnected: Connection unexpectedly closed test_smtpnet test_socket test_socketserver test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_strtod test_struct test_structmembers test_structseq test_subprocess [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16893 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] . [16678 refs] [16678 refs] this bit of output is from a test of stdout in a different process ... [16678 refs] [16678 refs] [16893 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16893 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] . [16678 refs] [16678 refs] this bit of output is from a test of stdout in a different process ... [16678 refs] [16678 refs] [16893 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [16678 refs] [16678 refs] [16678 refs] [16907 refs] [16701 refs] test_sysconfig [16678 refs] [16678 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [16678 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [19978 refs] [22149 refs] [21061 refs] [21061 refs] [21061 refs] [21061 refs] test_threading_local test_threadsignals test_time test_timeout test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllibnet test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid test_wait3 test_wait4 test_warnings [16709 refs] [16709 refs] [16702 refs] [16709 refs] [16709 refs] [16702 refs] test_wave test_weakref test_weakset test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib test_xmlrpc test_xpickle sh: line 1: python2.4: command not found sh: line 1: python2.6: command not found test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 352 tests OK. 1 test failed: test_smtplib 28 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gdb test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_winreg test_winsound test_zipfile64 7 skips unexpected on linux2: test_epoll test_gdb test_ioctl test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly [983760 refs] From python-checkins at python.org Thu Jun 3 14:34:14 2010 From: python-checkins at python.org (lars.gustaebel) Date: Thu, 3 Jun 2010 14:34:14 +0200 (CEST) Subject: [Python-checkins] r81667 - in python/trunk/Lib: tarfile.py test/test_tarfile.py test/testtar.tar Message-ID: <20100603123414.41830EE989@mail.python.org> Author: lars.gustaebel Date: Thu Jun 3 14:34:14 2010 New Revision: 81667 Log: Issue #8741: Fixed the TarFile.makelink() method that is responsible for extracting symbolic and hard link entries as regular files as a work-around on platforms that do not support filesystem links. This stopped working reliably after a change in r74571. I also added a few tests for this functionality. Modified: python/trunk/Lib/tarfile.py python/trunk/Lib/test/test_tarfile.py python/trunk/Lib/test/testtar.tar Modified: python/trunk/Lib/tarfile.py ============================================================================== --- python/trunk/Lib/tarfile.py (original) +++ python/trunk/Lib/tarfile.py Thu Jun 3 14:34:14 2010 @@ -2127,8 +2127,7 @@ raise StreamError("cannot extract (sym)link as file object") else: # A (sym)link's file object is its target's file object. - return self.extractfile(self._getmember(tarinfo.linkname, - tarinfo)) + return self.extractfile(self._find_link_target(tarinfo)) else: # If there's no data associated with the member (directory, chrdev, # blkdev, etc.), return None instead of a file object. @@ -2237,27 +2236,21 @@ (platform limitation), we try to make a copy of the referenced file instead of a link. """ - try: + if hasattr(os, "symlink") and hasattr(os, "link"): + # For systems that support symbolic and hard links. if tarinfo.issym(): os.symlink(tarinfo.linkname, targetpath) else: # See extract(). - os.link(tarinfo._link_target, targetpath) - except AttributeError: - if tarinfo.issym(): - linkpath = os.path.dirname(tarinfo.name) + "/" + \ - tarinfo.linkname - else: - linkpath = tarinfo.linkname - + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), targetpath) + else: try: - self._extract_member(self.getmember(linkpath), targetpath) - except (EnvironmentError, KeyError), e: - linkpath = linkpath.replace("/", os.sep) - try: - shutil.copy2(linkpath, targetpath) - except EnvironmentError, e: - raise IOError("link could not be created") + self._extract_member(self._find_link_target(tarinfo), targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") def chown(self, tarinfo, targetpath): """Set owner of targetpath according to tarinfo. @@ -2356,21 +2349,28 @@ #-------------------------------------------------------------------------- # Little helper methods: - def _getmember(self, name, tarinfo=None): + def _getmember(self, name, tarinfo=None, normalize=False): """Find an archive member by name from bottom to top. If tarinfo is given, it is used as the starting point. """ # Ensure that all members have been loaded. members = self.getmembers() - if tarinfo is None: - end = len(members) - else: - end = members.index(tarinfo) + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] - for i in xrange(end - 1, -1, -1): - if name == members[i].name: - return members[i] + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member def _load(self): """Read through the entire archive file and look for readable @@ -2391,6 +2391,25 @@ if mode is not None and self.mode not in mode: raise IOError("bad operation for mode %r" % self.mode) + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + def __iter__(self): """Provide an iterator object. """ Modified: python/trunk/Lib/test/test_tarfile.py ============================================================================== --- python/trunk/Lib/test/test_tarfile.py (original) +++ python/trunk/Lib/test/test_tarfile.py Thu Jun 3 14:34:14 2010 @@ -134,6 +134,26 @@ "read() after readline() failed") fobj.close() + # Test if symbolic and hard links are resolved by extractfile(). The + # test link members each point to a regular member whose data is + # supposed to be exported. + def _test_fileobj_link(self, lnktype, regtype): + a = self.tar.extractfile(lnktype) + b = self.tar.extractfile(regtype) + self.assertEqual(a.name, b.name) + + def test_fileobj_link1(self): + self._test_fileobj_link("ustar/lnktype", "ustar/regtype") + + def test_fileobj_link2(self): + self._test_fileobj_link("./ustar/linktest2/lnktype", "ustar/linktest1/regtype") + + def test_fileobj_symlink1(self): + self._test_fileobj_link("ustar/symtype", "ustar/regtype") + + def test_fileobj_symlink2(self): + self._test_fileobj_link("./ustar/linktest2/symtype", "ustar/linktest1/regtype") + class CommonReadTest(ReadTest): @@ -1376,6 +1396,29 @@ fobj.close() +class LinkEmulationTest(ReadTest): + + # Test for issue #8741 regression. On platforms that do not support + # symbolic or hard links tarfile tries to extract these types of members as + # the regular files they point to. + def _test_link_extraction(self, name): + self.tar.extract(name, TEMPDIR) + data = open(os.path.join(TEMPDIR, name), "rb").read() + self.assertEqual(md5sum(data), md5_regtype) + + def test_hardlink_extraction1(self): + self._test_link_extraction("ustar/lnktype") + + def test_hardlink_extraction2(self): + self._test_link_extraction("./ustar/linktest2/lnktype") + + def test_symlink_extraction1(self): + self._test_link_extraction("ustar/symtype") + + def test_symlink_extraction2(self): + self._test_link_extraction("./ustar/linktest2/symtype") + + class GzipMiscReadTest(MiscReadTest): tarname = gzipname mode = "r:gz" @@ -1460,6 +1503,8 @@ if hasattr(os, "link"): tests.append(HardlinkTest) + else: + tests.append(LinkEmulationTest) fobj = open(tarname, "rb") data = fobj.read() Modified: python/trunk/Lib/test/testtar.tar ============================================================================== Binary files. No diff available. From python-checkins at python.org Thu Jun 3 14:38:15 2010 From: python-checkins at python.org (lars.gustaebel) Date: Thu, 3 Jun 2010 14:38:15 +0200 (CEST) Subject: [Python-checkins] r81668 - python/branches/release26-maint Message-ID: <20100603123815.AE7E3EE989@mail.python.org> Author: lars.gustaebel Date: Thu Jun 3 14:38:15 2010 New Revision: 81668 Log: Blocked revisions 81667 via svnmerge ........ r81667 | lars.gustaebel | 2010-06-03 14:34:14 +0200 (Thu, 03 Jun 2010) | 8 lines Issue #8741: Fixed the TarFile.makelink() method that is responsible for extracting symbolic and hard link entries as regular files as a work-around on platforms that do not support filesystem links. This stopped working reliably after a change in r74571. I also added a few tests for this functionality. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Jun 3 14:39:50 2010 From: python-checkins at python.org (stefan.krah) Date: Thu, 3 Jun 2010 14:39:50 +0200 (CEST) Subject: [Python-checkins] r81669 - in python/trunk: Lib/test/test_curses.py Misc/NEWS setup.py Message-ID: <20100603123950.BACCCEE9B1@mail.python.org> Author: stefan.krah Date: Thu Jun 3 14:39:50 2010 New Revision: 81669 Log: Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. Thanks Thomas Dickey for answering questions about ncurses/ncursesw and readline! Modified: python/trunk/Lib/test/test_curses.py python/trunk/Misc/NEWS python/trunk/setup.py Modified: python/trunk/Lib/test/test_curses.py ============================================================================== --- python/trunk/Lib/test/test_curses.py (original) +++ python/trunk/Lib/test/test_curses.py Thu Jun 3 14:39:50 2010 @@ -21,11 +21,6 @@ curses = import_module('curses') curses.panel = import_module('curses.panel') -# skip all these tests on FreeBSD: test_curses currently hangs the -# FreeBSD buildbots, preventing other tests from running. See issue -# #7384. -if 'freebsd' in sys.platform: - raise unittest.SkipTest('The curses module is broken on FreeBSD. See http://bugs.python.org/issue7384.') # XXX: if newterm was supported we could use it instead of initscr and not exit term = os.environ.get('TERM') Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Jun 3 14:39:50 2010 @@ -89,6 +89,10 @@ Extension Modules ----------------- +- Issue #7384: If the system readline library is linked against ncurses, + the curses module must be linked against ncurses as well. Otherwise it + is not safe to load both the readline and curses modules in an application. + - Issue #2810: Fix cases where the Windows registry API returns ERROR_MORE_DATA, requiring a re-try in order to get the complete result. Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Thu Jun 3 14:39:50 2010 @@ -588,6 +588,32 @@ # readline do_readline = self.compiler.find_library_file(lib_dirs, 'readline') + readline_termcap_library = "" + curses_library = "" + # Determine if readline is already linked against curses or tinfo. + if do_readline and platform != 'darwin': # OS X does not have ldd. + fp = os.popen("ldd %s" % do_readline) + for ln in fp: + if 'curses' in ln: + readline_termcap_library = re.sub( + r'.*lib(n?cursesw?)\.so.*', r'\1', ln + ).rstrip() + break + if 'tinfo' in ln: # termcap interface split out from ncurses + readline_termcap_library = 'tinfo' + break + fp.close() + # Issue 7384: If readline is already linked against curses, + # use the same library for the readline and curses modules. + if 'curses' in readline_termcap_library: + curses_library = readline_termcap_library + elif self.compiler_obj.find_library_file(lib_dirs, 'ncursesw'): + curses_library = 'ncursesw' + elif self.compiler_obj.find_library_file(lib_dirs, 'ncurses'): + curses_library = 'ncurses' + elif self.compiler_obj.find_library_file(lib_dirs, 'curses'): + curses_library = 'curses' + if platform == 'darwin': os_release = int(os.uname()[2].split('.')[0]) dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') @@ -611,14 +637,10 @@ readline_extra_link_args = () readline_libs = ['readline'] - if self.compiler.find_library_file(lib_dirs, - 'ncursesw'): - readline_libs.append('ncursesw') - elif self.compiler.find_library_file(lib_dirs, - 'ncurses'): - readline_libs.append('ncurses') - elif self.compiler.find_library_file(lib_dirs, 'curses'): - readline_libs.append('curses') + if readline_termcap_library: + pass # Issue 7384: Already linked against curses or tinfo. + elif curses_library: + readline_libs.append(curses_library) elif self.compiler.find_library_file(lib_dirs + ['/usr/lib/termcap'], 'termcap'): @@ -1187,19 +1209,15 @@ # Curses support, requiring the System V version of curses, often # provided by the ncurses library. panel_library = 'panel' - if (self.compiler.find_library_file(lib_dirs, 'ncursesw')): - curses_libs = ['ncursesw'] - # Bug 1464056: If _curses.so links with ncursesw, - # _curses_panel.so must link with panelw. - panel_library = 'panelw' - exts.append( Extension('_curses', ['_cursesmodule.c'], - libraries = curses_libs) ) - elif (self.compiler.find_library_file(lib_dirs, 'ncurses')): - curses_libs = ['ncurses'] + if curses_library.startswith('ncurses'): + if curses_library == 'ncursesw': + # Bug 1464056: If _curses.so links with ncursesw, + # _curses_panel.so must link with panelw. + panel_library = 'panelw' + curses_libs = [curses_library] exts.append( Extension('_curses', ['_cursesmodule.c'], libraries = curses_libs) ) - elif (self.compiler.find_library_file(lib_dirs, 'curses') - and platform != 'darwin'): + elif curses_library == 'curses' and platform != 'darwin': # OSX has an old Berkeley curses, not good enough for # the _curses module. if (self.compiler.find_library_file(lib_dirs, 'terminfo')): From python-checkins at python.org Thu Jun 3 14:45:17 2010 From: python-checkins at python.org (lars.gustaebel) Date: Thu, 3 Jun 2010 14:45:17 +0200 (CEST) Subject: [Python-checkins] r81670 - in python/branches/py3k: Lib/tarfile.py Lib/test/test_tarfile.py Lib/test/testtar.tar Message-ID: <20100603124517.281EBEEA02@mail.python.org> Author: lars.gustaebel Date: Thu Jun 3 14:45:16 2010 New Revision: 81670 Log: Merged revisions 81667 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81667 | lars.gustaebel | 2010-06-03 14:34:14 +0200 (Thu, 03 Jun 2010) | 8 lines Issue #8741: Fixed the TarFile.makelink() method that is responsible for extracting symbolic and hard link entries as regular files as a work-around on platforms that do not support filesystem links. This stopped working reliably after a change in r74571. I also added a few tests for this functionality. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/tarfile.py python/branches/py3k/Lib/test/test_tarfile.py python/branches/py3k/Lib/test/testtar.tar Modified: python/branches/py3k/Lib/tarfile.py ============================================================================== --- python/branches/py3k/Lib/tarfile.py (original) +++ python/branches/py3k/Lib/tarfile.py Thu Jun 3 14:45:16 2010 @@ -2163,8 +2163,7 @@ raise StreamError("cannot extract (sym)link as file object") else: # A (sym)link's file object is its target's file object. - return self.extractfile(self._getmember(tarinfo.linkname, - tarinfo)) + return self.extractfile(self._find_link_target(tarinfo)) else: # If there's no data associated with the member (directory, chrdev, # blkdev, etc.), return None instead of a file object. @@ -2273,27 +2272,21 @@ (platform limitation), we try to make a copy of the referenced file instead of a link. """ - try: + if hasattr(os, "symlink") and hasattr(os, "link"): + # For systems that support symbolic and hard links. if tarinfo.issym(): os.symlink(tarinfo.linkname, targetpath) else: # See extract(). - os.link(tarinfo._link_target, targetpath) - except AttributeError: - if tarinfo.issym(): - linkpath = os.path.dirname(tarinfo.name) + "/" + \ - tarinfo.linkname - else: - linkpath = tarinfo.linkname - + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), targetpath) + else: try: - self._extract_member(self.getmember(linkpath), targetpath) - except (EnvironmentError, KeyError) as e: - linkpath = linkpath.replace("/", os.sep) - try: - shutil.copy2(linkpath, targetpath) - except EnvironmentError as e: - raise IOError("link could not be created") + self._extract_member(self._find_link_target(tarinfo), targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") def chown(self, tarinfo, targetpath): """Set owner of targetpath according to tarinfo. @@ -2392,21 +2385,28 @@ #-------------------------------------------------------------------------- # Little helper methods: - def _getmember(self, name, tarinfo=None): + def _getmember(self, name, tarinfo=None, normalize=False): """Find an archive member by name from bottom to top. If tarinfo is given, it is used as the starting point. """ # Ensure that all members have been loaded. members = self.getmembers() - if tarinfo is None: - end = len(members) - else: - end = members.index(tarinfo) + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] - for i in range(end - 1, -1, -1): - if name == members[i].name: - return members[i] + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member def _load(self): """Read through the entire archive file and look for readable @@ -2427,6 +2427,25 @@ if mode is not None and self.mode not in mode: raise IOError("bad operation for mode %r" % self.mode) + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + def __iter__(self): """Provide an iterator object. """ Modified: python/branches/py3k/Lib/test/test_tarfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_tarfile.py (original) +++ python/branches/py3k/Lib/test/test_tarfile.py Thu Jun 3 14:45:16 2010 @@ -133,6 +133,26 @@ "read() after readline() failed") fobj.close() + # Test if symbolic and hard links are resolved by extractfile(). The + # test link members each point to a regular member whose data is + # supposed to be exported. + def _test_fileobj_link(self, lnktype, regtype): + a = self.tar.extractfile(lnktype) + b = self.tar.extractfile(regtype) + self.assertEqual(a.name, b.name) + + def test_fileobj_link1(self): + self._test_fileobj_link("ustar/lnktype", "ustar/regtype") + + def test_fileobj_link2(self): + self._test_fileobj_link("./ustar/linktest2/lnktype", "ustar/linktest1/regtype") + + def test_fileobj_symlink1(self): + self._test_fileobj_link("ustar/symtype", "ustar/regtype") + + def test_fileobj_symlink2(self): + self._test_fileobj_link("./ustar/linktest2/symtype", "ustar/linktest1/regtype") + class CommonReadTest(ReadTest): @@ -1378,6 +1398,29 @@ fobj.close() +class LinkEmulationTest(ReadTest): + + # Test for issue #8741 regression. On platforms that do not support + # symbolic or hard links tarfile tries to extract these types of members as + # the regular files they point to. + def _test_link_extraction(self, name): + self.tar.extract(name, TEMPDIR) + data = open(os.path.join(TEMPDIR, name), "rb").read() + self.assertEqual(md5sum(data), md5_regtype) + + def test_hardlink_extraction1(self): + self._test_link_extraction("ustar/lnktype") + + def test_hardlink_extraction2(self): + self._test_link_extraction("./ustar/linktest2/lnktype") + + def test_symlink_extraction1(self): + self._test_link_extraction("ustar/symtype") + + def test_symlink_extraction2(self): + self._test_link_extraction("./ustar/linktest2/symtype") + + class GzipMiscReadTest(MiscReadTest): tarname = gzipname mode = "r:gz" @@ -1463,6 +1506,8 @@ if hasattr(os, "link"): tests.append(HardlinkTest) + else: + tests.append(LinkEmulationTest) fobj = open(tarname, "rb") data = fobj.read() Modified: python/branches/py3k/Lib/test/testtar.tar ============================================================================== Binary files. No diff available. From python-checkins at python.org Thu Jun 3 14:46:14 2010 From: python-checkins at python.org (lars.gustaebel) Date: Thu, 3 Jun 2010 14:46:14 +0200 (CEST) Subject: [Python-checkins] r81671 - python/branches/release31-maint Message-ID: <20100603124614.D7320EEB3A@mail.python.org> Author: lars.gustaebel Date: Thu Jun 3 14:46:14 2010 New Revision: 81671 Log: Blocked revisions 81670 via svnmerge ................ r81670 | lars.gustaebel | 2010-06-03 14:45:16 +0200 (Thu, 03 Jun 2010) | 14 lines Merged revisions 81667 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81667 | lars.gustaebel | 2010-06-03 14:34:14 +0200 (Thu, 03 Jun 2010) | 8 lines Issue #8741: Fixed the TarFile.makelink() method that is responsible for extracting symbolic and hard link entries as regular files as a work-around on platforms that do not support filesystem links. This stopped working reliably after a change in r74571. I also added a few tests for this functionality. ........ ................ Modified: python/branches/release31-maint/ (props changed) From fuzzyman at voidspace.org.uk Thu Jun 3 16:03:13 2010 From: fuzzyman at voidspace.org.uk (Michael Foord) Date: Thu, 3 Jun 2010 15:03:13 +0100 Subject: [Python-checkins] r81669 - in python/trunk: Lib/test/test_curses.py Misc/NEWS setup.py In-Reply-To: <20100603123950.BACCCEE9B1@mail.python.org> References: <20100603123950.BACCCEE9B1@mail.python.org> Message-ID: This kills the build on Mac OS X (Snow Leopard) for me: Traceback (most recent call last): File "./setup.py", line 2040, in main() File "./setup.py", line 2035, in main 'Lib/smtpd.py'] File "/compile/python-trunk/Lib/distutils/core.py", line 152, in setup dist.run_commands() File "/compile/python-trunk/Lib/distutils/dist.py", line 953, in run_commands self.run_command(cmd) File "/compile/python-trunk/Lib/distutils/dist.py", line 972, in run_command cmd_obj.run() File "/compile/python-trunk/Lib/distutils/command/build.py", line 127, in run self.run_command(cmd_name) File "/compile/python-trunk/Lib/distutils/cmd.py", line 326, in run_command self.distribution.run_command(command) File "/compile/python-trunk/Lib/distutils/dist.py", line 972, in run_command cmd_obj.run() File "/compile/python-trunk/Lib/distutils/command/build_ext.py", line 340, in run self.build_extensions() File "./setup.py", line 151, in build_extensions missing = self.detect_modules() File "./setup.py", line 610, in detect_modules elif self.compiler_obj.find_library_file(lib_dirs, 'ncursesw'): File "/compile/python-trunk/Lib/distutils/cmd.py", line 105, in __getattr__ raise AttributeError, attr AttributeError: compiler_obj [35980 refs] make: *** [sharedmods] Error 1 On 3 June 2010 13:39, stefan.krah wrote: > Author: stefan.krah > Date: Thu Jun 3 14:39:50 2010 > New Revision: 81669 > > Log: > Issue #7384: If the system readline library is linked against ncurses, > the curses module must be linked against ncurses as well. Otherwise it > is not safe to load both the readline and curses modules in an application. > > Thanks Thomas Dickey for answering questions about ncurses/ncursesw > and readline! > > > > > Modified: > python/trunk/Lib/test/test_curses.py > python/trunk/Misc/NEWS > python/trunk/setup.py > > Modified: python/trunk/Lib/test/test_curses.py > > ============================================================================== > --- python/trunk/Lib/test/test_curses.py (original) > +++ python/trunk/Lib/test/test_curses.py Thu Jun 3 14:39:50 2010 > @@ -21,11 +21,6 @@ > curses = import_module('curses') > curses.panel = import_module('curses.panel') > > -# skip all these tests on FreeBSD: test_curses currently hangs the > -# FreeBSD buildbots, preventing other tests from running. See issue > -# #7384. > -if 'freebsd' in sys.platform: > - raise unittest.SkipTest('The curses module is broken on FreeBSD. See > http://bugs.python.org/issue7384.') > > # XXX: if newterm was supported we could use it instead of initscr and not > exit > term = os.environ.get('TERM') > > Modified: python/trunk/Misc/NEWS > > ============================================================================== > --- python/trunk/Misc/NEWS (original) > +++ python/trunk/Misc/NEWS Thu Jun 3 14:39:50 2010 > @@ -89,6 +89,10 @@ > Extension Modules > ----------------- > > +- Issue #7384: If the system readline library is linked against ncurses, > + the curses module must be linked against ncurses as well. Otherwise it > + is not safe to load both the readline and curses modules in an > application. > + > - Issue #2810: Fix cases where the Windows registry API returns > ERROR_MORE_DATA, requiring a re-try in order to get the complete result. > > > Modified: python/trunk/setup.py > > ============================================================================== > --- python/trunk/setup.py (original) > +++ python/trunk/setup.py Thu Jun 3 14:39:50 2010 > @@ -588,6 +588,32 @@ > > # readline > do_readline = self.compiler.find_library_file(lib_dirs, 'readline') > + readline_termcap_library = "" > + curses_library = "" > + # Determine if readline is already linked against curses or tinfo. > + if do_readline and platform != 'darwin': # OS X does not have ldd. > + fp = os.popen("ldd %s" % do_readline) > + for ln in fp: > + if 'curses' in ln: > + readline_termcap_library = re.sub( > + r'.*lib(n?cursesw?)\.so.*', r'\1', ln > + ).rstrip() > + break > + if 'tinfo' in ln: # termcap interface split out from > ncurses > + readline_termcap_library = 'tinfo' > + break > + fp.close() > + # Issue 7384: If readline is already linked against curses, > + # use the same library for the readline and curses modules. > + if 'curses' in readline_termcap_library: > + curses_library = readline_termcap_library > + elif self.compiler_obj.find_library_file(lib_dirs, 'ncursesw'): > + curses_library = 'ncursesw' > + elif self.compiler_obj.find_library_file(lib_dirs, 'ncurses'): > + curses_library = 'ncurses' > + elif self.compiler_obj.find_library_file(lib_dirs, 'curses'): > + curses_library = 'curses' > + > if platform == 'darwin': > os_release = int(os.uname()[2].split('.')[0]) > dep_target = > sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') > @@ -611,14 +637,10 @@ > readline_extra_link_args = () > > readline_libs = ['readline'] > - if self.compiler.find_library_file(lib_dirs, > - 'ncursesw'): > - readline_libs.append('ncursesw') > - elif self.compiler.find_library_file(lib_dirs, > - 'ncurses'): > - readline_libs.append('ncurses') > - elif self.compiler.find_library_file(lib_dirs, 'curses'): > - readline_libs.append('curses') > + if readline_termcap_library: > + pass # Issue 7384: Already linked against curses or tinfo. > + elif curses_library: > + readline_libs.append(curses_library) > elif self.compiler.find_library_file(lib_dirs + > ['/usr/lib/termcap'], > 'termcap'): > @@ -1187,19 +1209,15 @@ > # Curses support, requiring the System V version of curses, often > # provided by the ncurses library. > panel_library = 'panel' > - if (self.compiler.find_library_file(lib_dirs, 'ncursesw')): > - curses_libs = ['ncursesw'] > - # Bug 1464056: If _curses.so links with ncursesw, > - # _curses_panel.so must link with panelw. > - panel_library = 'panelw' > - exts.append( Extension('_curses', ['_cursesmodule.c'], > - libraries = curses_libs) ) > - elif (self.compiler.find_library_file(lib_dirs, 'ncurses')): > - curses_libs = ['ncurses'] > + if curses_library.startswith('ncurses'): > + if curses_library == 'ncursesw': > + # Bug 1464056: If _curses.so links with ncursesw, > + # _curses_panel.so must link with panelw. > + panel_library = 'panelw' > + curses_libs = [curses_library] > exts.append( Extension('_curses', ['_cursesmodule.c'], > libraries = curses_libs) ) > - elif (self.compiler.find_library_file(lib_dirs, 'curses') > - and platform != 'darwin'): > + elif curses_library == 'curses' and platform != 'darwin': > # OSX has an old Berkeley curses, not good enough for > # the _curses module. > if (self.compiler.find_library_file(lib_dirs, 'terminfo')): > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > -- http://www.voidspace.org.uk -------------- next part -------------- An HTML attachment was scrubbed... URL: From python-checkins at python.org Thu Jun 3 16:25:16 2010 From: python-checkins at python.org (stefan.krah) Date: Thu, 3 Jun 2010 16:25:16 +0200 (CEST) Subject: [Python-checkins] r81672 - python/trunk/setup.py Message-ID: <20100603142516.A809DEE9A4@mail.python.org> Author: stefan.krah Date: Thu Jun 3 16:25:16 2010 New Revision: 81672 Log: Use compiler rather than compiler_obj. Thanks Michael Foord for noticing. Modified: python/trunk/setup.py Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Thu Jun 3 16:25:16 2010 @@ -607,11 +607,11 @@ # use the same library for the readline and curses modules. if 'curses' in readline_termcap_library: curses_library = readline_termcap_library - elif self.compiler_obj.find_library_file(lib_dirs, 'ncursesw'): + elif self.compiler.find_library_file(lib_dirs, 'ncursesw'): curses_library = 'ncursesw' - elif self.compiler_obj.find_library_file(lib_dirs, 'ncurses'): + elif self.compiler.find_library_file(lib_dirs, 'ncurses'): curses_library = 'ncurses' - elif self.compiler_obj.find_library_file(lib_dirs, 'curses'): + elif self.compiler.find_library_file(lib_dirs, 'curses'): curses_library = 'curses' if platform == 'darwin': From stefan-usenet at bytereef.org Thu Jun 3 16:20:24 2010 From: stefan-usenet at bytereef.org (Stefan Krah) Date: Thu, 3 Jun 2010 16:20:24 +0200 Subject: [Python-checkins] r81669 - in python/trunk: Lib/test/test_curses.py Misc/NEWS setup.py In-Reply-To: References: <20100603123950.BACCCEE9B1@mail.python.org> Message-ID: <20100603142024.GA2775@yoda.bytereef.org> Michael Foord wrote: > This kills the build on Mac OS X (Snow Leopard) for me: > elif self.compiler_obj.find_library_file(lib_dirs, 'ncursesw'): > File "/compile/python-trunk/Lib/distutils/cmd.py", line 105, in __getattr__ > raise AttributeError, attr > AttributeError: compiler_obj > [35980 refs] > make: *** [sharedmods] Error 1 Thanks, the compiler_obj slipped in from the py3k patch. Stefan Krah From python-checkins at python.org Thu Jun 3 16:42:25 2010 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 3 Jun 2010 16:42:25 +0200 (CEST) Subject: [Python-checkins] r81673 - in python/branches/py3k: Lib/distutils/unixccompiler.py setup.py Message-ID: <20100603144225.3EBA9EE9E4@mail.python.org> Author: ronald.oussoren Date: Thu Jun 3 16:42:25 2010 New Revision: 81673 Log: Merged revisions 81662 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81662 | ronald.oussoren | 2010-06-03 11:47:21 +0200 (Thu, 03 Jun 2010) | 9 lines Fix for issue #7724: ensure that distutils and python's own setup.py honor the MacOSX SDK when one is specified. This is needed to be able to build using the 10.4u SDK while running on OSX 10.6. This is a fixed version of the patch in r80963, I've tested this patch on OSX and Linux. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/unixccompiler.py python/branches/py3k/setup.py Modified: python/branches/py3k/Lib/distutils/unixccompiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/unixccompiler.py (original) +++ python/branches/py3k/Lib/distutils/unixccompiler.py Thu Jun 3 16:42:25 2010 @@ -15,7 +15,7 @@ __revision__ = "$Id$" -import os, sys +import os, sys, re from distutils.dep_util import newer from distutils.ccompiler import \ @@ -320,10 +320,31 @@ dylib_f = self.library_filename(lib, lib_type='dylib') static_f = self.library_filename(lib, lib_type='static') + if sys.platform == 'darwin': + # On OSX users can specify an alternate SDK using + # '-isysroot', calculate the SDK root if it is specified + # (and use it further on) + _sysconfig = __import__('sysconfig') + cflags = _sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + + + for dir in dirs: shared = os.path.join(dir, shared_f) dylib = os.path.join(dir, dylib_f) static = os.path.join(dir, static_f) + + if sys.platform == 'darwin' and ( + dir.startswith('/System/') or dir.startswith('/usr/')): + shared = os.path.join(sysroot, dir[1:], shared_f) + dylib = os.path.join(sysroot, dir[1:], dylib_f) + static = os.path.join(sysroot, dir[1:], static_f) + # We're second-guessing the linker here, with not much hard # data to go on: GCC seems to prefer the shared library, so I'm # assuming that *all* Unix C compilers do. And of course I'm Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Thu Jun 3 16:42:25 2010 @@ -28,6 +28,25 @@ if dir is not None and os.path.isdir(dir) and dir not in dirlist: dirlist.insert(0, dir) +def macosx_sdk_root(): + """ + Return the directory of the current OSX SDK, + or '/' if no SDK was specified. + """ + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + return sysroot + +def is_macosx_sdk_path(path): + """ + Returns True if 'path' can be located in an OSX SDK + """ + return path.startswith('/usr/') or path.startswith('/System/') + def find_file(filename, std_dirs, paths): """Searches for the directory where a given file is located, and returns a possibly-empty list of additional directories, or None @@ -39,15 +58,28 @@ 'paths' is a list of additional locations to check; if the file is found in one of them, the resulting list will contain the directory. """ + if sys.platform == 'darwin': + # Honor the MacOSX SDK setting when one was specified. + # An SDK is a directory with the same structure as a real + # system, but with only header files and libraries. + sysroot = macosx_sdk_root() # Check the standard locations for dir in std_dirs: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [] # Check the additional directories for dir in paths: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [dir] @@ -59,11 +91,19 @@ if result is None: return None + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + # Check whether the found file is in one of the standard directories dirname = os.path.dirname(result) for p in std_dirs: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ ] + if p == dirname: return [ ] @@ -72,6 +112,11 @@ for p in paths: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ p ] + if p == dirname: return [p] else: @@ -497,7 +542,7 @@ # library and then a static library, instead of first looking # for dynamic libraries on the entire path. # This way a staticly linked custom readline gets picked up - # before the (broken) dynamic library in /usr/lib. + # before the (possibly broken) dynamic library in /usr/lib. readline_extra_link_args = ('-Wl,-search_paths_first',) else: readline_extra_link_args = () @@ -571,22 +616,23 @@ openssl_ver = 0 openssl_ver_re = re.compile( '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' ) - for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in: - name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h') - if os.path.isfile(name): - try: - incfile = open(name, 'r') - for line in incfile: - m = openssl_ver_re.match(line) - if m: - openssl_ver = eval(m.group(1)) - break - except IOError: - pass - # first version found is what we'll use (as the compiler should) - if openssl_ver: - break + # look for the openssl version header on the compiler search path. + opensslv_h = find_file('openssl/opensslv.h', [], + inc_dirs + search_for_ssl_incs_in) + if opensslv_h: + name = os.path.join(opensslv_h[0], 'openssl/opensslv.h') + if sys.platform == 'darwin' and is_macosx_sdk_path(name): + name = os.path.join(macosx_sdk_root(), name[1:]) + try: + incfile = open(name, 'r') + for line in incfile: + m = openssl_ver_re.match(line) + if m: + openssl_ver = eval(m.group(1)) + except IOError as msg: + print("IOError while reading opensshv.h:", msg) + pass #print('openssl_ver = 0x%08x' % openssl_ver) min_openssl_ver = 0x00907000 @@ -715,12 +761,18 @@ db_ver_inc_map = {} + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + class db_found(Exception): pass try: # See whether there is a Sleepycat header in the standard # search path. for d in inc_dirs + db_inc_paths: f = os.path.join(d, "db.h") + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "db.h") + if db_setup_debug: print("db: looking for db.h in", f) if os.path.exists(f): f = open(f, "rb").read() @@ -767,7 +819,22 @@ db_incdir.replace("include", 'lib64'), db_incdir.replace("include", 'lib'), ] - db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + if sys.platform != 'darwin': + db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + else: + # Same as other branch, but takes OSX SDK into account + tmp = [] + for dn in db_dirs_to_check: + if is_macosx_sdk_path(dn): + if os.path.isdir(os.path.join(sysroot, dn[1:])): + tmp.append(dn) + else: + if os.path.isdir(dn): + tmp.append(dn) + + db_dirs_to_check = tmp # Look for a version specific db-X.Y before an ambiguoius dbX # XXX should we -ever- look for a dbX name? Do any @@ -816,8 +883,15 @@ # Scan the default include directories before the SQLite specific # ones. This allows one to override the copy of sqlite on OSX, # where /usr/include contains an old version of sqlite. + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + for d in inc_dirs + sqlite_inc_paths: f = os.path.join(d, "sqlite3.h") + + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "sqlite3.h") + if os.path.exists(f): if sqlite_setup_debug: print("sqlite: found %s"%f) incf = open(f).read() @@ -1253,14 +1327,22 @@ join(os.getenv('HOME'), '/Library/Frameworks') ] + sysroot = macosx_sdk_root() + # Find the directory that contains the Tcl.framework and Tk.framework # bundles. # XXX distutils should support -F! for F in framework_dirs: # both Tcl.framework and Tk.framework should be present + + for fw in 'Tcl', 'Tk': - if not exists(join(F, fw + '.framework')): - break + if is_macosx_sdk_path(F): + if not exists(join(sysroot, F[1:], fw + '.framework')): + break + else: + if not exists(join(F, fw + '.framework')): + break else: # ok, F is now directory with both frameworks. Continure # building @@ -1297,8 +1379,12 @@ # Note: cannot use os.popen or subprocess here, that # requires extensions that are not available here. - os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) + if is_macosx_sdk_path(F): + os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(os.path.join(sysroot, F[1:]), tmpfile)) + else: + os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) fp = open(tmpfile) + detected_archs = [] for ln in fp: a = ln.split()[-1] From python-checkins at python.org Thu Jun 3 16:59:56 2010 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 3 Jun 2010 16:59:56 +0200 (CEST) Subject: [Python-checkins] r81674 - in python/branches/release26-maint: Lib/distutils/unixccompiler.py setup.py Message-ID: <20100603145956.6FC1BEEA2E@mail.python.org> Author: ronald.oussoren Date: Thu Jun 3 16:59:56 2010 New Revision: 81674 Log: Merged revisions 81662 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81662 | ronald.oussoren | 2010-06-03 11:47:21 +0200 (Thu, 03 Jun 2010) | 9 lines Fix for issue #7724: ensure that distutils and python's own setup.py honor the MacOSX SDK when one is specified. This is needed to be able to build using the 10.4u SDK while running on OSX 10.6. This is a fixed version of the patch in r80963, I've tested this patch on OSX and Linux. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/unixccompiler.py python/branches/release26-maint/setup.py Modified: python/branches/release26-maint/Lib/distutils/unixccompiler.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/unixccompiler.py (original) +++ python/branches/release26-maint/Lib/distutils/unixccompiler.py Thu Jun 3 16:59:56 2010 @@ -15,7 +15,7 @@ __revision__ = "$Id$" -import os, sys +import os, sys, re from types import StringType, NoneType from distutils import sysconfig @@ -305,10 +305,30 @@ dylib_f = self.library_filename(lib, lib_type='dylib') static_f = self.library_filename(lib, lib_type='static') + if sys.platform == 'darwin': + # On OSX users can specify an alternate SDK using + # '-isysroot', calculate the SDK root if it is specified + # (and use it further on) + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + + + for dir in dirs: shared = os.path.join(dir, shared_f) dylib = os.path.join(dir, dylib_f) static = os.path.join(dir, static_f) + + if sys.platform == 'darwin' and ( + dir.startswith('/System/') or dir.startswith('/usr/')): + shared = os.path.join(sysroot, dir[1:], shared_f) + dylib = os.path.join(sysroot, dir[1:], dylib_f) + static = os.path.join(sysroot, dir[1:], static_f) + # We're second-guessing the linker here, with not much hard # data to go on: GCC seems to prefer the shared library, so I'm # assuming that *all* Unix C compilers do. And of course I'm Modified: python/branches/release26-maint/setup.py ============================================================================== --- python/branches/release26-maint/setup.py (original) +++ python/branches/release26-maint/setup.py Thu Jun 3 16:59:56 2010 @@ -26,6 +26,25 @@ if dir is not None and os.path.isdir(dir) and dir not in dirlist: dirlist.insert(0, dir) +def macosx_sdk_root(): + """ + Return the directory of the current OSX SDK, + or '/' if no SDK was specified. + """ + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + return sysroot + +def is_macosx_sdk_path(path): + """ + Returns True if 'path' can be located in an OSX SDK + """ + return path.startswith('/usr/') or path.startswith('/System/') + def find_file(filename, std_dirs, paths): """Searches for the directory where a given file is located, and returns a possibly-empty list of additional directories, or None @@ -37,15 +56,28 @@ 'paths' is a list of additional locations to check; if the file is found in one of them, the resulting list will contain the directory. """ + if sys.platform == 'darwin': + # Honor the MacOSX SDK setting when one was specified. + # An SDK is a directory with the same structure as a real + # system, but with only header files and libraries. + sysroot = macosx_sdk_root() # Check the standard locations for dir in std_dirs: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [] # Check the additional directories for dir in paths: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [dir] @@ -57,11 +89,19 @@ if result is None: return None + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + # Check whether the found file is in one of the standard directories dirname = os.path.dirname(result) for p in std_dirs: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ ] + if p == dirname: return [ ] @@ -70,6 +110,11 @@ for p in paths: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ p ] + if p == dirname: return [p] else: @@ -573,7 +618,7 @@ # library and then a static library, instead of first looking # for dynamic libraries on the entiry path. # This way a staticly linked custom readline gets picked up - # before the (broken) dynamic library in /usr/lib. + # before the (possibly broken) dynamic library in /usr/lib. readline_extra_link_args = ('-Wl,-search_paths_first',) else: readline_extra_link_args = () @@ -647,24 +692,24 @@ openssl_ver = 0 openssl_ver_re = re.compile( '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' ) - for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in: - name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h') - if os.path.isfile(name): - try: - incfile = open(name, 'r') - for line in incfile: - m = openssl_ver_re.match(line) - if m: - openssl_ver = eval(m.group(1)) - break - except IOError: - pass - # first version found is what we'll use (as the compiler should) - if openssl_ver: - break + # look for the openssl version header on the compiler search path. + opensslv_h = find_file('openssl/opensslv.h', [], + inc_dirs + search_for_ssl_incs_in) + if opensslv_h: + name = os.path.join(opensslv_h[0], 'openssl/opensslv.h') + if sys.platform == 'darwin' and is_macosx_sdk_path(name): + name = os.path.join(macosx_sdk_root(), name[1:]) + try: + incfile = open(name, 'r') + for line in incfile: + m = openssl_ver_re.match(line) + if m: + openssl_ver = eval(m.group(1)) + except IOError, msg: + print "IOError while reading opensshv.h:", msg + pass - #print 'openssl_ver = 0x%08x' % openssl_ver if (ssl_incs is not None and ssl_libs is not None and @@ -792,12 +837,19 @@ db_ver_inc_map = {} + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + class db_found(Exception): pass try: # See whether there is a Sleepycat header in the standard # search path. for d in inc_dirs + db_inc_paths: f = os.path.join(d, "db.h") + + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "db.h") + if db_setup_debug: print "db: looking for db.h in", f if os.path.exists(f): f = open(f).read() @@ -844,7 +896,20 @@ db_incdir.replace("include", 'lib64'), db_incdir.replace("include", 'lib'), ] - db_dirs_to_check = filter(os.path.isdir, db_dirs_to_check) + + if sys.platform != 'darwin': + db_dirs_to_check = filter(os.path.isdir, db_dirs_to_check) + + else: + # Same as other branch, but takes OSX SDK into account + tmp = [] + for dn in db_dirs_to_check: + if is_macosx_sdk_path(dn): + if os.path.isdir(os.path.join(sysroot, dn[1:])): + tmp.append(dn) + else: + if os.path.isdir(dn): + tmp.append(dn) # Look for a version specific db-X.Y before an ambiguoius dbX # XXX should we -ever- look for a dbX name? Do any @@ -906,8 +971,15 @@ # Scan the default include directories before the SQLite specific # ones. This allows one to override the copy of sqlite on OSX, # where /usr/include contains an old version of sqlite. + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + for d in inc_dirs + sqlite_inc_paths: f = os.path.join(d, "sqlite3.h") + + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "sqlite3.h") + if os.path.exists(f): if sqlite_setup_debug: print "sqlite: found %s"%f incf = open(f).read() @@ -993,6 +1065,12 @@ # the more recent berkeleydb's db.h file first in the include path # when attempting to compile and it will fail. f = "/usr/include/db.h" + + if sys.platform == 'darwin': + if is_macosx_sdk_path(f): + sysroot = macosx_sdk_root() + f = os.path.join(sysroot, f[1:]) + if os.path.exists(f) and not db_incs: data = open(f).read() m = re.search(r"#s*define\s+HASHVERSION\s+2\s*", data) @@ -1483,14 +1561,22 @@ join(os.getenv('HOME'), '/Library/Frameworks') ] + sysroot = macosx_sdk_root() + # Find the directory that contains the Tcl.framework and Tk.framework # bundles. # XXX distutils should support -F! for F in framework_dirs: # both Tcl.framework and Tk.framework should be present + + for fw in 'Tcl', 'Tk': - if not exists(join(F, fw + '.framework')): - break + if is_macosx_sdk_path(F): + if not exists(join(sysroot, F[1:], fw + '.framework')): + break + else: + if not exists(join(F, fw + '.framework')): + break else: # ok, F is now directory with both frameworks. Continure # building @@ -1520,7 +1606,12 @@ # architectures. cflags = sysconfig.get_config_vars('CFLAGS')[0] archs = re.findall('-arch\s+(\w+)', cflags) - fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,)) + + if is_macosx_sdk_path(F): + fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(os.path.join(sysroot, F[1:]),)) + else: + fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,)) + detected_archs = [] for ln in fp: a = ln.split()[-1] From python-checkins at python.org Thu Jun 3 17:43:20 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 3 Jun 2010 17:43:20 +0200 (CEST) Subject: [Python-checkins] r81675 - in python/trunk: Lib/email/feedparser.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20100603154320.5878FEEB88@mail.python.org> Author: r.david.murray Date: Thu Jun 3 17:43:20 2010 New Revision: 81675 Log: #5610: use \Z not $ so we don't eat extra chars when body part ends with \r\n. If a body part ended with \r\n, feedparser, using '$' to terminate its search for the newline, would match on the \r\n, and think that it needed to strip two characters in order to account for the line end before the boundary. That made it chop one too many characters off the end of the body part. Using \Z makes the match correct. Patch and test by Tony Nelson. Modified: python/trunk/Lib/email/feedparser.py python/trunk/Lib/email/test/test_email.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/email/feedparser.py ============================================================================== --- python/trunk/Lib/email/feedparser.py (original) +++ python/trunk/Lib/email/feedparser.py Thu Jun 3 17:43:20 2010 @@ -28,7 +28,7 @@ NLCRE = re.compile('\r\n|\r|\n') NLCRE_bol = re.compile('(\r\n|\r|\n)') -NLCRE_eol = re.compile('(\r\n|\r|\n)$') +NLCRE_eol = re.compile('(\r\n|\r|\n)\Z') NLCRE_crack = re.compile('(\r\n|\r|\n)') # RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character # except controls, SP, and ":". Modified: python/trunk/Lib/email/test/test_email.py ============================================================================== --- python/trunk/Lib/email/test/test_email.py (original) +++ python/trunk/Lib/email/test/test_email.py Thu Jun 3 17:43:20 2010 @@ -2610,6 +2610,24 @@ eq(headers, ['A', 'B', 'CC']) eq(msg.get_payload(), 'body') + def test_CRLFLF_at_end_of_part(self): + # issue 5610: feedparser should not eat two chars from body part ending + # with "\r\n\n". + m = ( + "From: foo at bar.com\n" + "To: baz\n" + "Mime-Version: 1.0\n" + "Content-Type: multipart/mixed; boundary=BOUNDARY\n" + "\n" + "--BOUNDARY\n" + "Content-Type: text/plain\n" + "\n" + "body ending with CRLF newline\r\n" + "\n" + "--BOUNDARY--\n" + ) + msg = email.message_from_string(m) + self.assertTrue(msg.get_payload(0).get_payload().endswith('\r\n')) class TestBase64(unittest.TestCase): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Jun 3 17:43:20 2010 @@ -46,6 +46,9 @@ Library ------- +- Issue #5610: feedparser no longer eats extra characters at the end of + a body part if the body part ends with a \r\n. + - Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. From python-checkins at python.org Thu Jun 3 18:04:47 2010 From: python-checkins at python.org (stefan.krah) Date: Thu, 3 Jun 2010 18:04:47 +0200 (CEST) Subject: [Python-checkins] r81676 - python/branches/release26-maint/Lib/test/test_signal.py Message-ID: <20100603160447.94CA4EEBAF@mail.python.org> Author: stefan.krah Date: Thu Jun 3 18:04:47 2010 New Revision: 81676 Log: Also skip when test_support.verbose is false. Modified: python/branches/release26-maint/Lib/test/test_signal.py Modified: python/branches/release26-maint/Lib/test/test_signal.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_signal.py (original) +++ python/branches/release26-maint/Lib/test/test_signal.py Thu Jun 3 18:04:47 2010 @@ -141,9 +141,10 @@ def test_main(self): # Issue 3864, unknown if this affects earlier versions of freebsd also - if sys.platform=='freebsd6' and test_support.verbose: - sys.stderr.write('skipping -- inter process signals not reliable ' - '(do not mix well with threading) on freebsd6\n') + if sys.platform=='freebsd6': + if test_support.verbose: + sys.stderr.write('skipping -- inter process signals not ' + 'reliable (do not mix well with threading) on freebsd6\n') return # This function spawns a child process to insulate the main # test-running process from all the signals. It then @@ -435,9 +436,10 @@ def test_itimer_virtual(self): # Issue 3864, unknown if this affects earlier versions of freebsd also - if sys.platform=='freebsd6' and test_support.verbose: - sys.stderr.write('skipping -- itimer not reliable ' - '(does not mix well with threading) on freebsd6\n') + if sys.platform=='freebsd6': + if test_support.verbose: + sys.stderr.write('skipping -- itimer not reliable (does not ' + 'mix well with threading) on freebsd6\n') return self.itimer = signal.ITIMER_VIRTUAL signal.signal(signal.SIGVTALRM, self.sig_vtalrm) @@ -461,9 +463,10 @@ def test_itimer_prof(self): # Issue 3864, unknown if this affects earlier versions of freebsd also - if sys.platform=='freebsd6' and test_support.verbose: - sys.stderr.write('skipping -- itimer not reliable ' - '(does not mix well with threading) on freebsd6\n') + if sys.platform=='freebsd6': + if test_support.verbose: + sys.stderr.write('skipping -- itimer not reliable (does not ' + 'mix well with threading) on freebsd6\n') return self.itimer = signal.ITIMER_PROF signal.signal(signal.SIGPROF, self.sig_prof) From python-checkins at python.org Thu Jun 3 18:21:04 2010 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 3 Jun 2010 18:21:04 +0200 (CEST) Subject: [Python-checkins] r81677 - in python/branches/release31-maint: Lib/distutils/unixccompiler.py setup.py Message-ID: <20100603162104.05D9EEEBB8@mail.python.org> Author: ronald.oussoren Date: Thu Jun 3 18:21:03 2010 New Revision: 81677 Log: Merged revisions 81673 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81673 | ronald.oussoren | 2010-06-03 16:42:25 +0200 (Thu, 03 Jun 2010) | 16 lines Merged revisions 81662 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81662 | ronald.oussoren | 2010-06-03 11:47:21 +0200 (Thu, 03 Jun 2010) | 9 lines Fix for issue #7724: ensure that distutils and python's own setup.py honor the MacOSX SDK when one is specified. This is needed to be able to build using the 10.4u SDK while running on OSX 10.6. This is a fixed version of the patch in r80963, I've tested this patch on OSX and Linux. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/distutils/unixccompiler.py python/branches/release31-maint/setup.py Modified: python/branches/release31-maint/Lib/distutils/unixccompiler.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/unixccompiler.py (original) +++ python/branches/release31-maint/Lib/distutils/unixccompiler.py Thu Jun 3 18:21:03 2010 @@ -15,7 +15,7 @@ __revision__ = "$Id$" -import os, sys +import os, sys, re from distutils import sysconfig from distutils.dep_util import newer @@ -317,10 +317,30 @@ dylib_f = self.library_filename(lib, lib_type='dylib') static_f = self.library_filename(lib, lib_type='static') + if sys.platform == 'darwin': + # On OSX users can specify an alternate SDK using + # '-isysroot', calculate the SDK root if it is specified + # (and use it further on) + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + + + for dir in dirs: shared = os.path.join(dir, shared_f) dylib = os.path.join(dir, dylib_f) static = os.path.join(dir, static_f) + + if sys.platform == 'darwin' and ( + dir.startswith('/System/') or dir.startswith('/usr/')): + shared = os.path.join(sysroot, dir[1:], shared_f) + dylib = os.path.join(sysroot, dir[1:], dylib_f) + static = os.path.join(sysroot, dir[1:], static_f) + # We're second-guessing the linker here, with not much hard # data to go on: GCC seems to prefer the shared library, so I'm # assuming that *all* Unix C compilers do. And of course I'm Modified: python/branches/release31-maint/setup.py ============================================================================== --- python/branches/release31-maint/setup.py (original) +++ python/branches/release31-maint/setup.py Thu Jun 3 18:21:03 2010 @@ -25,6 +25,25 @@ if dir is not None and os.path.isdir(dir) and dir not in dirlist: dirlist.insert(0, dir) +def macosx_sdk_root(): + """ + Return the directory of the current OSX SDK, + or '/' if no SDK was specified. + """ + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + return sysroot + +def is_macosx_sdk_path(path): + """ + Returns True if 'path' can be located in an OSX SDK + """ + return path.startswith('/usr/') or path.startswith('/System/') + def find_file(filename, std_dirs, paths): """Searches for the directory where a given file is located, and returns a possibly-empty list of additional directories, or None @@ -36,15 +55,28 @@ 'paths' is a list of additional locations to check; if the file is found in one of them, the resulting list will contain the directory. """ + if sys.platform == 'darwin': + # Honor the MacOSX SDK setting when one was specified. + # An SDK is a directory with the same structure as a real + # system, but with only header files and libraries. + sysroot = macosx_sdk_root() # Check the standard locations for dir in std_dirs: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [] # Check the additional directories for dir in paths: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [dir] @@ -56,11 +88,19 @@ if result is None: return None + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + # Check whether the found file is in one of the standard directories dirname = os.path.dirname(result) for p in std_dirs: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ ] + if p == dirname: return [ ] @@ -69,6 +109,11 @@ for p in paths: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ p ] + if p == dirname: return [p] else: @@ -507,7 +552,7 @@ # library and then a static library, instead of first looking # for dynamic libraries on the entire path. # This way a staticly linked custom readline gets picked up - # before the (broken) dynamic library in /usr/lib. + # before the (possibly broken) dynamic library in /usr/lib. readline_extra_link_args = ('-Wl,-search_paths_first',) else: readline_extra_link_args = () @@ -581,22 +626,23 @@ openssl_ver = 0 openssl_ver_re = re.compile( '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' ) - for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in: - name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h') - if os.path.isfile(name): - try: - incfile = open(name, 'r') - for line in incfile: - m = openssl_ver_re.match(line) - if m: - openssl_ver = eval(m.group(1)) - break - except IOError: - pass - # first version found is what we'll use (as the compiler should) - if openssl_ver: - break + # look for the openssl version header on the compiler search path. + opensslv_h = find_file('openssl/opensslv.h', [], + inc_dirs + search_for_ssl_incs_in) + if opensslv_h: + name = os.path.join(opensslv_h[0], 'openssl/opensslv.h') + if sys.platform == 'darwin' and is_macosx_sdk_path(name): + name = os.path.join(macosx_sdk_root(), name[1:]) + try: + incfile = open(name, 'r') + for line in incfile: + m = openssl_ver_re.match(line) + if m: + openssl_ver = eval(m.group(1)) + except IOError as msg: + print("IOError while reading opensshv.h:", msg) + pass #print('openssl_ver = 0x%08x' % openssl_ver) @@ -717,12 +763,18 @@ db_ver_inc_map = {} + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + class db_found(Exception): pass try: # See whether there is a Sleepycat header in the standard # search path. for d in inc_dirs + db_inc_paths: f = os.path.join(d, "db.h") + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "db.h") + if db_setup_debug: print("db: looking for db.h in", f) if os.path.exists(f): f = open(f, "rb").read() @@ -769,7 +821,22 @@ db_incdir.replace("include", 'lib64'), db_incdir.replace("include", 'lib'), ] - db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + if sys.platform != 'darwin': + db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + else: + # Same as other branch, but takes OSX SDK into account + tmp = [] + for dn in db_dirs_to_check: + if is_macosx_sdk_path(dn): + if os.path.isdir(os.path.join(sysroot, dn[1:])): + tmp.append(dn) + else: + if os.path.isdir(dn): + tmp.append(dn) + + db_dirs_to_check = tmp # Look for a version specific db-X.Y before an ambiguoius dbX # XXX should we -ever- look for a dbX name? Do any @@ -818,8 +885,15 @@ # Scan the default include directories before the SQLite specific # ones. This allows one to override the copy of sqlite on OSX, # where /usr/include contains an old version of sqlite. + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + for d in inc_dirs + sqlite_inc_paths: f = os.path.join(d, "sqlite3.h") + + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "sqlite3.h") + if os.path.exists(f): if sqlite_setup_debug: print("sqlite: found %s"%f) incf = open(f).read() @@ -1245,14 +1319,22 @@ join(os.getenv('HOME'), '/Library/Frameworks') ] + sysroot = macosx_sdk_root() + # Find the directory that contains the Tcl.framework and Tk.framework # bundles. # XXX distutils should support -F! for F in framework_dirs: # both Tcl.framework and Tk.framework should be present + + for fw in 'Tcl', 'Tk': - if not exists(join(F, fw + '.framework')): - break + if is_macosx_sdk_path(F): + if not exists(join(sysroot, F[1:], fw + '.framework')): + break + else: + if not exists(join(F, fw + '.framework')): + break else: # ok, F is now directory with both frameworks. Continure # building @@ -1289,8 +1371,12 @@ # Note: cannot use os.popen or subprocess here, that # requires extensions that are not available here. - os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) + if is_macosx_sdk_path(F): + os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(os.path.join(sysroot, F[1:]), tmpfile)) + else: + os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) fp = open(tmpfile) + detected_archs = [] for ln in fp: a = ln.split()[-1] From python-checkins at python.org Thu Jun 3 22:19:25 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 3 Jun 2010 22:19:25 +0200 (CEST) Subject: [Python-checkins] r81678 - in python/trunk: Lib/test/test_support.py Misc/NEWS Message-ID: <20100603201925.47F61EE990@mail.python.org> Author: r.david.murray Date: Thu Jun 3 22:19:25 2010 New Revision: 81678 Log: #8889: rewrite transient_internet so we don't use EAI_NODATA on FreeBSD. FreeBSD doesn't have socket.EAI_NODATA. I rewrote the routine because there's no easy way to conditionally include a context manager in a with statement. As a side benefit, instead of a stack of context managers there's now only one. Modified: python/trunk/Lib/test/test_support.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_support.py ============================================================================== --- python/trunk/Lib/test/test_support.py (original) +++ python/trunk/Lib/test/test_support.py Thu Jun 3 22:19:25 2010 @@ -750,17 +750,32 @@ raise ResourceDenied("an optional resource is not available") +_transients = { + IOError: (errno.ECONNRESET, errno.ETIMEDOUT), + socket.error: (errno.ECONNRESET,), + socket.gaierror: [getattr(socket, t) + for t in ('EAI_NODATA', 'EAI_NONAME') + if hasattr(socket, t)], + } @contextlib.contextmanager def transient_internet(): """Return a context manager that raises ResourceDenied when various issues - with the Internet connection manifest themselves as exceptions.""" - time_out = TransientResource(IOError, errno=errno.ETIMEDOUT) - socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET) - ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET) - dns_nodata = TransientResource(socket.gaierror, errno=socket.EAI_NODATA) - dns_noname = TransientResource(socket.gaierror, errno=socket.EAI_NONAME) - with time_out, socket_peer_reset, ioerror_peer_reset, dns_nodata, dns_noname: + with the Internet connection manifest themselves as exceptions. + + Errors caught: + timeout IOError errno = ETIMEDOUT + socket reset socket.error, IOError errno = ECONNRESET + dns no data socket.gaierror errno = EAI_NODATA + dns no name socket.gaierror errno = EAI_NONAME + """ + try: yield + except tuple(_transients) as err: + for errtype in _transients: + if isinstance(err, errtype) and err.errno in _transients[errtype]: + raise ResourceDenied("could not establish network " + "connection ({})".format(err)) + raise @contextlib.contextmanager Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Jun 3 22:19:25 2010 @@ -105,7 +105,10 @@ Tests ----- -- Issue #8835: test_support.transient_internet() catchs gaierror(EAI_NONAME) +- Issue #8889: test_support.transient_internet rewritten so that the new + checks also work on FreeBSD, which lacks EAI_NODATA. + +- Issue #8835: test_support.transient_internet() catches gaierror(EAI_NONAME) and gaierror(EAI_NODATA) - Issue #7449: Skip test_socketserver if threading support is disabled From python-checkins at python.org Thu Jun 3 23:21:03 2010 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 3 Jun 2010 23:21:03 +0200 (CEST) Subject: [Python-checkins] r81679 - python/trunk/Lib/site.py Message-ID: <20100603212103.8CB3CEE99B@mail.python.org> Author: benjamin.peterson Date: Thu Jun 3 23:21:03 2010 New Revision: 81679 Log: use a set for membership testing Modified: python/trunk/Lib/site.py Modified: python/trunk/Lib/site.py ============================================================================== --- python/trunk/Lib/site.py (original) +++ python/trunk/Lib/site.py Thu Jun 3 23:21:03 2010 @@ -276,12 +276,12 @@ environment, and will return a list of full paths. """ sitepackages = [] - seen = [] + seen = set() for prefix in PREFIXES: if not prefix or prefix in seen: continue - seen.append(prefix) + seen.add(prefix) if sys.platform in ('os2emx', 'riscos'): sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) From python-checkins at python.org Fri Jun 4 00:34:42 2010 From: python-checkins at python.org (vinay.sajip) Date: Fri, 4 Jun 2010 00:34:42 +0200 (CEST) Subject: [Python-checkins] r81680 - python/trunk/Doc/library/logging.rst Message-ID: <20100603223442.852F7EE996@mail.python.org> Author: vinay.sajip Date: Fri Jun 4 00:34:42 2010 New Revision: 81680 Log: Issue #8890: Documentation changed to avoid reference to temporary files. Modified: python/trunk/Doc/library/logging.rst Modified: python/trunk/Doc/library/logging.rst ============================================================================== --- python/trunk/Doc/library/logging.rst (original) +++ python/trunk/Doc/library/logging.rst Fri Jun 4 00:34:42 2010 @@ -55,10 +55,12 @@ Most applications are probably going to want to log to a file, so let's start with that case. Using the :func:`basicConfig` function, we can set up the -default handler so that debug messages are written to a file:: +default handler so that debug messages are written to a file (in the example, +we assume that you have the appropriate permissions to create a file called +*example.log* in the current directory:: import logging - LOG_FILENAME = '/tmp/logging_example.out' + LOG_FILENAME = 'example.log' logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG) logging.debug('This message should go to the log file') From solipsis at pitrou.net Fri Jun 4 01:23:25 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 4 Jun 2010 01:23:25 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81673): sum=0 Message-ID: <20100603232326.102961770A@ns6635.ovh.net> py3k results for svn r81673 (hg cset 7da632f142ed) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogXBofHD', '-x'] From python-checkins at python.org Fri Jun 4 03:51:27 2010 From: python-checkins at python.org (sean.reifschneider) Date: Fri, 4 Jun 2010 03:51:27 +0200 (CEST) Subject: [Python-checkins] r81681 - python/trunk/Modules/datetimemodule.c Message-ID: <20100604015127.1C135EEBFB@mail.python.org> Author: sean.reifschneider Date: Fri Jun 4 03:51:26 2010 New Revision: 81681 Log: Issue8810: Clearing up docstring for tzinfo.utcoffset. Modified: python/trunk/Modules/datetimemodule.c Modified: python/trunk/Modules/datetimemodule.c ============================================================================== --- python/trunk/Modules/datetimemodule.c (original) +++ python/trunk/Modules/datetimemodule.c Fri Jun 4 03:51:26 2010 @@ -3026,7 +3026,8 @@ PyDoc_STR("datetime -> DST offset in minutes east of UTC.")}, {"fromutc", (PyCFunction)tzinfo_fromutc, METH_O, - PyDoc_STR("datetime in UTC -> datetime in local time.")}, + PyDoc_STR("datetime -> timedelta showing offset from UTC, negative " + "values indicating West of UTC")}, {"__reduce__", (PyCFunction)tzinfo_reduce, METH_NOARGS, PyDoc_STR("-> (cls, state)")}, From python-checkins at python.org Fri Jun 4 03:51:38 2010 From: python-checkins at python.org (sean.reifschneider) Date: Fri, 4 Jun 2010 03:51:38 +0200 (CEST) Subject: [Python-checkins] r81682 - python/branches/py3k/Modules/datetimemodule.c Message-ID: <20100604015138.59F86EEC05@mail.python.org> Author: sean.reifschneider Date: Fri Jun 4 03:51:38 2010 New Revision: 81682 Log: Issue8810: Clearing up docstring for tzinfo.utcoffset. Modified: python/branches/py3k/Modules/datetimemodule.c Modified: python/branches/py3k/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k/Modules/datetimemodule.c (original) +++ python/branches/py3k/Modules/datetimemodule.c Fri Jun 4 03:51:38 2010 @@ -3223,8 +3223,8 @@ PyDoc_STR("datetime -> string name of time zone.")}, {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O, - PyDoc_STR("datetime -> minutes east of UTC (negative for " - "west of UTC).")}, + PyDoc_STR("datetime -> timedelta showing offset from UTC, negative " + "values indicating West of UTC")}, {"dst", (PyCFunction)tzinfo_dst, METH_O, PyDoc_STR("datetime -> DST offset in minutes east of UTC.")}, From mal at egenix.com Fri Jun 4 10:58:09 2010 From: mal at egenix.com (M.-A. Lemburg) Date: Fri, 04 Jun 2010 10:58:09 +0200 Subject: [Python-checkins] r81674 - in python/branches/release26-maint: Lib/distutils/unixccompiler.py setup.py In-Reply-To: <20100603145956.6FC1BEEA2E@mail.python.org> References: <20100603145956.6FC1BEEA2E@mail.python.org> Message-ID: <4C08C021.5010309@egenix.com> ronald.oussoren wrote: > Author: ronald.oussoren > Date: Thu Jun 3 16:59:56 2010 > New Revision: 81674 > > Log: > Merged revisions 81662 via svnmerge from > svn+ssh://pythondev at svn.python.org/python/trunk > > ........ > r81662 | ronald.oussoren | 2010-06-03 11:47:21 +0200 (Thu, 03 Jun 2010) | 9 lines > > Fix for issue #7724: ensure that distutils and python's own setup.py > honor the MacOSX SDK when one is specified. > > This is needed to be able to build using the 10.4u SDK while running > on OSX 10.6. > > This is a fixed version of the patch in r80963, I've tested this patch > on OSX and Linux. Overall, I don't particularly like this patch. It adds way too many special cases just for the MacOSX SDK setup. Isn't there some more elegant way to update the search paths if an SDK is present - one that doesn't require this long tail of "if sys.platform == 'darwin':..." all over setup.py ? BTW, this part still doesn't look right: > @@ -647,24 +692,24 @@ > openssl_ver = 0 > openssl_ver_re = re.compile( > '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' ) > - for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in: > - name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h') > - if os.path.isfile(name): > - try: > - incfile = open(name, 'r') > - for line in incfile: > - m = openssl_ver_re.match(line) > - if m: > - openssl_ver = eval(m.group(1)) > - break > - except IOError: > - pass > > - # first version found is what we'll use (as the compiler should) > - if openssl_ver: > - break > + # look for the openssl version header on the compiler search path. > + opensslv_h = find_file('openssl/opensslv.h', [], You should use os.path.join() for this rather than a verbatim '/'. > + inc_dirs + search_for_ssl_incs_in) > + if opensslv_h: > + name = os.path.join(opensslv_h[0], 'openssl/opensslv.h') > + if sys.platform == 'darwin' and is_macosx_sdk_path(name): > + name = os.path.join(macosx_sdk_root(), name[1:]) > + try: > + incfile = open(name, 'r') > + for line in incfile: > + m = openssl_ver_re.match(line) > + if m: > + openssl_ver = eval(m.group(1)) > + except IOError, msg: > + print "IOError while reading opensshv.h:", msg > + pass Note that the new code doesn't search all available opensslv.h header files for a matching case. It only looks at the first found and if that doesn't match, it fails. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Jun 04 2010) >>> Python/Zope Consulting and Support ... http://www.egenix.com/ >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ ________________________________________________________________________ 2010-07-19: EuroPython 2010, Birmingham, UK 44 days to go ::: Try our new mxODBC.Connect Python Database Interface for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/ From python-checkins at python.org Fri Jun 4 11:49:21 2010 From: python-checkins at python.org (stefan.krah) Date: Fri, 4 Jun 2010 11:49:21 +0200 (CEST) Subject: [Python-checkins] r81683 - python/trunk/setup.py Message-ID: <20100604094921.2C2A4EE994@mail.python.org> Author: stefan.krah Date: Fri Jun 4 11:49:20 2010 New Revision: 81683 Log: Detect missing ldd on all systems. Modified: python/trunk/setup.py Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Fri Jun 4 11:49:20 2010 @@ -15,6 +15,7 @@ from distutils.command.build_ext import build_ext from distutils.command.install import install from distutils.command.install_lib import install_lib +from distutils.spawn import find_executable # Were we compiled --with-pydebug or with #define Py_DEBUG? COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') @@ -591,7 +592,7 @@ readline_termcap_library = "" curses_library = "" # Determine if readline is already linked against curses or tinfo. - if do_readline and platform != 'darwin': # OS X does not have ldd. + if do_readline and find_executable('ldd'): fp = os.popen("ldd %s" % do_readline) for ln in fp: if 'curses' in ln: From python-checkins at python.org Fri Jun 4 15:41:02 2010 From: python-checkins at python.org (vinay.sajip) Date: Fri, 4 Jun 2010 15:41:02 +0200 (CEST) Subject: [Python-checkins] r81684 - python/trunk/Doc/library/logging.rst Message-ID: <20100604134102.60B6BEEC1B@mail.python.org> Author: vinay.sajip Date: Fri Jun 4 15:41:02 2010 New Revision: 81684 Log: Issue #8890: Documentation changed to avoid reference to temporary files - other cases covered. Modified: python/trunk/Doc/library/logging.rst Modified: python/trunk/Doc/library/logging.rst ============================================================================== --- python/trunk/Doc/library/logging.rst (original) +++ python/trunk/Doc/library/logging.rst Fri Jun 4 15:41:02 2010 @@ -57,7 +57,7 @@ with that case. Using the :func:`basicConfig` function, we can set up the default handler so that debug messages are written to a file (in the example, we assume that you have the appropriate permissions to create a file called -*example.log* in the current directory:: +*example.log* in the current directory):: import logging LOG_FILENAME = 'example.log' @@ -79,7 +79,7 @@ import logging import logging.handlers - LOG_FILENAME = '/tmp/logging_rotatingfile_example.out' + LOG_FILENAME = 'logging_rotatingfile_example.out' # Set up a specific logger with our desired output level my_logger = logging.getLogger('MyLogger') @@ -104,14 +104,14 @@ The result should be 6 separate files, each with part of the log history for the application:: - /tmp/logging_rotatingfile_example.out - /tmp/logging_rotatingfile_example.out.1 - /tmp/logging_rotatingfile_example.out.2 - /tmp/logging_rotatingfile_example.out.3 - /tmp/logging_rotatingfile_example.out.4 - /tmp/logging_rotatingfile_example.out.5 + logging_rotatingfile_example.out + logging_rotatingfile_example.out.1 + logging_rotatingfile_example.out.2 + logging_rotatingfile_example.out.3 + logging_rotatingfile_example.out.4 + logging_rotatingfile_example.out.5 -The most current file is always :file:`/tmp/logging_rotatingfile_example.out`, +The most current file is always :file:`logging_rotatingfile_example.out`, and each time it reaches the size limit it is renamed with the suffix ``.1``. Each of the existing backup files is renamed to increment the suffix (``.1`` becomes ``.2``, etc.) and the ``.6`` file is erased. @@ -1134,14 +1134,14 @@ logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', - filename='/tmp/myapp.log', + filename='myapp.log', filemode='w') logging.debug('A debug message') logging.info('Some information') logging.warning('A shot across the bows') The :meth:`basicConfig` method is used to change the configuration defaults, -which results in output (written to ``/tmp/myapp.log``) which should look +which results in output (written to ``myapp.log``) which should look something like the following:: 2004-07-02 13:00:08,743 DEBUG A debug message From python-checkins at python.org Fri Jun 4 18:11:08 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 4 Jun 2010 18:11:08 +0200 (CEST) Subject: [Python-checkins] r81685 - in python/branches/py3k: Lib/email/encoders.py Lib/email/test/test_email.py Misc/ACKS Misc/NEWS Message-ID: <20100604161108.E11EEEECD8@mail.python.org> Author: r.david.murray Date: Fri Jun 4 18:11:08 2010 New Revision: 81685 Log: #4768: store base64 encoded email body parts as text, not binary. Patch and tests by Forest Bond. Modified: python/branches/py3k/Lib/email/encoders.py python/branches/py3k/Lib/email/test/test_email.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/email/encoders.py ============================================================================== --- python/branches/py3k/Lib/email/encoders.py (original) +++ python/branches/py3k/Lib/email/encoders.py Fri Jun 4 18:11:08 2010 @@ -29,7 +29,7 @@ Also, add an appropriate Content-Transfer-Encoding header. """ orig = msg.get_payload() - encdata = _bencode(orig) + encdata = str(_bencode(orig), 'ascii') msg.set_payload(encdata) msg['Content-Transfer-Encoding'] = 'base64' Modified: python/branches/py3k/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k/Lib/email/test/test_email.py (original) +++ python/branches/py3k/Lib/email/test/test_email.py Fri Jun 4 18:11:08 2010 @@ -970,7 +970,8 @@ def test_encoding(self): payload = self._au.get_payload() - self.assertEqual(base64.decodebytes(payload), self._audiodata) + self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), + self._audiodata) def test_checkSetMinor(self): au = MIMEAudio(self._audiodata, 'fish') @@ -1010,7 +1011,8 @@ def test_encoding(self): payload = self._im.get_payload() - self.assertEqual(base64.decodebytes(payload), self._imgdata) + self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), + self._imgdata) def test_checkSetMinor(self): im = MIMEImage(self._imgdata, 'fish') @@ -1050,7 +1052,7 @@ eq = self.assertEqual bytes = b'\xfa\xfb\xfc\xfd\xfe\xff' msg = MIMEApplication(bytes) - eq(msg.get_payload(), b'+vv8/f7/') + eq(msg.get_payload(), '+vv8/f7/') eq(msg.get_payload(decode=True), bytes) Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Fri Jun 4 18:11:08 2010 @@ -83,6 +83,7 @@ Paul Boddie Matthew Boedicker David Bolen +Forest Bond Gawain Bolton Gregory Bond Jurjen Bos Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 4 18:11:08 2010 @@ -398,6 +398,9 @@ Library ------- +- Issue #4768: base64 encoded email body parts were incorrectly stored as + binary strings. They are now correctly converted to strings. + - Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. From python-checkins at python.org Fri Jun 4 18:15:35 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 4 Jun 2010 18:15:35 +0200 (CEST) Subject: [Python-checkins] r81686 - in python/branches/release31-maint: Lib/email/encoders.py Lib/email/test/test_email.py Misc/ACKS Misc/NEWS Message-ID: <20100604161535.252B7EEA2@mail.python.org> Author: r.david.murray Date: Fri Jun 4 18:15:34 2010 New Revision: 81686 Log: Merged revisions 81685 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81685 | r.david.murray | 2010-06-04 12:11:08 -0400 (Fri, 04 Jun 2010) | 4 lines #4768: store base64 encoded email body parts as text, not binary. Patch and tests by Forest Bond. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/email/encoders.py python/branches/release31-maint/Lib/email/test/test_email.py python/branches/release31-maint/Misc/ACKS python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/email/encoders.py ============================================================================== --- python/branches/release31-maint/Lib/email/encoders.py (original) +++ python/branches/release31-maint/Lib/email/encoders.py Fri Jun 4 18:15:34 2010 @@ -29,7 +29,7 @@ Also, add an appropriate Content-Transfer-Encoding header. """ orig = msg.get_payload() - encdata = _bencode(orig) + encdata = str(_bencode(orig), 'ascii') msg.set_payload(encdata) msg['Content-Transfer-Encoding'] = 'base64' Modified: python/branches/release31-maint/Lib/email/test/test_email.py ============================================================================== --- python/branches/release31-maint/Lib/email/test/test_email.py (original) +++ python/branches/release31-maint/Lib/email/test/test_email.py Fri Jun 4 18:15:34 2010 @@ -966,7 +966,8 @@ def test_encoding(self): payload = self._au.get_payload() - self.assertEqual(base64.decodebytes(payload), self._audiodata) + self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), + self._audiodata) def test_checkSetMinor(self): au = MIMEAudio(self._audiodata, 'fish') @@ -1006,7 +1007,8 @@ def test_encoding(self): payload = self._im.get_payload() - self.assertEqual(base64.decodebytes(payload), self._imgdata) + self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), + self._imgdata) def test_checkSetMinor(self): im = MIMEImage(self._imgdata, 'fish') @@ -1046,7 +1048,7 @@ eq = self.assertEqual bytes = b'\xfa\xfb\xfc\xfd\xfe\xff' msg = MIMEApplication(bytes) - eq(msg.get_payload(), b'+vv8/f7/') + eq(msg.get_payload(), '+vv8/f7/') eq(msg.get_payload(decode=True), bytes) Modified: python/branches/release31-maint/Misc/ACKS ============================================================================== --- python/branches/release31-maint/Misc/ACKS (original) +++ python/branches/release31-maint/Misc/ACKS Fri Jun 4 18:15:34 2010 @@ -81,6 +81,7 @@ Paul Boddie Matthew Boedicker David Bolen +Forest Bond Gregory Bond Jurjen Bos Peter Bosch Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Jun 4 18:15:34 2010 @@ -54,6 +54,9 @@ Library ------- +- Issue #4768: base64 encoded email body parts were incorrectly stored as + binary strings. They are now correctly converted to strings. + - Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. From python-checkins at python.org Fri Jun 4 18:32:14 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 4 Jun 2010 18:32:14 +0200 (CEST) Subject: [Python-checkins] r81687 - python/trunk/Lib/httplib.py Message-ID: <20100604163214.8A4F1EECE9@mail.python.org> Author: senthil.kumaran Date: Fri Jun 4 18:32:14 2010 New Revision: 81687 Log: Fix issue6312 - close the resp object for HEAD response. Modified: python/trunk/Lib/httplib.py Modified: python/trunk/Lib/httplib.py ============================================================================== --- python/trunk/Lib/httplib.py (original) +++ python/trunk/Lib/httplib.py Fri Jun 4 18:32:14 2010 @@ -525,6 +525,7 @@ return '' if self._method == 'HEAD': + self.close() return '' if self.chunked: From python-checkins at python.org Fri Jun 4 18:34:53 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 4 Jun 2010 18:34:53 +0200 (CEST) Subject: [Python-checkins] r81688 - in python/branches/release26-maint: Lib/httplib.py Message-ID: <20100604163453.83E7BEFE3@mail.python.org> Author: senthil.kumaran Date: Fri Jun 4 18:34:53 2010 New Revision: 81688 Log: Merged revisions 81687 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81687 | senthil.kumaran | 2010-06-04 22:02:14 +0530 (Fri, 04 Jun 2010) | 3 lines Fix issue6312 - close the resp object for HEAD response. ........ Modified: python/branches/release26-maint/ (props changed) 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 Fri Jun 4 18:34:53 2010 @@ -515,6 +515,7 @@ return '' if self._method == 'HEAD': + self.close() return '' if self.chunked: From python-checkins at python.org Fri Jun 4 18:38:00 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 4 Jun 2010 18:38:00 +0200 (CEST) Subject: [Python-checkins] r81689 - in python/branches/py3k: Lib/http/client.py Message-ID: <20100604163800.BAC2FEE98A@mail.python.org> Author: senthil.kumaran Date: Fri Jun 4 18:38:00 2010 New Revision: 81689 Log: Merged revisions 81687 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81687 | senthil.kumaran | 2010-06-04 22:02:14 +0530 (Fri, 04 Jun 2010) | 3 lines Fix issue6312 - close the resp object for HEAD response. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/http/client.py Modified: python/branches/py3k/Lib/http/client.py ============================================================================== --- python/branches/py3k/Lib/http/client.py (original) +++ python/branches/py3k/Lib/http/client.py Fri Jun 4 18:38:00 2010 @@ -488,6 +488,7 @@ return b"" if self._method == "HEAD": + self.close() return b"" if self.chunked: From python-checkins at python.org Fri Jun 4 18:43:10 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 4 Jun 2010 18:43:10 +0200 (CEST) Subject: [Python-checkins] r81690 - in python/branches/release31-maint: Lib/http/client.py Message-ID: <20100604164310.CDA46EE9AC@mail.python.org> Author: senthil.kumaran Date: Fri Jun 4 18:43:10 2010 New Revision: 81690 Log: Merged revisions 81689 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81689 | senthil.kumaran | 2010-06-04 22:08:00 +0530 (Fri, 04 Jun 2010) | 9 lines Merged revisions 81687 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81687 | senthil.kumaran | 2010-06-04 22:02:14 +0530 (Fri, 04 Jun 2010) | 3 lines Fix issue6312 - close the resp object for HEAD response. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/http/client.py 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 Fri Jun 4 18:43:10 2010 @@ -488,6 +488,7 @@ return b"" if self._method == "HEAD": + self.close() return b"" if self.chunked: From python-checkins at python.org Fri Jun 4 19:17:09 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 4 Jun 2010 19:17:09 +0200 (CEST) Subject: [Python-checkins] r81691 - python/trunk/Lib/test/test_httplib.py Message-ID: <20100604171709.62EADEECBA@mail.python.org> Author: senthil.kumaran Date: Fri Jun 4 19:17:09 2010 New Revision: 81691 Log: test verifying the resp object is closed for HEAD response. Modified: python/trunk/Lib/test/test_httplib.py Modified: python/trunk/Lib/test/test_httplib.py ============================================================================== --- python/trunk/Lib/test/test_httplib.py (original) +++ python/trunk/Lib/test/test_httplib.py Fri Jun 4 19:17:09 2010 @@ -227,7 +227,7 @@ self.assertEquals(resp.read(), '') self.assertEquals(resp.status, 200) self.assertEquals(resp.reason, 'OK') - resp.close() + self.assertTrue(resp.isclosed()) def test_negative_content_length(self): sock = FakeSocket('HTTP/1.1 200 OK\r\n' From python-checkins at python.org Fri Jun 4 19:18:43 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 19:18:43 +0200 (CEST) Subject: [Python-checkins] r81692 - in python/trunk: Misc/NEWS Modules/_multiprocessing/multiprocessing.h Message-ID: <20100604171843.056C4F2F1@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 19:18:42 2010 New Revision: 81692 Log: Issue #8864: Define _XOPEN_SOURCE on Solaris for the multiprocessing module. Modified: python/trunk/Misc/NEWS python/trunk/Modules/_multiprocessing/multiprocessing.h Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Jun 4 19:18:42 2010 @@ -120,7 +120,8 @@ Build ----- -- Issue #1759169: Drop _XOPEN_SOURCE on Solaris. +- Issues #1759169, #8864: Drop _XOPEN_SOURCE on Solaris, define it for + multiprocessing only. What's New in Python 2.7 beta 2? ================================ Modified: python/trunk/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/trunk/Modules/_multiprocessing/multiprocessing.h (original) +++ python/trunk/Modules/_multiprocessing/multiprocessing.h Fri Jun 4 19:18:42 2010 @@ -3,6 +3,12 @@ #define PY_SSIZE_T_CLEAN +#ifdef __sun +/* The control message API is only available on Solaris + if XPG 4.2 or later is requested. */ +#define _XOPEN_SOURCE 500 +#endif + #include "Python.h" #include "structmember.h" #include "pythread.h" From python-checkins at python.org Fri Jun 4 19:20:13 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 4 Jun 2010 19:20:13 +0200 (CEST) Subject: [Python-checkins] r81693 - in python/branches/release26-maint: Lib/test/test_httplib.py Message-ID: <20100604172013.BAFD4EE999@mail.python.org> Author: senthil.kumaran Date: Fri Jun 4 19:20:13 2010 New Revision: 81693 Log: Merged revisions 81691 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81691 | senthil.kumaran | 2010-06-04 22:47:09 +0530 (Fri, 04 Jun 2010) | 3 lines test verifying the resp object is closed for HEAD response. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_httplib.py Modified: python/branches/release26-maint/Lib/test/test_httplib.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_httplib.py (original) +++ python/branches/release26-maint/Lib/test/test_httplib.py Fri Jun 4 19:20:13 2010 @@ -222,7 +222,7 @@ self.assertEquals(resp.read(), '') self.assertEquals(resp.status, 200) self.assertEquals(resp.reason, 'OK') - resp.close() + self.assertTrue(resp.isclosed()) def test_negative_content_length(self): sock = FakeSocket('HTTP/1.1 200 OK\r\n' From python-checkins at python.org Fri Jun 4 19:20:56 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 19:20:56 +0200 (CEST) Subject: [Python-checkins] r81694 - in python/branches/py3k: Misc/NEWS Modules/_multiprocessing/multiprocessing.h Message-ID: <20100604172056.69FACEE999@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 19:20:56 2010 New Revision: 81694 Log: Merged revisions 81692 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81692 | martin.v.loewis | 2010-06-04 19:18:42 +0200 (Fr, 04 Jun 2010) | 3 lines Issue #8864: Define _XOPEN_SOURCE on Solaris for the multiprocessing module. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_multiprocessing/multiprocessing.h Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 4 19:20:56 2010 @@ -1328,7 +1328,8 @@ Build ----- -- Issue #1759169: Drop _XOPEN_SOURCE on Solaris. +- Issue #1759169, #8864: Drop _XOPEN_SOURCE on Solaris, define it for + multiprocessing only. - Issue #8625: Turn off optimization in --with-pydebug builds with gcc. (Optimization was unintentionally turned on in gcc Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.h Fri Jun 4 19:20:56 2010 @@ -3,6 +3,12 @@ #define PY_SSIZE_T_CLEAN +#ifdef __sun +/* The control message API is only available on Solaris + if XPG 4.2 or later is requested. */ +#define _XOPEN_SOURCE 500 +#endif + #include "Python.h" #include "structmember.h" #include "pythread.h" From python-checkins at python.org Fri Jun 4 19:27:11 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 4 Jun 2010 19:27:11 +0200 (CEST) Subject: [Python-checkins] r81695 - in python/branches/py3k: Lib/test/test_httplib.py Message-ID: <20100604172711.94547F6905@mail.python.org> Author: senthil.kumaran Date: Fri Jun 4 19:27:11 2010 New Revision: 81695 Log: Merged revisions 81691 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81691 | senthil.kumaran | 2010-06-04 22:47:09 +0530 (Fri, 04 Jun 2010) | 3 lines test verifying the resp object is closed for HEAD response. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_httplib.py Modified: python/branches/py3k/Lib/test/test_httplib.py ============================================================================== --- python/branches/py3k/Lib/test/test_httplib.py (original) +++ python/branches/py3k/Lib/test/test_httplib.py Fri Jun 4 19:27:11 2010 @@ -239,7 +239,7 @@ self.assertEquals(resp.read(), b'') self.assertEquals(resp.status, 200) self.assertEquals(resp.reason, 'OK') - resp.close() + self.assertTrue(resp.isclosed()) def test_negative_content_length(self): sock = FakeSocket( From python-checkins at python.org Fri Jun 4 19:31:11 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 4 Jun 2010 19:31:11 +0200 (CEST) Subject: [Python-checkins] r81696 - in python/branches/release31-maint: Lib/test/test_httplib.py Message-ID: <20100604173111.B3FECEE9B8@mail.python.org> Author: senthil.kumaran Date: Fri Jun 4 19:31:11 2010 New Revision: 81696 Log: Merged revisions 81695 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81695 | senthil.kumaran | 2010-06-04 22:57:11 +0530 (Fri, 04 Jun 2010) | 9 lines Merged revisions 81691 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81691 | senthil.kumaran | 2010-06-04 22:47:09 +0530 (Fri, 04 Jun 2010) | 3 lines test verifying the resp object is closed for HEAD response. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_httplib.py Modified: python/branches/release31-maint/Lib/test/test_httplib.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_httplib.py (original) +++ python/branches/release31-maint/Lib/test/test_httplib.py Fri Jun 4 19:31:11 2010 @@ -234,7 +234,7 @@ self.assertEquals(resp.read(), b'') self.assertEquals(resp.status, 200) self.assertEquals(resp.reason, 'OK') - resp.close() + self.assertTrue(resp.isclosed()) def test_negative_content_length(self): sock = FakeSocket( From python-checkins at python.org Fri Jun 4 20:04:42 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 20:04:42 +0200 (CEST) Subject: [Python-checkins] r81697 - in python/trunk: Misc/NEWS Tools/i18n/msgfmt.py Message-ID: <20100604180442.6EAFEEECE6@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 20:04:42 2010 New Revision: 81697 Log: Issue #5464: Implement plural forms in msgfmt.py. Modified: python/trunk/Misc/NEWS python/trunk/Tools/i18n/msgfmt.py Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Jun 4 20:04:42 2010 @@ -123,6 +123,12 @@ - Issues #1759169, #8864: Drop _XOPEN_SOURCE on Solaris, define it for multiprocessing only. +Tools/Demos +----------- + +- Issue #5464: Implement plural forms in msgfmt.py. + + What's New in Python 2.7 beta 2? ================================ Modified: python/trunk/Tools/i18n/msgfmt.py ============================================================================== --- python/trunk/Tools/i18n/msgfmt.py (original) +++ python/trunk/Tools/i18n/msgfmt.py Fri Jun 4 20:04:42 2010 @@ -133,16 +133,39 @@ if l[0] == '#': continue # Now we are in a msgid section, output previous section - if l.startswith('msgid'): + if l.startswith('msgid') and not l.startswith('msgid_plural'): if section == STR: add(msgid, msgstr, fuzzy) section = ID l = l[5:] msgid = msgstr = '' + is_plural = False + # This is a message with plural forms + elif l.startswith('msgid_plural'): + if section != ID: + print >> sys.stderr, 'msgid_plural not preceeded by msgid on %s:%d' %\ + (infile, lno) + sys.exit(1) + l = l[12:] + msgid += '\0' # separator of singular and plural + is_plural = True # Now we are in a msgstr section elif l.startswith('msgstr'): section = STR - l = l[6:] + if l.startswith('msgstr['): + if not is_plural: + print >> sys.stderr, 'plural without msgid_plural on %s:%d' %\ + (infile, lno) + sys.exit(1) + l = l.split(']', 1)[1] + if msgstr: + msgstr += '\0' # Separator of the various plural forms + else: + if is_plural: + print >> sys.stderr, 'indexed msgstr required for plural on %s:%d' %\ + (infile, lno) + sys.exit(1) + l = l[6:] # Skip empty lines l = l.strip() if not l: From python-checkins at python.org Fri Jun 4 20:14:43 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 20:14:43 +0200 (CEST) Subject: [Python-checkins] r81698 - in python/branches/py3k: Misc/NEWS Tools/i18n/msgfmt.py Message-ID: <20100604181443.034B0F6905@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 20:14:42 2010 New Revision: 81698 Log: Merged revisions 81697 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81697 | martin.v.loewis | 2010-06-04 20:04:42 +0200 (Fr, 04 Jun 2010) | 2 lines Issue #5464: Implement plural forms in msgfmt.py. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/Tools/i18n/msgfmt.py Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 4 20:14:42 2010 @@ -1548,6 +1548,8 @@ Tools/Demos ----------- +- Issue #5464: Implement plural forms in msgfmt.py. + - iobench (a file I/O benchmark) and ccbench (a concurrency benchmark) were added to the `Tools/` directory. They were previously living in the sandbox. Modified: python/branches/py3k/Tools/i18n/msgfmt.py ============================================================================== --- python/branches/py3k/Tools/i18n/msgfmt.py (original) +++ python/branches/py3k/Tools/i18n/msgfmt.py Fri Jun 4 20:14:42 2010 @@ -132,16 +132,39 @@ if l[0] == '#': continue # Now we are in a msgid section, output previous section - if l.startswith('msgid'): + if l.startswith('msgid') and not l.startswith('msgid_plural'): if section == STR: add(msgid, msgstr, fuzzy) section = ID l = l[5:] msgid = msgstr = '' + is_plural = False + # This is a message with plural forms + elif l.startswith('msgid_plural'): + if section != ID: + print('msgid_plural not preceeded by msgid on %s:%d' % (infile, lno), + file=sys.stderr) + sys.exit(1) + l = l[12:] + msgid += '\0' # separator of singular and plural + is_plural = True # Now we are in a msgstr section elif l.startswith('msgstr'): section = STR - l = l[6:] + if l.startswith('msgstr['): + if not is_plural: + print(sys.stderr, 'plural without msgid_plural on %s:%d' % (infile, lno), + file=sys.stderr) + sys.exit(1) + l = l.split(']', 1)[1] + if msgstr: + msgstr += '\0' # Separator of the various plural forms + else: + if is_plural: + print(sys.stderr, 'indexed msgstr required for plural on %s:%d' % (infile, lno), + file=sys.stderr) + sys.exit(1) + l = l[6:] # Skip empty lines l = l.strip() if not l: From python-checkins at python.org Fri Jun 4 20:40:55 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 20:40:55 +0200 (CEST) Subject: [Python-checkins] r81699 - python/branches/py3k/Tools/i18n/msgfmt.py Message-ID: <20100604184055.66D12EED08@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 20:40:55 2010 New Revision: 81699 Log: Port to Python 3. Modified: python/branches/py3k/Tools/i18n/msgfmt.py Modified: python/branches/py3k/Tools/i18n/msgfmt.py ============================================================================== --- python/branches/py3k/Tools/i18n/msgfmt.py (original) +++ python/branches/py3k/Tools/i18n/msgfmt.py Fri Jun 4 20:40:55 2010 @@ -30,6 +30,7 @@ import getopt import struct import array +from email.parser import HeaderParser __version__ = "1.1" @@ -59,13 +60,13 @@ # the keys are sorted in the .mo file keys = sorted(MESSAGES.keys()) offsets = [] - ids = strs = '' + ids = strs = b'' for id in keys: # For each string, we need size and file offset. Each string is NUL # terminated; the NUL does not count into the size. offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) - ids += id + '\0' - strs += MESSAGES[id] + '\0' + ids += id + b'\0' + strs += MESSAGES[id] + b'\0' output = '' # The header is 7 32-bit unsigned integers. We don't use hash tables, so # the keys start right after the index tables. @@ -108,7 +109,7 @@ outfile = os.path.splitext(infile)[0] + '.mo' try: - lines = open(infile).readlines() + lines = open(infile, 'rb').readlines() except IOError as msg: print(msg, file=sys.stderr) sys.exit(1) @@ -116,9 +117,14 @@ section = None fuzzy = 0 + # Start off assuming Latin-1, so everything decodes without failure, + # until we know the exact encoding + encoding = 'latin-1' + # Parse the catalog lno = 0 for l in lines: + l = l.decode(encoding) lno += 1 # If we get a comment line after a msgstr, this is a new entry if l[0] == '#' and section == STR: @@ -135,9 +141,15 @@ if l.startswith('msgid') and not l.startswith('msgid_plural'): if section == STR: add(msgid, msgstr, fuzzy) + if not msgid: + # See whether there is an encoding declaration + p = HeaderParser() + charset = p.parsestr(msgstr.decode(encoding)).get_content_charset() + if charset: + encoding = charset section = ID l = l[5:] - msgid = msgstr = '' + msgid = msgstr = b'' is_plural = False # This is a message with plural forms elif l.startswith('msgid_plural'): @@ -146,7 +158,7 @@ file=sys.stderr) sys.exit(1) l = l[12:] - msgid += '\0' # separator of singular and plural + msgid += b'\0' # separator of singular and plural is_plural = True # Now we are in a msgstr section elif l.startswith('msgstr'): @@ -158,7 +170,7 @@ sys.exit(1) l = l.split(']', 1)[1] if msgstr: - msgstr += '\0' # Separator of the various plural forms + msgstr += b'\0' # Separator of the various plural forms else: if is_plural: print(sys.stderr, 'indexed msgstr required for plural on %s:%d' % (infile, lno), @@ -172,9 +184,9 @@ # XXX: Does this always follow Python escape semantics? l = eval(l) if section == ID: - msgid += l + msgid += l.encode(encoding) elif section == STR: - msgstr += l + msgstr += l.encode(encoding) else: print('Syntax error on %s:%d' % (infile, lno), \ 'before:', file=sys.stderr) From python-checkins at python.org Fri Jun 4 21:15:32 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 21:15:32 +0200 (CEST) Subject: [Python-checkins] r81700 - in python/trunk: Misc/NEWS Tools/msi/msi.py Message-ID: <20100604191532.9AA0AEED17@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 21:15:32 2010 New Revision: 81700 Log: Display installer warning that Windows 2000 won't be supported in future releases. Modified: python/trunk/Misc/NEWS python/trunk/Tools/msi/msi.py Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Jun 4 21:15:32 2010 @@ -120,6 +120,9 @@ Build ----- +- Display installer warning that Windows 2000 won't be supported in future + releases. + - Issues #1759169, #8864: Drop _XOPEN_SOURCE on Solaris, define it for multiprocessing only. Modified: python/trunk/Tools/msi/msi.py ============================================================================== --- python/trunk/Tools/msi/msi.py (original) +++ python/trunk/Tools/msi/msi.py Fri Jun 4 21:15:32 2010 @@ -503,9 +503,9 @@ " would still be Python for DOS.") c = exit_dialog.text("warning", 135, 200, 220, 40, 0x30003, - "{\\VerdanaRed9}Warning: Python 2.5.x is the last " - "Python release for Windows 9x.") - c.condition("Hide", "NOT Version9X") + "{\\VerdanaRed9}Warning: Python 2.7.x is the last " + "Python release for Windows 2000.") + c.condition("Hide", "VersionNT > 500") exit_dialog.text("Description", 135, 235, 220, 20, 0x30003, "Click the Finish button to exit the Installer.") From python-checkins at python.org Fri Jun 4 21:39:07 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 21:39:07 +0200 (CEST) Subject: [Python-checkins] r81701 - in python/trunk: Lib/lib-tk/FixTk.py Lib/test/test_tcl.py Misc/NEWS Message-ID: <20100604193907.55480EEC20@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 21:39:07 2010 New Revision: 81701 Log: Issue #6470: Drop UNC prefix in FixTk.py Patch by Christop Gohlke and Amaury Forgeot d'Arc. Modified: python/trunk/Lib/lib-tk/FixTk.py python/trunk/Lib/test/test_tcl.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/lib-tk/FixTk.py ============================================================================== --- python/trunk/Lib/lib-tk/FixTk.py (original) +++ python/trunk/Lib/lib-tk/FixTk.py Fri Jun 4 21:39:07 2010 @@ -42,6 +42,8 @@ # Ignore leading \\?\ if s.startswith("\\\\?\\"): s = s[4:] + if s.startswith("UNC"): + s = "\\" + s[3:] return s prefix = os.path.join(sys.prefix,"tcl") Modified: python/trunk/Lib/test/test_tcl.py ============================================================================== --- python/trunk/Lib/test/test_tcl.py (original) +++ python/trunk/Lib/test/test_tcl.py Fri Jun 4 21:39:07 2010 @@ -127,6 +127,31 @@ tcl = self.interp self.assertRaises(TclError,tcl.eval,'package require DNE') + def testLoadWithUNC(self): + import sys + if sys.platform != 'win32': + return + + # Build a UNC path from the regular path. + # Something like + # \\%COMPUTERNAME%\c$\python27\python.exe + + fullname = os.path.abspath(sys.executable) + if fullname[1] != ':': + return + unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'], + fullname[0], + fullname[3:]) + + with test_support.EnvironmentVarGuard() as env: + env.unset("TCL_LIBRARY") + f = os.popen('%s -c "import Tkinter; print Tkinter"' % (unc_name,)) + + self.assert_('Tkinter.py' in f.read()) + # exit code must be zero + self.assertEqual(f.close(), None) + + def test_main(): test_support.run_unittest(TclTest, TkinterTest) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Jun 4 21:39:07 2010 @@ -46,6 +46,8 @@ Library ------- +- Issue #6470: Drop UNC prefix in FixTk. + - Issue #5610: feedparser no longer eats extra characters at the end of a body part if the body part ends with a \r\n. From python-checkins at python.org Fri Jun 4 21:46:21 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 21:46:21 +0200 (CEST) Subject: [Python-checkins] r81702 - in python/branches/release26-maint: Lib/lib-tk/FixTk.py Lib/test/test_tcl.py Misc/NEWS Message-ID: <20100604194621.E5FD2EED0A@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 21:46:21 2010 New Revision: 81702 Log: Merged revisions 81701 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81701 | martin.v.loewis | 2010-06-04 21:39:07 +0200 (Fr, 04 Jun 2010) | 2 lines Issue #6470: Drop UNC prefix in FixTk.py Patch by Christop Gohlke and Amaury Forgeot d'Arc. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/lib-tk/FixTk.py python/branches/release26-maint/Lib/test/test_tcl.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/lib-tk/FixTk.py ============================================================================== --- python/branches/release26-maint/Lib/lib-tk/FixTk.py (original) +++ python/branches/release26-maint/Lib/lib-tk/FixTk.py Fri Jun 4 21:46:21 2010 @@ -42,6 +42,8 @@ # Ignore leading \\?\ if s.startswith("\\\\?\\"): s = s[4:] + if s.startswith("UNC"): + s = "\\" + s[3:] return s prefix = os.path.join(sys.prefix,"tcl") Modified: python/branches/release26-maint/Lib/test/test_tcl.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_tcl.py (original) +++ python/branches/release26-maint/Lib/test/test_tcl.py Fri Jun 4 21:46:21 2010 @@ -150,6 +150,31 @@ if old_display is not None: os.environ['DISPLAY'] = old_display + def testLoadWithUNC(self): + import sys + if sys.platform != 'win32': + return + + # Build a UNC path from the regular path. + # Something like + # \\%COMPUTERNAME%\c$\python27\python.exe + + fullname = os.path.abspath(sys.executable) + if fullname[1] != ':': + return + unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'], + fullname[0], + fullname[3:]) + + with test_support.EnvironmentVarGuard() as env: + env.unset("TCL_LIBRARY") + f = os.popen('%s -c "import Tkinter; print Tkinter"' % (unc_name,)) + + self.assert_('Tkinter.py' in f.read()) + # exit code must be zero + self.assertEqual(f.close(), None) + + def test_main(): test_support.run_unittest(TclTest) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Fri Jun 4 21:46:21 2010 @@ -58,6 +58,8 @@ Library ------- +- Issue #6470: Drop UNC prefix in FixTk. + - Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. From python-checkins at python.org Fri Jun 4 21:50:27 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 21:50:27 +0200 (CEST) Subject: [Python-checkins] r81703 - in python/branches/py3k: Lib/test/test_tcl.py Lib/tkinter/_fix.py Misc/NEWS Message-ID: <20100604195027.11DC6EEC9B@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 21:50:26 2010 New Revision: 81703 Log: Merged revisions 81701 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81701 | martin.v.loewis | 2010-06-04 21:39:07 +0200 (Fr, 04 Jun 2010) | 2 lines Issue #6470: Drop UNC prefix in FixTk.py Patch by Christop Gohlke and Amaury Forgeot d'Arc. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_tcl.py python/branches/py3k/Lib/tkinter/_fix.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/test_tcl.py ============================================================================== --- python/branches/py3k/Lib/test/test_tcl.py (original) +++ python/branches/py3k/Lib/test/test_tcl.py Fri Jun 4 21:50:26 2010 @@ -127,6 +127,31 @@ tcl = self.interp self.assertRaises(TclError,tcl.eval,'package require DNE') + def testLoadWithUNC(self): + import sys + if sys.platform != 'win32': + return + + # Build a UNC path from the regular path. + # Something like + # \\%COMPUTERNAME%\c$\python27\python.exe + + fullname = os.path.abspath(sys.executable) + if fullname[1] != ':': + return + unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'], + fullname[0], + fullname[3:]) + + with test_support.EnvironmentVarGuard() as env: + env.unset("TCL_LIBRARY") + f = os.popen('%s -c "import Tkinter; print Tkinter"' % (unc_name,)) + + self.assert_('Tkinter.py' in f.read()) + # exit code must be zero + self.assertEqual(f.close(), None) + + def test_main(): support.run_unittest(TclTest, TkinterTest) Modified: python/branches/py3k/Lib/tkinter/_fix.py ============================================================================== --- python/branches/py3k/Lib/tkinter/_fix.py (original) +++ python/branches/py3k/Lib/tkinter/_fix.py Fri Jun 4 21:50:26 2010 @@ -42,6 +42,8 @@ # Ignore leading \\?\ if s.startswith("\\\\?\\"): s = s[4:] + if s.startswith("UNC"): + s = "\\" + s[3:] return s prefix = os.path.join(sys.prefix,"tcl") Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 4 21:50:26 2010 @@ -398,6 +398,8 @@ Library ------- +- Issue #6470: Drop UNC prefix in FixTk. + - Issue #4768: base64 encoded email body parts were incorrectly stored as binary strings. They are now correctly converted to strings. From python-checkins at python.org Fri Jun 4 21:51:05 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 4 Jun 2010 21:51:05 +0200 (CEST) Subject: [Python-checkins] r81704 - in python/branches/release31-maint: Lib/test/test_tcl.py Lib/tkinter/_fix.py Misc/NEWS Message-ID: <20100604195105.3E139EEC9E@mail.python.org> Author: martin.v.loewis Date: Fri Jun 4 21:51:05 2010 New Revision: 81704 Log: Merged revisions 81703 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81703 | martin.v.loewis | 2010-06-04 21:50:26 +0200 (Fr, 04 Jun 2010) | 10 lines Merged revisions 81701 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81701 | martin.v.loewis | 2010-06-04 21:39:07 +0200 (Fr, 04 Jun 2010) | 2 lines Issue #6470: Drop UNC prefix in FixTk.py Patch by Christop Gohlke and Amaury Forgeot d'Arc. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_tcl.py python/branches/release31-maint/Lib/tkinter/_fix.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/test/test_tcl.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_tcl.py (original) +++ python/branches/release31-maint/Lib/test/test_tcl.py Fri Jun 4 21:51:05 2010 @@ -127,6 +127,31 @@ tcl = self.interp self.assertRaises(TclError,tcl.eval,'package require DNE') + def testLoadWithUNC(self): + import sys + if sys.platform != 'win32': + return + + # Build a UNC path from the regular path. + # Something like + # \\%COMPUTERNAME%\c$\python27\python.exe + + fullname = os.path.abspath(sys.executable) + if fullname[1] != ':': + return + unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'], + fullname[0], + fullname[3:]) + + with test_support.EnvironmentVarGuard() as env: + env.unset("TCL_LIBRARY") + f = os.popen('%s -c "import Tkinter; print Tkinter"' % (unc_name,)) + + self.assert_('Tkinter.py' in f.read()) + # exit code must be zero + self.assertEqual(f.close(), None) + + def test_main(): support.run_unittest(TclTest, TkinterTest) Modified: python/branches/release31-maint/Lib/tkinter/_fix.py ============================================================================== --- python/branches/release31-maint/Lib/tkinter/_fix.py (original) +++ python/branches/release31-maint/Lib/tkinter/_fix.py Fri Jun 4 21:51:05 2010 @@ -42,6 +42,8 @@ # Ignore leading \\?\ if s.startswith("\\\\?\\"): s = s[4:] + if s.startswith("UNC"): + s = "\\" + s[3:] return s prefix = os.path.join(sys.prefix,"tcl") Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Jun 4 21:51:05 2010 @@ -54,6 +54,8 @@ Library ------- +- Issue #6470: Drop UNC prefix in FixTk. + - Issue #4768: base64 encoded email body parts were incorrectly stored as binary strings. They are now correctly converted to strings. From python-checkins at python.org Fri Jun 4 21:51:06 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 4 Jun 2010 21:51:06 +0200 (CEST) Subject: [Python-checkins] r81705 - in python/trunk: Lib/email/charset.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20100604195106.E3D15EED13@mail.python.org> Author: r.david.murray Date: Fri Jun 4 21:51:06 2010 New Revision: 81705 Log: #4487: have Charset check with codecs for possible aliases. Previously, unexpected results occurred when email was passed, for example, 'utf8' as a charset name, since email would accept it but would *not* use the 'utf-8' codec for it, even though Python itself recognises that as an alias for utf-8. Now Charset checks with codecs for aliases as well as its own internal table. Issue 8898 has been opened to change this further in py3k so that all aliasing is routed through the codecs module. Modified: python/trunk/Lib/email/charset.py python/trunk/Lib/email/test/test_email.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/email/charset.py ============================================================================== --- python/trunk/Lib/email/charset.py (original) +++ python/trunk/Lib/email/charset.py Fri Jun 4 21:51:06 2010 @@ -9,6 +9,7 @@ 'add_codec', ] +import codecs import email.base64mime import email.quoprimime @@ -209,7 +210,12 @@ except UnicodeError: raise errors.CharsetError(input_charset) input_charset = input_charset.lower() - # Set the input charset after filtering through the aliases + # Set the input charset after filtering through the aliases and/or codecs + if not (input_charset in ALIASES or input_charset in CHARSETS): + try: + input_charset = codecs.lookup(input_charset).name + except LookupError: + pass self.input_charset = ALIASES.get(input_charset, input_charset) # We can try to guess which encoding and conversion to use by the # charset_map dictionary. Try that first, but let the user override Modified: python/trunk/Lib/email/test/test_email.py ============================================================================== --- python/trunk/Lib/email/test/test_email.py (original) +++ python/trunk/Lib/email/test/test_email.py Fri Jun 4 21:51:06 2010 @@ -2868,6 +2868,9 @@ self.assertEqual(str(charset), 'us-ascii') self.assertRaises(Errors.CharsetError, Charset, 'asc\xffii') + def test_codecs_aliases_accepted(self): + charset = Charset('utf8') + self.assertEqual(str(charset), 'utf-8') # Test multilingual MIME headers. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Jun 4 21:51:06 2010 @@ -46,6 +46,9 @@ Library ------- +- Issue #4487: email now accepts as charset aliases all codec aliases + accepted by the codecs module. + - Issue #6470: Drop UNC prefix in FixTk. - Issue #5610: feedparser no longer eats extra characters at the end of From solipsis at pitrou.net Sat Jun 5 01:23:39 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 5 Jun 2010 01:23:39 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81703): sum=0 Message-ID: <20100604232339.8D4261770A@ns6635.ovh.net> py3k results for svn r81703 (hg cset a0c24aaa2de5) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogUlgvl4', '-x'] From python-checkins at python.org Sat Jun 5 02:32:51 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 5 Jun 2010 02:32:51 +0200 (CEST) Subject: [Python-checkins] r81706 - in python/trunk: Lib/test/test_descr.py Objects/abstract.c Message-ID: <20100605003251.2A9BCEECF3@mail.python.org> Author: benjamin.peterson Date: Sat Jun 5 02:32:50 2010 New Revision: 81706 Log: properly lookup the __format__ special method Modified: python/trunk/Lib/test/test_descr.py python/trunk/Objects/abstract.c Modified: python/trunk/Lib/test/test_descr.py ============================================================================== --- python/trunk/Lib/test/test_descr.py (original) +++ python/trunk/Lib/test/test_descr.py Sat Jun 5 02:32:50 2010 @@ -1697,6 +1697,8 @@ def some_number(self_, key): self.assertEqual(key, "hi") return 4 + def format_impl(self, spec): + return "hello" # It would be nice to have every special method tested here, but I'm # only listing the ones I can remember outside of typeobject.c, since it @@ -1715,6 +1717,7 @@ ("__enter__", run_context, iden, set(), {"__exit__" : swallow}), ("__exit__", run_context, swallow, set(), {"__enter__" : iden}), ("__complex__", complex, complex_num, set(), {}), + ("__format__", format, format_impl, set(), {}), ] class Checker(object): Modified: python/trunk/Objects/abstract.c ============================================================================== --- python/trunk/Objects/abstract.c (original) +++ python/trunk/Objects/abstract.c Sat Jun 5 02:32:50 2010 @@ -723,7 +723,6 @@ PyObject * PyObject_Format(PyObject* obj, PyObject *format_spec) { - static PyObject * str__format__ = NULL; PyObject *empty = NULL; PyObject *result = NULL; #ifdef Py_USING_UNICODE @@ -731,14 +730,6 @@ int result_is_unicode; #endif - /* Initialize cached value */ - if (str__format__ == NULL) { - /* Initialize static variable needed by _PyType_Lookup */ - str__format__ = PyString_InternFromString("__format__"); - if (str__format__ == NULL) - goto done; - } - /* If no format_spec is provided, use an empty string */ if (format_spec == NULL) { empty = PyString_FromStringAndSize(NULL, 0); @@ -769,8 +760,7 @@ /* Check for a __format__ method and call it. */ if (PyInstance_Check(obj)) { /* We're an instance of a classic class */ - PyObject *bound_method = PyObject_GetAttr(obj, - str__format__); + PyObject *bound_method = PyObject_GetAttrString(obj, "__format__"); if (bound_method != NULL) { result = PyObject_CallFunctionObjArgs(bound_method, format_spec, @@ -820,8 +810,7 @@ } /* Then call str.__format__ on that result */ - format_method = PyObject_GetAttr(self_as_str, - str__format__); + format_method = PyObject_GetAttrString(self_as_str, "__format__"); if (format_method == NULL) { goto done1; } @@ -837,20 +826,21 @@ } else { /* Not an instance of a classic class, use the code from py3k */ + static PyObject *format_cache; /* Find the (unbound!) __format__ method (a borrowed reference) */ - PyObject *method = _PyType_Lookup(Py_TYPE(obj), - str__format__); + PyObject *method = _PyObject_LookupSpecial(obj, "__format__", + &format_cache); if (method == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __format__", - Py_TYPE(obj)->tp_name); + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __format__", + Py_TYPE(obj)->tp_name); goto done; } - /* And call it, binding it to the value */ - result = PyObject_CallFunctionObjArgs(method, obj, - format_spec, NULL); + /* And call it. */ + result = PyObject_CallFunctionObjArgs(method, format_spec, NULL); } if (result == NULL) From python-checkins at python.org Sat Jun 5 02:38:22 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 5 Jun 2010 02:38:22 +0200 (CEST) Subject: [Python-checkins] r81707 - python/trunk/Objects/abstract.c Message-ID: <20100605003822.EF84AEECF3@mail.python.org> Author: benjamin.peterson Date: Sat Jun 5 02:38:22 2010 New Revision: 81707 Log: remove PyType_Ready call; float should be initialized in interpreter startup Modified: python/trunk/Objects/abstract.c Modified: python/trunk/Objects/abstract.c ============================================================================== --- python/trunk/Objects/abstract.c (original) +++ python/trunk/Objects/abstract.c Sat Jun 5 02:38:22 2010 @@ -752,11 +752,6 @@ goto done; } - /* Make sure the type is initialized. float gets initialized late */ - if (Py_TYPE(obj)->tp_dict == NULL) - if (PyType_Ready(Py_TYPE(obj)) < 0) - goto done; - /* Check for a __format__ method and call it. */ if (PyInstance_Check(obj)) { /* We're an instance of a classic class */ @@ -826,7 +821,7 @@ } else { /* Not an instance of a classic class, use the code from py3k */ - static PyObject *format_cache; + static PyObject *format_cache = NULL; /* Find the (unbound!) __format__ method (a borrowed reference) */ From python-checkins at python.org Sat Jun 5 02:45:38 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 5 Jun 2010 02:45:38 +0200 (CEST) Subject: [Python-checkins] r81708 - in python/branches/py3k: Lib/test/test_descr.py Objects/abstract.c Message-ID: <20100605004538.15428EED0C@mail.python.org> Author: benjamin.peterson Date: Sat Jun 5 02:45:37 2010 New Revision: 81708 Log: Merged revisions 81706-81707 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81706 | benjamin.peterson | 2010-06-04 19:32:50 -0500 (Fri, 04 Jun 2010) | 1 line properly lookup the __format__ special method ........ r81707 | benjamin.peterson | 2010-06-04 19:38:22 -0500 (Fri, 04 Jun 2010) | 1 line remove PyType_Ready call; float should be initialized in interpreter startup ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_descr.py python/branches/py3k/Objects/abstract.c Modified: python/branches/py3k/Lib/test/test_descr.py ============================================================================== --- python/branches/py3k/Lib/test/test_descr.py (original) +++ python/branches/py3k/Lib/test/test_descr.py Sat Jun 5 02:45:37 2010 @@ -1557,6 +1557,8 @@ self.assertEqual(key, "hi") return 4 def swallow(*args): pass + def format_impl(self, spec): + return "hello" # It would be nice to have every special method tested here, but I'm # only listing the ones I can remember outside of typeobject.c, since it @@ -1575,6 +1577,7 @@ ("__enter__", run_context, iden, set(), {"__exit__" : swallow}), ("__exit__", run_context, swallow, set(), {"__enter__" : iden}), ("__complex__", complex, complex_num, set(), {}), + ("__format__", format, format_impl, set(), {}), ] class Checker(object): Modified: python/branches/py3k/Objects/abstract.c ============================================================================== --- python/branches/py3k/Objects/abstract.c (original) +++ python/branches/py3k/Objects/abstract.c Sat Jun 5 02:45:37 2010 @@ -693,48 +693,36 @@ PyObject * PyObject_Format(PyObject *obj, PyObject *format_spec) { - static PyObject * str__format__ = NULL; PyObject *meth; PyObject *empty = NULL; PyObject *result = NULL; - - /* Initialize cached value */ - if (str__format__ == NULL) { - /* Initialize static variable needed by _PyType_Lookup */ - str__format__ = PyUnicode_FromString("__format__"); - if (str__format__ == NULL) - goto done; - } + static PyObject *format_cache = NULL; /* If no format_spec is provided, use an empty string */ if (format_spec == NULL) { - empty = PyUnicode_FromUnicode(NULL, 0); - format_spec = empty; + empty = PyUnicode_FromUnicode(NULL, 0); + format_spec = empty; } - /* Make sure the type is initialized. float gets initialized late */ - if (Py_TYPE(obj)->tp_dict == NULL) - if (PyType_Ready(Py_TYPE(obj)) < 0) - goto done; - /* Find the (unbound!) __format__ method (a borrowed reference) */ - meth = _PyType_Lookup(Py_TYPE(obj), str__format__); + meth = _PyObject_LookupSpecial(obj, "__format__", &format_cache); if (meth == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __format__", - Py_TYPE(obj)->tp_name); + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __format__", + Py_TYPE(obj)->tp_name); goto done; } - /* And call it, binding it to the value */ - result = PyObject_CallFunctionObjArgs(meth, obj, format_spec, NULL); + /* And call it. */ + result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL); if (result && !PyUnicode_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "__format__ method did not return string"); - Py_DECREF(result); - result = NULL; - goto done; + PyErr_SetString(PyExc_TypeError, + "__format__ method did not return string"); + Py_DECREF(result); + result = NULL; + goto done; } done: From python-checkins at python.org Sat Jun 5 02:56:46 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 5 Jun 2010 02:56:46 +0200 (CEST) Subject: [Python-checkins] r81709 - python/trunk/Objects/typeobject.c Message-ID: <20100605005646.7D6E2EE9C1@mail.python.org> Author: benjamin.peterson Date: Sat Jun 5 02:56:46 2010 New Revision: 81709 Log: implement object.__format__ with PyObject_Format Modified: python/trunk/Objects/typeobject.c Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Sat Jun 5 02:56:46 2010 @@ -3413,7 +3413,6 @@ PyObject *format_spec; PyObject *self_as_str = NULL; PyObject *result = NULL; - PyObject *format_meth = NULL; Py_ssize_t format_len; if (!PyArg_ParseTuple(args, "O:__format__", &format_spec)) @@ -3449,21 +3448,11 @@ goto done; */ } - - /* find the format function */ - format_meth = PyObject_GetAttrString(self_as_str, - "__format__"); - if (format_meth != NULL) { - /* and call it */ - result = PyObject_CallFunctionObjArgs(format_meth, - format_spec, - NULL); - } + return PyObject_Format(self_as_str, format_spec); } done: Py_XDECREF(self_as_str); - Py_XDECREF(format_meth); return result; } From python-checkins at python.org Sat Jun 5 03:00:10 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 5 Jun 2010 03:00:10 +0200 (CEST) Subject: [Python-checkins] r81710 - python/trunk/Objects/typeobject.c Message-ID: <20100605010010.B832DEE9C1@mail.python.org> Author: benjamin.peterson Date: Sat Jun 5 03:00:10 2010 New Revision: 81710 Log: fix ref counting Modified: python/trunk/Objects/typeobject.c Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Sat Jun 5 03:00:10 2010 @@ -3448,7 +3448,7 @@ goto done; */ } - return PyObject_Format(self_as_str, format_spec); + result = PyObject_Format(self_as_str, format_spec); } done: From python-checkins at python.org Sat Jun 5 03:03:25 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 5 Jun 2010 03:03:25 +0200 (CEST) Subject: [Python-checkins] r81711 - in python/branches/py3k: Objects/typeobject.c Message-ID: <20100605010325.0FBB7EEDA1@mail.python.org> Author: benjamin.peterson Date: Sat Jun 5 03:03:24 2010 New Revision: 81711 Log: Merged revisions 81709-81710 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81709 | benjamin.peterson | 2010-06-04 19:56:46 -0500 (Fri, 04 Jun 2010) | 1 line implement object.__format__ with PyObject_Format ........ r81710 | benjamin.peterson | 2010-06-04 20:00:10 -0500 (Fri, 04 Jun 2010) | 1 line fix ref counting ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Objects/typeobject.c Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Sat Jun 5 03:03:24 2010 @@ -3310,23 +3310,15 @@ PyObject *format_spec; PyObject *self_as_str = NULL; PyObject *result = NULL; - PyObject *format_meth = NULL; if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) return NULL; self_as_str = PyObject_Str(self); - if (self_as_str != NULL) { - /* find the format function */ - format_meth = PyObject_GetAttrString(self_as_str, "__format__"); - if (format_meth != NULL) { - /* and call it */ - result = PyObject_CallFunctionObjArgs(format_meth, format_spec, NULL); - } - } + if (self_as_str != NULL) + result = PyObject_Format(self_as_str, format_spec); Py_XDECREF(self_as_str); - Py_XDECREF(format_meth); return result; } From python-checkins at python.org Sat Jun 5 04:07:01 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 5 Jun 2010 04:07:01 +0200 (CEST) Subject: [Python-checkins] r81712 - python/trunk/Objects/abstract.c Message-ID: <20100605020701.32B58EE9D5@mail.python.org> Author: benjamin.peterson Date: Sat Jun 5 04:07:01 2010 New Revision: 81712 Log: _PyObject_LookupSpecial returns a new reference Modified: python/trunk/Objects/abstract.c Modified: python/trunk/Objects/abstract.c ============================================================================== --- python/trunk/Objects/abstract.c (original) +++ python/trunk/Objects/abstract.c Sat Jun 5 04:07:01 2010 @@ -836,6 +836,7 @@ } /* And call it. */ result = PyObject_CallFunctionObjArgs(method, format_spec, NULL); + Py_DECREF(method); } if (result == NULL) From python-checkins at python.org Sat Jun 5 04:11:45 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 5 Jun 2010 04:11:45 +0200 (CEST) Subject: [Python-checkins] r81713 - in python/branches/py3k: Objects/abstract.c Message-ID: <20100605021145.670C7EEDA8@mail.python.org> Author: benjamin.peterson Date: Sat Jun 5 04:11:45 2010 New Revision: 81713 Log: Merged revisions 81712 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81712 | benjamin.peterson | 2010-06-04 21:07:01 -0500 (Fri, 04 Jun 2010) | 1 line _PyObject_LookupSpecial returns a new reference ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Objects/abstract.c Modified: python/branches/py3k/Objects/abstract.c ============================================================================== --- python/branches/py3k/Objects/abstract.c (original) +++ python/branches/py3k/Objects/abstract.c Sat Jun 5 04:11:45 2010 @@ -716,6 +716,7 @@ /* And call it. */ result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL); + Py_DECREF(meth); if (result && !PyUnicode_Check(result)) { PyErr_SetString(PyExc_TypeError, From python-checkins at python.org Sat Jun 5 09:45:11 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 09:45:11 +0200 (CEST) Subject: [Python-checkins] r81714 - python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Message-ID: <20100605074511.43C68EED8B@mail.python.org> Author: stefan.krah Date: Sat Jun 5 09:45:11 2010 New Revision: 81714 Log: 1) Speed up threading: The speed penalty is now about 16%. The new default is to compile with thread local contexts enabled. 2) Make clamp a public context field. Allow both _clamp and clamp for backwards compatibility. 3) Add IEEEContext factory function for interchange format contexts. 4) context.copy() should not zero the status. 5) All sNaN comparisons raise InvalidOperation. 6) Module default context is initialized from DefaultContext on first access (compatibility with decimal.py). 7) Use DefaultContext for the Context() constructor. 8) format() uses the 'capitals' setting of the context as default. 9) Change order of Context.__repr__ to match decimal.py. 10) Use PyUnicode_CompareWithASCIIString. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Modified: python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Sat Jun 5 09:45:11 2010 @@ -32,7 +32,6 @@ #define Dec_INCREF_TRUE (Py_INCREF(Py_True), Py_True) #define Dec_INCREF_FALSE (Py_INCREF(Py_False), Py_False) -#define Dec_INCREF_NONE (Py_INCREF(Py_None), Py_None) typedef struct { @@ -72,15 +71,23 @@ #define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags) #define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags) #define CtxAddr(v) (&((PyDecContextObject *)v)->ctx) +#define CtxCaps(v) (((PyDecContextObject *)v)->capitals) +#ifdef WITHOUT_THREADS /* Default module context */ static PyObject *module_context = NULL; -/* Basic and extended contexts */ -static PyObject *basic_context = NULL; -static PyObject *ext_context = NULL; -/* Thread local objects */ -static PyObject *tls = NULL; +#else +/* Key for thread state dictionary */ +static PyObject *tls_context_key = NULL; +#endif + +/* Template for creating new thread contexts, calling Context() without + * arguments and initializing the module_context on first access. */ +static PyObject *default_context_template = NULL; +/* Basic and extended context templates */ +static PyObject *basic_context_template = NULL; +static PyObject *extended_context_template = NULL; typedef struct { @@ -696,7 +703,7 @@ static PyObject * context_getcapitals(PyObject *self, void *closure UNUSED) { - return Py_BuildValue("i", ((PyDecContextObject *)self)->capitals); + return Py_BuildValue("i", CtxCaps(self)); } static PyObject * @@ -870,7 +877,7 @@ return -1; } - ((PyDecContextObject *)self)->capitals = (int)x; + CtxCaps(self) = (int)x; return 0; } @@ -1040,54 +1047,59 @@ static PyObject * context_getattr(PyObject *self, PyObject *name) { - PyObject *retval, *s; + PyObject *retval; - if ((s = PyUnicode_AsASCIIString(name)) == NULL) { + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); return NULL; } - if (strcmp(PyBytes_AS_STRING(s), "traps") == 0) { + if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { retval = ((PyDecContextObject *)self)->traps; Py_INCREF(retval); + return retval; } - else if (strcmp(PyBytes_AS_STRING(s), "flags") == 0) { + else if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { retval = ((PyDecContextObject *)self)->flags; Py_INCREF(retval); + return retval; } else { - retval = PyObject_GenericGetAttr(self, name); + return PyObject_GenericGetAttr(self, name); } - - Py_DECREF(s); - return retval; } static int context_setattr(PyObject *self, PyObject *name, PyObject *value) { - PyObject *s; - int retval = 0; - - if ((s = PyUnicode_AsASCIIString(name)) == NULL) { + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); return -1; } - if (strcmp(PyBytes_AS_STRING(s), "traps") == 0) { - if (context_settraps_dict(self, value) < 0) { - retval = -1; + if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { + if (value == NULL) { + PyErr_SetString(PyExc_ValueError, + "traps cannot be deleted"); + return -1; } + return context_settraps_dict(self, value); } - else if (strcmp(PyBytes_AS_STRING(s), "flags") == 0) { - if (context_setstatus_dict(self, value) < 0) { - retval = -1; + else if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { + if (value == NULL) { + PyErr_SetString(PyExc_ValueError, + "flags cannot be deleted"); + return -1; } + return context_setstatus_dict(self, value); } else { - retval = PyObject_GenericSetAttr(self, name, value); + return PyObject_GenericSetAttr(self, name, value); } - - Py_DECREF(s); - return retval; } static PyObject * @@ -1150,28 +1162,44 @@ PyObject_Del(self); } +#ifdef CONFIG_64 + #define DEC_DFLT_EMAX 999999999 + #define DEC_DFLT_EMIN -999999999 +#else + #define DEC_DFLT_EMAX MPD_MAX_EMAX + #define DEC_DFLT_EMIN MPD_MIN_EMIN +#endif + +static mpd_context_t dflt_ctx = { + 28, DEC_DFLT_EMAX, DEC_DFLT_EMIN, + MPD_Invalid_operation|MPD_Division_by_zero|MPD_Overflow, + 0, 0, MPD_ROUND_HALF_EVEN, 0, 1 +}; + static int context_init(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = { - "prec", "Emin", "Emax", "rounding", "capitals", - "traps", "flags", "_clamp", "_allcr", NULL + "prec", "rounding", "Emin", "Emax", "capitals", "clamp", + "flags", "traps", "_allcr", NULL }; PyObject *traps = NULL; PyObject *status = NULL; - mpd_context_t *ctx, t; + mpd_context_t *ctx, t=dflt_ctx; int capitals = 1; assert(PyTuple_Check(args)); ctx = CtxAddr(self); - mpd_defaultcontext(&t); + if (default_context_template) { + t = *CtxAddr(default_context_template); + } if (!PyArg_ParseTupleAndKeywords( args, kwds, - "|"CONV_mpd_ssize_t CONV_mpd_ssize_t CONV_mpd_ssize_t"iiOOii", - kwlist, - &t.prec, &t.emin, &t.emax, &t.round, &capitals, - &traps, &status, &t.clamp, &t.allcr + "|" CONV_mpd_ssize_t "i" CONV_mpd_ssize_t CONV_mpd_ssize_t "ii" + "OOi", kwlist, + &t.prec, &t.round, &t.emin, &t.emax, &capitals, &t.clamp, + &status, &traps, &t.allcr )) { return -1; } @@ -1193,7 +1221,7 @@ PyErr_SetString(PyExc_ValueError, "invalid value for capitals"); return -1; } - ((PyDecContextObject *)self)->capitals = capitals; + CtxCaps(self) = capitals; if (traps != NULL) { if (PyLong_Check(traps)) { @@ -1221,7 +1249,7 @@ return 0; } -#define FD_CTX_LEN 640 +#define FD_CTX_LEN 400 static PyObject * context_repr(PyDecContextObject *self) { @@ -1235,32 +1263,97 @@ cp = s; mem = FD_CTX_LEN; n = snprintf(cp, mem, - "Context(prec=%"PRI_mpd_ssize_t", Emin=%"PRI_mpd_ssize_t"" - ", Emax=%"PRI_mpd_ssize_t", rounding=%s, capitals=%d, traps=", - ctx->prec, ctx->emin, ctx->emax, mpd_round_string[ctx->round], - self->capitals); - if (n < 0 || n >= mem) return NULL; + "Context(prec=%"PRI_mpd_ssize_t", rounding=%s, " + "Emin=%"PRI_mpd_ssize_t", Emax=%"PRI_mpd_ssize_t", " + "capitals=%d, clamp=%d, flags=", + ctx->prec, mpd_round_string[ctx->round], + ctx->emin, ctx->emax, + self->capitals, ctx->clamp); + if (n < 0 || n >= mem) goto error; cp += n; mem -= n; - n = mpd_lsnprint_signals(cp, mem, ctx->traps, dec_signal_string); - if (n < 0 || n >= mem) return NULL; + n = mpd_lsnprint_signals(cp, mem, ctx->status, dec_signal_string); + if (n < 0 || n >= mem) goto error; cp += n; mem -= n; - n = snprintf(cp, mem, ", flags="); - if (n < 0 || n >= mem) return NULL; + n = snprintf(cp, mem, ", traps="); + if (n < 0 || n >= mem) goto error; cp += n; mem -= n; - n = mpd_lsnprint_signals(cp, mem, ctx->status, dec_signal_string); - if (n < 0 || n >= mem) return NULL; + n = mpd_lsnprint_signals(cp, mem, ctx->traps, dec_signal_string); + if (n < 0 || n >= mem) goto error; cp += n; mem -= n; n = snprintf(cp, mem, ")"); - if (n < 0 || n >= mem) return NULL; + if (n < 0 || n >= mem) goto error; return PyUnicode_FromString(s); + +error: + PyErr_SetString(PyExc_RuntimeError, "internal error in context_repr"); + return NULL; +} + +static void +init_basic_context(PyObject *v) +{ + mpd_context_t ctx = dflt_ctx; + + ctx.prec = 9; + ctx.traps |= (MPD_Underflow|MPD_Clamped); + ctx.round = MPD_ROUND_HALF_UP; + + *CtxAddr(v) = ctx; + CtxCaps(v) = 1; +} + +static void +init_extended_context(PyObject *v) +{ + mpd_context_t ctx = dflt_ctx; + + ctx.prec = 9; + ctx.traps = 0; + + *CtxAddr(v) = ctx; + CtxCaps(v) = 1; +} + +/* Factory function for creating IEEE interchange format contexts */ +static PyObject * +ieee_context(PyObject *dummy UNUSED, PyObject *v) +{ + PyObject *ctxobj; + mpd_ssize_t bits; + mpd_context_t ctx; + + bits = PyLong_AsMpdSsize(v); + if (PyErr_Occurred()) { + return NULL; + } + if (bits <= 0 || bits > INT_MAX) { + goto error; + } + if (mpd_ieee_context(&ctx, (int)bits) < 0) { + goto error; + } + + ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); + if (ctxobj == NULL) { + return NULL; + } + *CtxAddr(ctxobj) = ctx; + + return ctxobj; + +error: + PyErr_Format(PyExc_ValueError, + "argument must be a multiple of 32, with a maximum of %d", + MPD_IEEE_CONTEXT_MAX_BITS + ); + return NULL; } -/* New copy with all settings except the status */ static PyObject * context_copy(PyObject *self) { @@ -1275,10 +1368,8 @@ ctx = CtxAddr(newob); *ctx = *CtxAddr(self); - ctx->status = 0; ctx->newtrap = 0; - ((PyDecContextObject *)newob)->capitals = - ((PyDecContextObject *)self)->capitals; + CtxCaps(newob) = CtxCaps(self); return newob; } @@ -1289,11 +1380,10 @@ mpd_context_t *ctx = CtxAddr(self); return Py_BuildValue( - "O("CONV_mpd_ssize_t CONV_mpd_ssize_t CONV_mpd_ssize_t \ - "iiiiii)", - Py_TYPE(self), ctx->prec, ctx->emin, ctx->emax, - ctx->round, ((PyDecContextObject *)self)->capitals, - ctx->traps, ctx->status, ctx->clamp, ctx->allcr + "O(" CONV_mpd_ssize_t "i" CONV_mpd_ssize_t CONV_mpd_ssize_t + "iiiii)", + Py_TYPE(self), ctx->prec, ctx->round, ctx->emin, ctx->emax, + CtxCaps(self), ctx->clamp, ctx->status, ctx->traps, ctx->allcr ); } @@ -1305,6 +1395,7 @@ { "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL}, { "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL}, { "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL}, + { "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL}, { "_clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL}, { "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL}, { "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL}, @@ -1332,214 +1423,254 @@ /* Global, thread local and temporary contexts */ /******************************************************************************/ +#ifdef WITHOUT_THREADS +/* Return borrowed reference to the current context. When compiled + * without threads, this is always the module context. */ +static int module_context_set = 0; +static PyObject * +current_context(void) +{ + /* In decimal.py, the module context is automatically initialized + * from the DefaultContext when it is first accessed. This + * complicates the code and has a speed penalty of 1-2%. */ + if (module_context_set) { + return module_context; + } -#ifndef USE_THREAD_LOCAL_STORAGE /* Recommended: No TLS */ -/* Internal: return borrowed reference to default context object */ -static inline PyObject * -dflt_ctx(void) -{ + *CtxAddr(module_context) = *CtxAddr(default_context_template); + module_context_set = 1; return module_context; } -/* Internal: set default context, preserve old reference */ -static inline PyObject * -set_dflt_ctx(PyObject *obj) -{ - module_context = obj; - return Py_None; -} +/* ctxobj := borrowed reference to the current context */ +#define CURRENT_CONTEXT(ctxobj) \ + ctxobj = current_context() -/* Internal: return convenience pointer to raw default context */ -static inline mpd_context_t * -mpd_ctx(void) -{ - return CtxAddr(module_context); -} +/* ctx := pointer to the mpd_context_t struct of the current context */ +#define CURRENT_CONTEXT_ADDR(ctx) \ + ctx = CtxAddr(current_context()) -/* Return context object, increment reference */ +/* Return current context, increment reference */ static PyObject * -PyDec_GetDefaultContext(void) +PyDec_GetCurrentContext(void) { - Py_INCREF(module_context); - return module_context; + PyObject *ctxobj; + + CURRENT_CONTEXT(ctxobj); + + Py_INCREF(ctxobj); + return ctxobj; } -/* Set the module context to a new context object */ +/* Set the module context to a new context, decrement old reference */ static PyObject * -PyDec_SetDefaultContext(PyObject *self UNUSED, PyObject *obj) +PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) { - CONTEXT_CHECK(obj); + CONTEXT_CHECK(v); + + /* If the new context is one of the templates, make a copy. + * This is the current behavior of decimal.py. */ + if (v == default_context_template || + v == basic_context_template || + v == extended_context_template) { + if ((v = context_copy(v)) == NULL) { + return NULL; + } + } + else { + Py_INCREF(v); + } Py_DECREF(module_context); - module_context = obj; - Py_INCREF(module_context); + module_context = v; + module_context_set = 1; Py_RETURN_NONE; } #else /* - * Thread local storage for the context is not a good idea. All functions - * that map Python's arithmetic operators to mpdecimal functions have to - * look up the default context for each and every operation. This is more - * than twice as slow as using the module context. - * - * This section is here for compatibility with decimal.py, but compiling - * with USE_THREAD_LOCAL_STORAGE is strongly discouraged. - * - * If you need threads in your application, simply create a context for - * each thread and only use the functions that accept a context parameter. + * Thread local storage currently has a speed penalty of about 16%. + * All functions that map Python's arithmetic operators to mpdecimal + * functions have to look up the current context for each and every + * operation. */ -/* Internal: return borrowed reference to thread local default context object */ +/* Return borrowed reference to thread local context. */ static PyObject * -dflt_ctx(void) +current_context(void) { - PyObject *obj = NULL; + PyObject *dict = NULL; + PyObject *tl_context = NULL; - if ((obj = PyObject_GetAttrString(tls, "default_context")) != NULL) { - /* We already have a thread local context and return a - * borrowed reference. */ - assert(PyDecContext_Check(obj)); - Py_DECREF(obj); - return obj; + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, "cannot get thread state"); + return NULL; + } + + tl_context = PyDict_GetItem(dict, tls_context_key); + if (tl_context != NULL) { + /* We already have a thread local context and + * return a borrowed reference. */ + CONTEXT_CHECK(tl_context); + return tl_context; } - /* Otherwise, set the default context attribute */ - PyErr_Clear(); - if ((obj = (PyObject *)context_copy(module_context)) == NULL) { + /* Otherwise, set up a new thread local context. */ + tl_context = (PyObject *)context_copy(default_context_template); + if (tl_context == NULL) { return NULL; } - if (PyObject_SetAttrString(tls, "default_context", obj) == -1) { - Py_DECREF(obj); + if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) { + Py_DECREF(tl_context); return NULL; } - Py_DECREF(obj); + Py_DECREF(tl_context); /* refcount is 1 */ - return obj; + return tl_context; } -/* Internal: set thread local default context, preserve old reference */ -static PyObject * -set_dflt_ctx(PyObject *obj) -{ - /* Preserve a reference to the previous context. */ - Py_INCREF(dflt_ctx()); - /* This decrements the refcount of a previous context. */ - if (PyObject_SetAttrString(tls, "default_context", obj) == -1) { - return NULL; - } - return Py_None; -} - -/* Internal: return convenience pointer to thread local raw context */ -static mpd_context_t * -mpd_ctx(void) -{ - PyObject *obj; +/* ctxobj := borrowed reference to the current context */ +#define CURRENT_CONTEXT(ctxobj) \ + if ((ctxobj = current_context()) == NULL) { \ + return NULL; \ + } - if ((obj = dflt_ctx()) == NULL) { - /* XXX The alternative is to add even more error handling code - * to the arithmetic functions. This would punish users who do - * not use TLS. */ - mpd_err_fatal("Retrieving thread local context failed."); - /* Not reached */ - } - return CtxAddr(obj); +/* ctx := pointer to the mpd_context_t struct of the current context */ +#define CURRENT_CONTEXT_ADDR(ctx) { \ + PyObject *_c_t_x_o_b_j = current_context(); \ + if (_c_t_x_o_b_j == NULL) { \ + return NULL; \ + } \ + ctx = CtxAddr(_c_t_x_o_b_j); \ } -/* Return thread local default context object with incremented refcount */ +/* Return current context, increment reference */ static PyObject * -PyDec_GetDefaultContext(void) +PyDec_GetCurrentContext(void) { PyObject *obj; - if ((obj = dflt_ctx()) == NULL) { + if ((obj = current_context()) == NULL) { return NULL; } + Py_INCREF(obj); return obj; } -/* Set thread local context object */ +/* Set the thread local context to a new context, decrement old reference */ static PyObject * -PyDec_SetDefaultContext(PyObject *self UNUSED, PyObject *obj) +PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) { - CONTEXT_CHECK(obj); + PyObject *dict; + + CONTEXT_CHECK(v); + + dict = PyThreadState_GetDict(); + if (dict == NULL) { + PyErr_SetString(PyExc_RuntimeError, "cannot get thread state"); + return NULL; + } + + /* If the new context is one of the templates, make a copy. + * This is the current behavior of decimal.py. */ + if (v == default_context_template || + v == basic_context_template || + v == extended_context_template) { + if ((v = context_copy(v)) == NULL) { + return NULL; + } + } + else { + Py_INCREF(v); + } - /* This clears one reference to a previous context. */ - if (PyObject_SetAttrString(tls, "default_context", obj) == -1) { + if (PyDict_SetItem(dict, tls_context_key, v) < 0) { return NULL; } + Py_DECREF(v); Py_RETURN_NONE; } #endif - -/* For the "with" statement: return a context manager object */ +/* Context manager object for the 'with' statement. The manager + * owns one reference to the global (outer) context and one + * to the local (inner) context. */ static PyObject * -ctxmanager_new(PyObject *self UNUSED, PyObject *args) +ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args) { - PyDecContextManagerObject *ctx_mgr; - PyObject *src; - - src = dflt_ctx(); - if (!PyArg_ParseTuple(args, "|O", &src)) { - return NULL; - } - CONTEXT_CHECK_VA(src); + PyDecContextManagerObject *self; + PyObject *local; + PyObject *global; - ctx_mgr = PyObject_New(PyDecContextManagerObject, - &PyDecContextManager_Type); - if (ctx_mgr == NULL) { + CURRENT_CONTEXT(global); + local = global; + if (!PyArg_ParseTuple(args, "|O", &local)) { return NULL; } + CONTEXT_CHECK_VA(local); - ctx_mgr->local = context_copy(src); - if (ctx_mgr->local == NULL) { - Py_DECREF(ctx_mgr); + self = PyObject_New(PyDecContextManagerObject, + &PyDecContextManager_Type); + if (self == NULL) { return NULL; } - ctx_mgr->global = dflt_ctx(); - if (ctx_mgr->global == NULL) { - Py_DECREF(ctx_mgr->local); - Py_DECREF(ctx_mgr); + self->local = context_copy(local); + if (self->local == NULL) { + Py_DECREF(self); return NULL; } + self->global = global; + Py_INCREF(self->global); - return (PyObject *)ctx_mgr; + return (PyObject *)self; } static void -ctxmanager_dealloc(PyDecContextObject *self) +ctxmanager_dealloc(PyDecContextManagerObject *self) { + Py_DECREF(self->local); + Py_DECREF(self->global); PyObject_Del(self); } static PyObject * ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED) { - if (set_dflt_ctx(self->local) == NULL) { + PyObject *ret; + + ret = PyDec_SetCurrentContext(NULL, self->local); + if (ret == NULL) { return NULL; } - return (PyObject *)self->local; + Py_DECREF(ret); + + Py_INCREF(self->local); + return self->local; } static PyObject * -ctxmanager_restore_default(PyDecContextManagerObject *self, +ctxmanager_restore_global(PyDecContextManagerObject *self, PyObject *args UNUSED) { - if (set_dflt_ctx(self->global) == NULL) { + PyObject *ret; + + ret = PyDec_SetCurrentContext(NULL, self->global); + if (ret == NULL) { return NULL; } - return Dec_INCREF_FALSE; + Py_DECREF(ret); + + Py_RETURN_NONE; } static PyMethodDef ctxmanager_methods[] = { {"__enter__", (PyCFunction)ctxmanager_set_local, METH_NOARGS, NULL}, - {"__exit__", (PyCFunction)ctxmanager_restore_default, METH_VARARGS, NULL}, + {"__exit__", (PyCFunction)ctxmanager_restore_global, METH_VARARGS, NULL}, {NULL, NULL} }; @@ -1841,9 +1972,8 @@ /* Caller guarantees types. */ static PyObject * -_PyDec_FromTuple_Max(PyObject *v, mpd_context_t *ctx) +string_from_tuple(PyObject *v) { - PyObject *result; PyObject *tmp, *dtuple; char *decstring, *cp; char sign_special[6]; @@ -1875,27 +2005,21 @@ tmp = PyTuple_GET_ITEM(v, 2); if (PyUnicode_Check(tmp)) { - tmp = PyUnicode_AsASCIIString(tmp); - if (tmp == NULL) { - return NULL; - } - if (strcmp(PyBytes_AS_STRING(tmp), "F") == 0) { + if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) { strcat(sign_special, "Inf"); } - else if (strcmp(PyBytes_AS_STRING(tmp), "n") == 0) { + else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) { strcat(sign_special, "NaN"); } - else if (strcmp(PyBytes_AS_STRING(tmp), "N") == 0) { + else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) { strcat(sign_special, "sNaN"); } else { - Py_DECREF(tmp); PyErr_SetString(PyExc_ValueError, "string argument in the third position " "must be 'F', 'n' or 'N'"); return NULL; } - Py_DECREF(tmp); } else { exp = PyLong_AsMpdSsize(tmp); @@ -1956,12 +2080,37 @@ tmp = PyUnicode_FromString(decstring); PyMem_Free(decstring); - if (tmp == NULL) { + + return tmp; +} + +static PyObject * +_PyDec_FromTuple_Max(PyObject *v, mpd_context_t *ctx) +{ + PyObject *result; + PyObject *s; + + s = string_from_tuple(v); + if (s == NULL) { return NULL; } + result = _PyDec_FromUnicode_Max(s, ctx); + Py_DECREF(s); + return result; +} - result = _PyDec_FromUnicode_Max(tmp, ctx); - Py_DECREF(tmp); +static PyObject * +_PyDec_FromTuple(PyObject *v, mpd_context_t *ctx) +{ + PyObject *result; + PyObject *s; + + s = string_from_tuple(v); + if (s == NULL) { + return NULL; + } + result = _PyDec_FromUnicode(s, ctx); + Py_DECREF(s); return result; } @@ -1997,7 +2146,7 @@ PyObject *ctxobj; mpd_context_t *ctx; - ctxobj = dflt_ctx(); + CURRENT_CONTEXT(ctxobj); if (!PyArg_ParseTuple(args, "|O", &ctxobj)) { return NULL; } @@ -2137,14 +2286,15 @@ static PyObject * dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds UNUSED) { - PyObject *v = NULL, *ctxobj = NULL; + PyObject *v = NULL; + PyObject *ctxobj; mpd_context_t *ctx; if (type != &PyDec_Type) { return dec_subtype_new(type, args, kwds); } - ctxobj = dflt_ctx(); + CURRENT_CONTEXT(ctxobj); if (!PyArg_ParseTuple(args, "|OO", &v, &ctxobj)) { return NULL; } @@ -2232,12 +2382,7 @@ return _PyDec_FromLong(v, ctx); } else if (PyTuple_Check(v)) { - PyObject *tmp; - tmp = _PyDec_FromTuple_Max(v, ctx); - if (tmp == NULL) return NULL; - v = dec_apply(tmp, ctx); - Py_DECREF(tmp); - return v; + return _PyDec_FromTuple(v, ctx); } else { PyErr_Format(PyExc_TypeError, "conversion from %s to Decimal is" @@ -2256,11 +2401,12 @@ int sign; mpd_t *d1, *d2; uint32_t status = 0; - mpd_context_t maxctx; + mpd_context_t *ctx, maxctx; + CURRENT_CONTEXT_ADDR(ctx); if (PyLong_Check(v)) { - return _PyDec_FromLong_Max(v, mpd_ctx()); + return _PyDec_FromLong_Max(v, ctx); } x = PyFloat_AsDouble(v); @@ -2329,7 +2475,7 @@ mpd_qset_uint(d1, 5, &maxctx, &status); mpd_qset_ssize(d2, k, &maxctx, &status); mpd_qpow(d1, d1, d2, &maxctx, &status); - if (dec_addstatus(mpd_ctx(), status)) { + if (dec_addstatus(ctx, status)) { mpd_del(d1); mpd_del(d2); Py_DECREF(n_d); @@ -2350,7 +2496,7 @@ mpd_qmul(DecAddr(result), DecAddr(result), d1, &maxctx, &status); mpd_del(d1); mpd_del(d2); - if (dec_addstatus(mpd_ctx(), status)) { + if (dec_addstatus(ctx, status)) { Py_DECREF(result); return NULL; } @@ -2466,7 +2612,10 @@ static PyObject * PyLong_FromDec(PyDecObject *self) { - return _PyInt_FromDec(self, mpd_ctx(), MPD_ROUND_DOWN); + mpd_context_t *ctx; + + CURRENT_CONTEXT_ADDR(ctx); + return _PyInt_FromDec(self, ctx, MPD_ROUND_DOWN); } /* Caller guarantees type */ @@ -2480,7 +2629,10 @@ static PyObject * PyDec_Trunc(PyObject *self, PyObject *dummy UNUSED) { - return _PyInt_FromDec((PyDecObject *)self, mpd_ctx(), MPD_ROUND_DOWN); + mpd_context_t *ctx; + + CURRENT_CONTEXT_ADDR(ctx); + return _PyInt_FromDec((PyDecObject *)self, ctx, MPD_ROUND_DOWN); } static PyObject * @@ -2488,19 +2640,19 @@ { static char *kwlist[] = {"rounding", "context", NULL}; PyDecObject *result; - PyObject *dctx; + PyObject *ctxobj; int round = -1; mpd_context_t *ctx, workctx; uint32_t status = 0; assert(PyTuple_Check(args)); - dctx = dflt_ctx(); + CURRENT_CONTEXT(ctxobj); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", - kwlist, &round, &dctx)) { + kwlist, &round, &ctxobj)) { return NULL; } - if (!PyDecContext_Check(dctx)) { + if (!PyDecContext_Check(ctxobj)) { PyErr_SetString(PyExc_TypeError, "optional second arg must be a context"); return NULL; @@ -2509,7 +2661,7 @@ return NULL; } - ctx = CtxAddr(dctx); + ctx = CtxAddr(ctxobj); workctx = *ctx; if (round >= 0) { workctx.round = round; @@ -2529,19 +2681,19 @@ { static char *kwlist[] = {"rounding", "context", NULL}; PyDecObject *result; - PyObject *dctx; + PyObject *ctxobj; int round = -1; mpd_context_t *ctx, workctx; uint32_t status = 0; assert(PyTuple_Check(args)); - dctx = dflt_ctx(); + CURRENT_CONTEXT(ctxobj); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", - kwlist, &round, &dctx)) { + kwlist, &round, &ctxobj)) { return NULL; } - if (!PyDecContext_Check(dctx)) { + if (!PyDecContext_Check(ctxobj)) { PyErr_SetString(PyExc_TypeError, "optional second arg must be a context"); return NULL; @@ -2550,7 +2702,7 @@ return NULL; } - ctx = CtxAddr(dctx); + ctx = CtxAddr(ctxobj); workctx = *ctx; if (round >= 0) { workctx.round = round; @@ -2664,8 +2816,8 @@ PyObject *s, *c; char *res; - c = dflt_ctx(); - res = mpd_to_sci(self->dec, ((PyDecContextObject *)c)->capitals); + CURRENT_CONTEXT(c); + res = mpd_to_sci(self->dec, CtxCaps(c)); if (res == NULL) { PyErr_NoMemory(); return NULL; @@ -2689,8 +2841,8 @@ char *cp; size_t declen; - c = dflt_ctx(); - cp = mpd_to_sci(self->dec, ((PyDecContextObject *)c)->capitals); + CURRENT_CONTEXT(c); + cp = mpd_to_sci(self->dec, CtxCaps(c)); if (cp == NULL) { PyErr_NoMemory(); return NULL; @@ -2742,12 +2894,12 @@ uint32_t status = 0; mpd_context_t *ctx; + + CURRENT_CONTEXT_ADDR(ctx); if (!PyArg_ParseTuple(args, "|O", &x)) { return NULL; } - ctx = mpd_ctx(); - if (x) { mpd_uint_t dq[1] = {1}; mpd_t q = {MPD_STATIC|MPD_CONST_DATA,0,1,1,1,dq}; @@ -2791,6 +2943,7 @@ PyObject *grouping = NULL; PyObject *fmtarg, *fmt; PyObject *tmp; + PyObject *ctxobj; mpd_spec_t spec; wchar_t buf[2]; char *decstring= NULL; @@ -2798,6 +2951,7 @@ size_t n; + CURRENT_CONTEXT(ctxobj); if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) { return NULL; } @@ -2816,7 +2970,8 @@ return NULL; } - if (!mpd_parse_fmt_str(&spec, PyBytes_AS_STRING(fmt))) { + if (!mpd_parse_fmt_str(&spec, PyBytes_AS_STRING(fmt), + CtxCaps(ctxobj))) { PyErr_SetString(PyExc_ValueError, "invalid format string"); goto finish; } @@ -2887,9 +3042,9 @@ } - decstring = mpd_qformat_spec(DecAddr(self), &spec, mpd_ctx(), &status); + decstring = mpd_qformat_spec(DecAddr(self), &spec, CtxAddr(ctxobj), &status); if (decstring == NULL) { - dec_addstatus(mpd_ctx(), status); + dec_addstatus(CtxAddr(ctxobj), status); goto finish; } result = PyUnicode_DecodeUTF8(decstring, strlen(decstring), NULL); @@ -2937,7 +3092,7 @@ PyObject *ctxobj; \ mpd_context_t *ctx; \ \ - ctxobj = dflt_ctx(); \ + CURRENT_CONTEXT(ctxobj); \ if (!PyArg_ParseTuple(args, "|O", &ctxobj)) { \ return NULL; \ } \ @@ -2959,11 +3114,11 @@ uint32_t status = 0; \ mpd_context_t *ctx; \ \ + CURRENT_CONTEXT_ADDR(ctx); \ if ((result = dec_alloc()) == NULL) { \ return NULL; \ } \ \ - ctx = mpd_ctx(); \ MPDFUNC(result->dec, a->dec, ctx, &status); \ if (dec_addstatus(ctx, status)) { \ Py_DECREF(result); \ @@ -2984,11 +3139,11 @@ uint32_t status = 0; \ mpd_context_t *ctx; \ \ + CURRENT_CONTEXT_ADDR(ctx); \ if ((result = dec_alloc()) == NULL) { \ return NULL; \ } \ \ - ctx = mpd_ctx(); \ MPDFUNC(result->dec, a->dec, ctx, &status); \ if (dec_addstatus(ctx, &status)) { \ Py_DECREF(result); \ @@ -3010,7 +3165,7 @@ uint32_t status = 0; \ mpd_context_t *ctx; \ \ - ctxobj = dflt_ctx(); \ + CURRENT_CONTEXT(ctxobj); \ if (!PyArg_ParseTuple(args, "|O", &ctxobj)) { \ return NULL; \ } \ @@ -3043,7 +3198,7 @@ uint32_t status = 0; \ mpd_context_t *ctx; \ \ - ctx = mpd_ctx(); \ + CURRENT_CONTEXT_ADDR(ctx); \ CONVERT_BINOP(v, w, &a, &b, ctx); \ \ if ((result = dec_alloc()) == NULL) { \ @@ -3075,7 +3230,7 @@ uint32_t status = 0; \ mpd_context_t *ctx; \ \ - ctxobj = dflt_ctx(); \ + CURRENT_CONTEXT(ctxobj); \ if (!PyArg_ParseTuple(args, "O|O", &w, &ctxobj)) { \ return NULL; \ } \ @@ -3113,7 +3268,7 @@ PyDecObject *result; \ mpd_context_t *ctx; \ \ - ctxobj = dflt_ctx(); \ + CURRENT_CONTEXT(ctxobj); \ if (!PyArg_ParseTuple(args, "O|O", &w, &ctxobj)) { \ return NULL; \ } \ @@ -3149,7 +3304,7 @@ uint32_t status = 0; \ mpd_context_t *ctx; \ \ - ctxobj = dflt_ctx(); \ + CURRENT_CONTEXT(ctxobj); \ if (!PyArg_ParseTuple(args, "OO|O", &w, &x, &ctxobj)) { \ return NULL; \ } \ @@ -3223,7 +3378,7 @@ uint32_t status = 0; mpd_context_t *ctx; - ctx = mpd_ctx(); + CURRENT_CONTEXT_ADDR(ctx); CONVERT_BINOP(v, w, &a, &b, ctx); if ((q = dec_alloc()) == NULL) { @@ -3258,7 +3413,7 @@ uint32_t status = 0; mpd_context_t *ctx; - ctx = mpd_ctx(); + CURRENT_CONTEXT_ADDR(ctx); CONVERT_BINOP(base, exp, &a, &b, ctx); if (mod != Py_None) { @@ -3350,13 +3505,15 @@ PyDecObject *a = (PyDecObject *) self; PyDecObject *result; uint32_t status = 0; + mpd_context_t *ctx; + CURRENT_CONTEXT_ADDR(ctx); if ((result = dec_alloc()) == NULL) { return NULL; } mpd_qcopy_abs(result->dec, a->dec, &status); - if (dec_addstatus(mpd_ctx(), status)) { + if (dec_addstatus(ctx, status)) { Py_DECREF(result); return NULL; } @@ -3370,13 +3527,15 @@ PyDecObject *a = (PyDecObject *) self; PyDecObject *result; uint32_t status = 0; + mpd_context_t *ctx; + CURRENT_CONTEXT_ADDR(ctx); if ((result = dec_alloc()) == NULL) { return NULL; } mpd_qcopy_negate(result->dec, a->dec, &status); - if (dec_addstatus(mpd_ctx(), status)) { + if (dec_addstatus(ctx, status)) { Py_DECREF(result); return NULL; } @@ -3398,7 +3557,7 @@ uint32_t status = 0; mpd_context_t *ctx; - ctx = mpd_ctx(); + CURRENT_CONTEXT_ADDR(ctx); CONVERT_BINOP_SET(v, w, &a, &b, ctx); if ((result = dec_alloc()) == NULL) { @@ -3434,7 +3593,7 @@ mpd_context_t *ctx; const char *cp; - ctxobj = dflt_ctx(); + CURRENT_CONTEXT(ctxobj); if (!PyArg_ParseTuple(args, "|O", &ctxobj)) { return NULL; } @@ -3469,7 +3628,7 @@ uint32_t status = 0; mpd_context_t *ctx; - ctxobj = dflt_ctx(); + CURRENT_CONTEXT(ctxobj); if (!PyArg_ParseTuple(args, "O|O", &w, &ctxobj)) { return NULL; } @@ -3516,7 +3675,7 @@ PyDecObject *a, *b; mpd_context_t *ctx; - ctxobj = dflt_ctx(); + CURRENT_CONTEXT(ctxobj); if (!PyArg_ParseTuple(args, "O|O", &w, &ctxobj)) { return NULL; } @@ -3549,13 +3708,13 @@ PyObject *result, *c; char *s; - c = dflt_ctx(); + CURRENT_CONTEXT(c); if (!PyArg_ParseTuple(args, "|O", &c)) { return NULL; } CONTEXT_CHECK_VA(c); - s = mpd_to_sci(a->dec, ((PyDecContextObject *)c)->capitals); + s = mpd_to_sci(a->dec, CtxCaps(c)); if (s == NULL) { PyErr_NoMemory(); return NULL; @@ -3574,13 +3733,13 @@ PyObject *result, *c; char *s; - c = dflt_ctx(); + CURRENT_CONTEXT(c); if (!PyArg_ParseTuple(args, "|O", &c)) { return NULL; } CONTEXT_CHECK_VA(c); - s = mpd_to_eng(a->dec, ((PyDecContextObject *)c)->capitals); + s = mpd_to_eng(a->dec, CtxCaps(c)); if (s == NULL) { PyErr_NoMemory(); return NULL; @@ -3596,13 +3755,13 @@ dec_richcompare(PyObject *v, PyObject *w, int op) { PyDecObject *a = (PyDecObject *)v; - PyDecObject *b; + PyDecObject *b; uint32_t status = 0; mpd_context_t *ctx; int a_issnan, b_issnan; int r; - ctx = mpd_ctx(); + CURRENT_CONTEXT_ADDR(ctx); CONVERT_BINOP(v, w, &a, &b, ctx); a_issnan = mpd_issnan(a->dec); @@ -3670,7 +3829,7 @@ mpd_t *tmp = NULL; char *cp = NULL; uint32_t status = 0; - mpd_context_t maxcontext, *ctx; + mpd_context_t maxcontext; long result; if ((a = dec_alloc()) == NULL) { @@ -3701,11 +3860,15 @@ result = 0; } else if (mpd_isinteger(a->dec)) { - + PyObject *ctxobj = current_context(); + mpd_context_t *ctx; + if (ctxobj == NULL) { + result = -1; + goto finish; + } + ctx = CtxAddr(ctxobj); mpd_maxcontext(&maxcontext); - ctx = mpd_ctx(); -#if PY_VERSION_HEX >= 0x02060000 if ((tmp = mpd_qnew()) == NULL) { PyErr_NoMemory(); result = -1; @@ -3725,7 +3888,6 @@ goto finish; } } -#endif if ((obj = PyLong_FromDecCtx(a, &maxcontext)) == NULL) { result = -1; @@ -4402,7 +4564,7 @@ ctx = CtxAddr(self); CONVERT_OP_SET(v, &a, ctx); - s = mpd_to_sci(a->dec, ((PyDecContextObject *)self)->capitals); + s = mpd_to_sci(a->dec, CtxCaps(self)); Py_DECREF(a); if (s == NULL) { PyErr_NoMemory(); @@ -4426,7 +4588,7 @@ ctx = CtxAddr(self); CONVERT_OP_SET(v, &a, ctx); - s = mpd_to_eng(a->dec, ((PyDecContextObject *)self)->capitals); + s = mpd_to_eng(a->dec, CtxCaps(self)); Py_DECREF(a); if (s == NULL) { PyErr_NoMemory(); @@ -4628,9 +4790,10 @@ static PyMethodDef cdecimal_methods [] = { - { "getcontext", (PyCFunction)PyDec_GetDefaultContext, METH_NOARGS, doc_getcontext}, - { "setcontext", (PyCFunction)PyDec_SetDefaultContext, METH_O, doc_setcontext}, + { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext}, + { "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext}, { "localcontext", (PyCFunction)ctxmanager_new, METH_VARARGS, doc_localcontext}, + { "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context}, { NULL, NULL, 1, NULL } }; @@ -4654,6 +4817,7 @@ PyObject *_numbers = NULL; PyObject *_Number = NULL; PyObject *obj, *ret, *s; + PyObject *ctxobj; DecCondMap *cm; @@ -4712,28 +4876,6 @@ Py_DECREF(obj); Py_DECREF(ret); - -#ifdef USE_THREAD_LOCAL_STORAGE /* not recommended */ -{ - PyObject *_thread; - PyObject *_local; - if ((_thread = PyImport_ImportModule("_thread")) == NULL) { - goto error; - } - if ((_local = PyObject_GetAttrString(_thread, "_local")) == NULL) { - goto error; - } - if ((tls = PyObject_CallObject(_local, NULL)) == NULL) { - Py_DECREF(_thread); - Py_DECREF(_local); - goto error; - } - Py_DECREF(_thread); - Py_DECREF(_local); -} -#endif - - if ((m = PyModule_Create(&cdecimal_module)) == NULL) { goto error; } @@ -4744,11 +4886,11 @@ mpd_callocfunc = mpd_callocfunc_em; mpd_free = PyMem_Free; - Py_INCREF(&PyDec_Type); - PyModule_AddObject(m, "Decimal", (PyObject *)&PyDec_Type); + Py_INCREF(&PyDec_Type); + PyModule_AddObject(m, "Decimal", (PyObject *)&PyDec_Type); - Py_INCREF(&PyDecContext_Type); - PyModule_AddObject(m, "Context", (PyObject *)&PyDecContext_Type); + Py_INCREF(&PyDecContext_Type); + PyModule_AddObject(m, "Context", (PyObject *)&PyDecContext_Type); /* Top level Exception */ @@ -4772,7 +4914,7 @@ */ cond_map[0].dec_cond = signal_map[0].dec_cond; - /* Remaining exceptions, inherit from the InvalidOperation */ + /* Remaining exceptions, inherit from InvalidOperation */ for (cm = cond_map+1; cm->name != NULL; cm++) { cm->dec_cond = PyErr_NewException((char *)cm->fqname, signal_map[0].dec_cond , NULL); @@ -4781,35 +4923,53 @@ } - /* Module default context and template for local and - * thread local contexts */ - module_context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); - if (module_context == NULL) { + /* MPD_MINALLOC */ + mpd_setminalloc(4); + + /* Default context template */ + ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); + if (ctxobj == NULL) { goto error; } - mpd_init(CtxAddr(module_context), 28); - CtxAddr(module_context)->traps &= ~MPD_Underflow; /* XXX */ - Py_INCREF(module_context); - PyModule_AddObject(m, "DefaultContext", (PyObject *)module_context); - - /* Basic context */ - basic_context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); - if (basic_context == NULL) { + default_context_template = ctxobj; + Py_INCREF(ctxobj); + PyModule_AddObject(m, "DefaultContext", ctxobj); + +#ifdef WITHOUT_THREADS + /* Module context */ + ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); + if (ctxobj == NULL) { goto error; } - mpd_basiccontext(CtxAddr(basic_context)); - Py_INCREF(basic_context); - PyModule_AddObject(m, "BasicContext", (PyObject *)basic_context); - - /* Extended context */ - ext_context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); - if (ext_context == NULL) { + module_context = ctxobj; + PyModule_AddIntConstant(m, "HAVE_THREADS", 0); +#else + tls_context_key = Py_BuildValue("s", "__CDECIMAL_CTX__"); + if (tls_context_key == NULL) { goto error; } - mpd_extcontext(CtxAddr(ext_context)); - Py_INCREF(ext_context); - PyModule_AddObject(m, "ExtendedContext", (PyObject *)ext_context); + PyModule_AddIntConstant(m, "HAVE_THREADS", 1); +#endif + /* Basic context template */ + ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); + if (ctxobj == NULL) { + goto error; + } + init_basic_context(ctxobj); + basic_context_template = ctxobj; + Py_INCREF(ctxobj); + PyModule_AddObject(m, "BasicContext", ctxobj); + + /* Extended context template */ + ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL); + if (ctxobj == NULL) { + goto error; + } + init_extended_context(ctxobj); + extended_context_template = ctxobj; + Py_INCREF(ctxobj); + PyModule_AddObject(m, "ExtendedContext", ctxobj); /* Useful constants */ @@ -4818,6 +4978,11 @@ PyModule_AddObject(m, "MIN_EMIN", Py_BuildValue(CONV_mpd_ssize_t, MPD_MIN_EMIN)); PyModule_AddObject(m, "MIN_ETINY", Py_BuildValue(CONV_mpd_ssize_t, MPD_MIN_ETINY)); + PyModule_AddIntConstant(m, "DECIMAL32", MPD_DECIMAL32); + PyModule_AddIntConstant(m, "DECIMAL64", MPD_DECIMAL64); + PyModule_AddIntConstant(m, "DECIMAL128", MPD_DECIMAL128); + PyModule_AddIntConstant(m, "IEEE_CONTEXT_MAX_BITS", MPD_IEEE_CONTEXT_MAX_BITS); + PyModule_AddIntConstant(m, "ROUND_CEILING", MPD_ROUND_CEILING); PyModule_AddIntConstant(m, "ROUND_FLOOR", MPD_ROUND_FLOOR); PyModule_AddIntConstant(m, "ROUND_UP", MPD_ROUND_UP); @@ -4851,14 +5016,17 @@ return m; - error: - if (tls) Py_DECREF(tls); if (_numbers) Py_DECREF(_numbers); if (_Number) Py_DECREF(_Number); +#ifdef WITHOUT_THREADS if (module_context) Py_DECREF(module_context); - if (basic_context) Py_DECREF(basic_context); - if (ext_context) Py_DECREF(ext_context); +#else + if (default_context_template) Py_DECREF(default_context_template); + if (tls_context_key) Py_DECREF(tls_context_key); +#endif + if (basic_context_template) Py_DECREF(basic_context_template); + if (extended_context_template) Py_DECREF(extended_context_template); if (m) Py_DECREF(m); return NULL; From python-checkins at python.org Sat Jun 5 09:51:13 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 09:51:13 +0200 (CEST) Subject: [Python-checkins] r81715 - python/branches/py3k-cdecimal/Modules/cdecimal/context.c Message-ID: <20100605075113.3ADA8EE9A5@mail.python.org> Author: stefan.krah Date: Sat Jun 5 09:51:13 2010 New Revision: 81715 Log: Remove mpd_extcontext (only from the library) and add mpd_ieee_context. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/context.c Modified: python/branches/py3k-cdecimal/Modules/cdecimal/context.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/context.c (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/context.c Sat Jun 5 09:51:13 2010 @@ -19,7 +19,7 @@ void (* mpd_traphandler)(mpd_context_t *) = mpd_dflt_traphandler; -static void +void mpd_setminalloc(mpd_ssize_t n) { static int minalloc_is_set = 0; @@ -97,20 +97,25 @@ ctx->allcr=1; } -void -mpd_extcontext(mpd_context_t *ctx) +int +mpd_ieee_context(mpd_context_t *ctx, int bits) { - ctx->prec=9; - ctx->emax=MPD_MAX_EMAX; - ctx->emin=MPD_MIN_EMIN; + if (bits <= 0 || bits > MPD_IEEE_CONTEXT_MAX_BITS || bits % 32) { + return -1; + } + + ctx->prec = 9 * (bits/32) - 2; + ctx->emax = 3 * ((mpd_ssize_t)1<<(bits/16+3)); + ctx->emin = 1 - ctx->emax; ctx->round=MPD_ROUND_HALF_EVEN; ctx->traps=0; ctx->status=0; ctx->newtrap=0; - ctx->clamp=0; + ctx->clamp=1; ctx->allcr=1; -} + return 0; +} mpd_ssize_t mpd_getprec(const mpd_context_t *ctx) From python-checkins at python.org Sat Jun 5 09:54:56 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 09:54:56 +0200 (CEST) Subject: [Python-checkins] r81716 - python/branches/py3k-cdecimal/Modules/cdecimal/docstrings.h Message-ID: <20100605075456.1A5F8EE9CF@mail.python.org> Author: stefan.krah Date: Sat Jun 5 09:54:55 2010 New Revision: 81716 Log: 1) Document IEEEContext(). 2) Example code should pass doctests. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/docstrings.h Modified: python/branches/py3k-cdecimal/Modules/cdecimal/docstrings.h ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/docstrings.h (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/docstrings.h Sat Jun 5 09:54:55 2010 @@ -34,6 +34,13 @@ the current default context is used.\n\ \n"); +PyDoc_STRVAR(doc_ieee_context,"\n\ +IEEEContext(bits) - Return a context object initialized to the proper values for\n\ +one of the IEEE interchange formats. The argument must be a multiple of 32 and\n\ +less than IEEE_CONTEXT_MAX_BITS. For the most common values, the constants\n\ +DECIMAL32, DECIMAL64 and DECIMAL128 are provided.\n\ +\n"); + /******************************************************************************/ /* Decimal Object and Methods */ @@ -552,10 +559,11 @@ Over/Underflow, raising of exceptions and much more. A new context\n\ can be constructed as follows:\n\ \n\ - >>> c = Context(prec=28, Emin=-425000000, Emax=425000000, \n\ - rounding=ROUND_HALF_EVEN, capitals=1,\n\ - traps=[InvalidOperation, DivisionByZero, Overflow],\n\ - flags=[], _clamp=0, _allcr=1)\n\ + >>> c = Context(prec=28, Emin=-425000000, Emax=425000000,\n\ + ... rounding=ROUND_HALF_EVEN, capitals=1, clamp=1,\n\ + ... traps=[InvalidOperation, DivisionByZero, Overflow],\n\ + ... flags=[], _allcr=1)\n\ + >>>\n\ \n\ \n"); From python-checkins at python.org Sat Jun 5 09:59:37 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 09:59:37 +0200 (CEST) Subject: [Python-checkins] r81717 - python/branches/py3k-cdecimal/Modules/cdecimal/io.c Message-ID: <20100605075937.70102EE983@mail.python.org> Author: stefan.krah Date: Sat Jun 5 09:59:37 2010 New Revision: 81717 Log: 1) Take the default for 'capitals' from the current context. 2) Must use maxcontext. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/io.c Modified: python/branches/py3k-cdecimal/Modules/cdecimal/io.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/io.c (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/io.c Sat Jun 5 09:59:37 2010 @@ -665,7 +665,7 @@ } int -mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt) +mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps) { char *cp = (char *)fmt; int have_align = 0, n; @@ -673,7 +673,7 @@ /* defaults */ spec->min_width = 0; spec->prec = -1; - spec->type = 'G'; + spec->type = caps ? 'G' : 'g'; spec->align = '>'; spec->sign = '-'; spec->dot = ""; @@ -1081,8 +1081,8 @@ flags |= MPD_FMT_SIGN_PLUS; } - workctx = *ctx; - workctx.traps = workctx.status = 0; + mpd_maxcontext(&workctx); + workctx.round = ctx->round; if (mpd_isspecial(&tmp)) { /* no percent formatting */ flags |= MPD_FMT_TOSCI; @@ -1165,7 +1165,7 @@ { mpd_spec_t spec; - if (!mpd_parse_fmt_str(&spec, fmt)) { + if (!mpd_parse_fmt_str(&spec, fmt, 1)) { *status |= MPD_Invalid_operation; return NULL; } From python-checkins at python.org Sat Jun 5 10:07:35 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 10:07:35 +0200 (CEST) Subject: [Python-checkins] r81718 - python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h Message-ID: <20100605080735.63165EED55@mail.python.org> Author: stefan.krah Date: Sat Jun 5 10:07:35 2010 New Revision: 81718 Log: 1) Add constants for IEEE 754 interchange format contexts. 2) Export mpd_setminalloc(), add mpd_ieee_context(). Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h Sat Jun 5 10:07:35 2010 @@ -142,6 +142,12 @@ /* Official name */ #define MPD_Insufficient_storage MPD_Malloc_error + +/* IEEE 754 interchange format contexts */ +#define MPD_IEEE_CONTEXT_MAX_BITS 512 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */ +#define MPD_DECIMAL32 32 +#define MPD_DECIMAL64 64 +#define MPD_DECIMAL128 128 #define MPD_MINALLOC_MIN 2 @@ -149,12 +155,13 @@ extern mpd_ssize_t MPD_MINALLOC; extern void (* mpd_traphandler)(mpd_context_t *); +void mpd_setminalloc(mpd_ssize_t n); void mpd_init(mpd_context_t *ctx, mpd_ssize_t prec); void mpd_maxcontext(mpd_context_t *ctx); void mpd_defaultcontext(mpd_context_t *ctx); void mpd_basiccontext(mpd_context_t *ctx); -void mpd_extcontext(mpd_context_t *ctx); +int mpd_ieee_context(mpd_context_t *ctx, int bits); mpd_ssize_t mpd_getprec(const mpd_context_t *ctx); mpd_ssize_t mpd_getemax(const mpd_context_t *ctx); @@ -228,7 +235,7 @@ /* output to a string */ char *mpd_to_sci(const mpd_t *dec, int fmt); char *mpd_to_eng(const mpd_t *dec, int fmt); -int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt); +int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps); char * mpd_qformat_spec(const mpd_t *dec, mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status); char *mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, uint32_t *status); From ncoghlan at gmail.com Sat Jun 5 10:08:05 2010 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sat, 05 Jun 2010 18:08:05 +1000 Subject: [Python-checkins] r81706 - in python/trunk: Lib/test/test_descr.py Objects/abstract.c In-Reply-To: <20100605003251.2A9BCEECF3@mail.python.org> References: <20100605003251.2A9BCEECF3@mail.python.org> Message-ID: <4C0A05E5.3030105@gmail.com> On 05/06/10 10:32, benjamin.peterson wrote: > - /* Initialize cached value */ > - if (str__format__ == NULL) { > - /* Initialize static variable needed by _PyType_Lookup */ > - str__format__ = PyString_InternFromString("__format__"); > - if (str__format__ == NULL) > - goto done; > - } > - Why kill the microoptimisation here? Looking the string up in the intern dict every time (as these changes do) is a waste of cycles. Since avoiding it is pretty easy using this common idiom, it's generally worth doing. I suggest restoring the microoptimisation and then rewriting the _PyObject_LookupSpecial call to prepopulate the object: _PyObject_LookupSpecial(obj, NULL, str__format) Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From python-checkins at python.org Sat Jun 5 10:15:47 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 10:15:47 +0200 (CEST) Subject: [Python-checkins] r81719 - python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal64.h Message-ID: <20100605081547.DBC8EEEDCA@mail.python.org> Author: stefan.krah Date: Sat Jun 5 10:15:47 2010 New Revision: 81719 Log: 1) Add constants for IEEE 754 interchange format contexts. 2) Export mpd_setminalloc(), add mpd_ieee_context(). Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal64.h Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal64.h ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal64.h (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal64.h Sat Jun 5 10:15:47 2010 @@ -138,18 +138,25 @@ /* Official name */ #define MPD_Insufficient_storage MPD_Malloc_error +/* IEEE 754 interchange format contexts */ +#define MPD_IEEE_CONTEXT_MAX_BITS 512 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */ +#define MPD_DECIMAL32 32 +#define MPD_DECIMAL64 64 +#define MPD_DECIMAL128 128 + #define MPD_MINALLOC_MIN 2 #define MPD_MINALLOC_MAX 64 extern mpd_ssize_t MPD_MINALLOC; extern void (* mpd_traphandler)(mpd_context_t *); +void mpd_setminalloc(mpd_ssize_t n); void mpd_init(mpd_context_t *ctx, mpd_ssize_t prec); void mpd_maxcontext(mpd_context_t *ctx); void mpd_defaultcontext(mpd_context_t *ctx); void mpd_basiccontext(mpd_context_t *ctx); -void mpd_extcontext(mpd_context_t *ctx); +int mpd_ieee_context(mpd_context_t *ctx, int bits); mpd_ssize_t mpd_getprec(const mpd_context_t *ctx); mpd_ssize_t mpd_getemax(const mpd_context_t *ctx); @@ -223,7 +230,7 @@ /* output to a string */ char *mpd_to_sci(const mpd_t *dec, int fmt); char *mpd_to_eng(const mpd_t *dec, int fmt); -int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt); +int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps); char * mpd_qformat_spec(const mpd_t *dec, mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status); char *mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, uint32_t *status); From python-checkins at python.org Sat Jun 5 11:04:03 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 11:04:03 +0200 (CEST) Subject: [Python-checkins] r81720 - python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Message-ID: <20100605090403.2A170EEDEE@mail.python.org> Author: stefan.krah Date: Sat Jun 5 11:04:02 2010 New Revision: 81720 Log: 1) If clamp=1, the maximum payload length of a NaN is prec-1. 2) Change cutoff for Newton division. 3) _mpd_qbarrett_divmod should use MAX_EMAX, MIN_EMIN. 4) _mpd_qexp() and _mpd_qln(): Do not use all excess digits by default. Ziv's strategy for correct rounding increases the precision as needed. 5) context.clamp must be set to 0 in several intermediate calculations. 6) Check for v = 1 must happen in mpd_qln(). 7) Add skips for certain underflow in _mpd_qln(). 8) Add skips for certain overflow in mpd_qln() and mpd_qlog10(). Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Sat Jun 5 11:04:02 2010 @@ -42,7 +42,7 @@ #define ALWAYS_INLINE inline __attribute__ ((always_inline)) #endif -#define MPD_NEWTONDIV_CUTOFF (8*MPD_RDIGITS) +#define MPD_NEWTONDIV_CUTOFF 1024L #define MPD_NEW_STATIC(name, flags, exp, digits, len) \ mpd_uint_t name##_data[MPD_MINALLOC_MAX]; \ @@ -77,7 +77,7 @@ static inline void _mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); static void _mpd_qbarrett_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, - const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); + const mpd_t *b, uint32_t *status); static inline void _mpd_qpow_uint(mpd_t *result, mpd_t *base, mpd_uint_t exp, uint8_t resultsign, const mpd_context_t *ctx, uint32_t *status); @@ -731,14 +731,13 @@ _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS); len = (r == 0) ? len : len+1; - /* resize to fewer words cannot fail */ - mpd_qresize(result, len, &dummy); - if (r != 0) { result->data[len-1] %= mpd_pow10[r]; } len = _mpd_real_size(result->data, len); + /* resize to fewer words cannot fail */ + mpd_qresize(result, len, &dummy); result->len = len; mpd_setdigits(result); } @@ -749,31 +748,38 @@ /* * Cut off the most significant digits of a NaN payload so that the rest - * fits in ctx->prec. Cannot fail. + * fits in ctx->prec - ctx->clamp. Cannot fail. */ static void _mpd_fix_nan(mpd_t *result, const mpd_context_t *ctx) { uint32_t dummy; + mpd_ssize_t prec; mpd_ssize_t len, r; - if (result->len > 0 && result->digits > ctx->prec-ctx->clamp) { - _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS); - len = (r == 0) ? len : len+1; - - /* resize to fewer words cannot fail */ - mpd_qresize(result, len, &dummy); - - if (r != 0) { - result->data[len-1] %= mpd_pow10[r]; + prec = ctx->prec - ctx->clamp; + if (result->len > 0 && result->digits > prec) { + if (prec == 0) { + mpd_minalloc(result); + result->len = result->digits = 0; } + else { + _mpd_idiv_word(&len, &r, prec, MPD_RDIGITS); + len = (r == 0) ? len : len+1; - len = _mpd_real_size(result->data, len); - result->len = len; - mpd_setdigits(result); - if (mpd_iszerocoeff(result)) { - /* NaN0 is not a valid representation */ - result->len = result->digits = 0; + if (r != 0) { + result->data[len-1] %= mpd_pow10[r]; + } + + len = _mpd_real_size(result->data, len); + /* resize to fewer words cannot fail */ + mpd_qresize(result, len, &dummy); + result->len = len; + mpd_setdigits(result); + if (mpd_iszerocoeff(result)) { + /* NaN0 is not a valid representation */ + result->len = result->digits = 0; + } } } } @@ -1220,7 +1226,8 @@ *status |= MPD_Invalid_operation; return MPD_UINT_MAX; } - /* at this point a->digits+a->exp <= MPD_RDIGITS+1, so the shift fits */ + /* At this point a->digits+a->exp <= MPD_RDIGITS+1, + * so the shift fits. */ tmp.data = tmp_data; tmp.flags = MPD_STATIC|MPD_CONST_DATA; mpd_qsshiftr(&tmp, a, -a->exp); @@ -2486,6 +2493,7 @@ mpd_clear_flags(result); result->exp = 0; result->len = _mpd_real_size(result->data, len); + mpd_qresize(result, result->len, status); mpd_setdigits(result); _mpd_cap(result, ctx); return; @@ -2598,6 +2606,7 @@ mpd_clear_flags(result); result->exp = 0; result->len = _mpd_real_size(result->data, big->len); + mpd_qresize(result, result->len, status); mpd_setdigits(result); _mpd_cap(result, ctx); return; @@ -2890,6 +2899,7 @@ mpd_clear_flags(result); result->exp = 0; result->len = _mpd_real_size(result->data, big->len); + mpd_qresize(result, result->len, status); mpd_setdigits(result); _mpd_cap(result, ctx); return; @@ -3301,8 +3311,8 @@ if (b->len == 1) { rem = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]); } - else if (ctx->prec < MPD_NEWTONDIV_CUTOFF || - b->digits < MPD_NEWTONDIV_CUTOFF) { + else if (a->len < 2*MPD_NEWTONDIV_CUTOFF && + b->len < MPD_NEWTONDIV_CUTOFF) { int ret = _mpd_basedivmod(q->data, NULL, a->data, b->data, a->len, b->len); if (ret < 0) { @@ -3313,7 +3323,7 @@ } else { MPD_NEW_STATIC(r,0,0,0,0); - _mpd_qbarrett_divmod(q, &r, a, b, ctx, status); + _mpd_qbarrett_divmod(q, &r, a, b, status); rem = !mpd_iszerocoeff(&r); mpd_del(&r); newsize = q->len; @@ -3457,8 +3467,8 @@ r->data[0] = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]); } } - else if (ctx->prec < MPD_NEWTONDIV_CUTOFF || - b->digits < MPD_NEWTONDIV_CUTOFF) { + else if (a->len < 2*MPD_NEWTONDIV_CUTOFF && + b->len < MPD_NEWTONDIV_CUTOFF) { int ret; ret = _mpd_basedivmod(q->data, r->data, a->data, b->data, a->len, b->len); @@ -3468,7 +3478,7 @@ } } else { - _mpd_qbarrett_divmod(q, r, a, b, ctx, status); + _mpd_qbarrett_divmod(q, r, a, b, status); if (mpd_isinfinite(q) || q->digits > ctx->prec) { *status |= MPD_Division_impossible; goto nanresult; @@ -3763,9 +3773,9 @@ } mpd_maxcontext(&workctx); - workctx.round = MPD_ROUND_HALF_EVEN; - workctx.prec = (ctx->prec > a->digits ? ctx->prec : a->digits) + t + 2; + workctx.prec = ctx->prec + t + 2; workctx.prec = (workctx.prec < 9) ? 9 : workctx.prec; + workctx.round = MPD_ROUND_HALF_EVEN; if ((n = _mpd_get_exp_iterations(a, workctx.prec)) == MPD_SSIZE_MAX) { mpd_seterror(result, MPD_Invalid_operation, status); @@ -3844,6 +3854,7 @@ a = &aa; } + workctx.clamp = 0; prec = ctx->prec + 3; while (1) { workctx.prec = prec; @@ -3852,10 +3863,11 @@ result->exp + result->digits-workctx.prec-1); workctx.prec = ctx->prec; - mpd_qadd(&t1, result, &ulp, &workctx, status); - mpd_qsub(&t2, result, &ulp, &workctx, status); + mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status); + mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status); if (mpd_isspecial(result) || mpd_iszerocoeff(result) || mpd_qcmp(&t1, &t2, status) == 0) { + workctx.clamp = ctx->clamp; mpd_qfinalize(result, &workctx, status); break; } @@ -3949,13 +3961,13 @@ mpd_ssize_t klist[MPD_MAX_PREC_LOG2]; int i; - if (mpd_ln10.digits > maxprec) { + if (mpd_ln10.digits > maxprec+2*MPD_RDIGITS) { /* shift to smaller cannot fail */ mpd_qshiftr_inplace(&mpd_ln10, mpd_ln10.digits-maxprec); mpd_ln10.exp = -(mpd_ln10.digits-1); return; } - else if (mpd_ln10.digits == maxprec) { + else if (mpd_ln10.digits >= maxprec) { return; } @@ -4047,7 +4059,7 @@ 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; -/* Internal ln() function that does not check for specials or zero. */ +/* Internal ln() function that does not check for specials, zero or one. */ static void _mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status) @@ -4063,11 +4075,6 @@ mpd_uint_t dummy, x; int i; - if (_mpd_cmp(a, &one) == 0) { - _settriple(result, MPD_POS, 0, 0); - return; - } - /* * We are calculating ln(a) = ln(v * 10^t) = ln(v) + t*ln(10), * where 0.5 < v <= 5. @@ -4104,22 +4111,42 @@ mpd_set_negative(z); } - mpd_maxcontext(&maxcontext); mpd_maxcontext(&varcontext); varcontext.round = MPD_ROUND_TRUNC; - maxprec = (a->digits > ctx->prec) ? a->digits : ctx->prec; - maxprec += 2; + maxprec = ctx->prec + 2; if (x <= 10 || x >= 805) { - /* v is close to 1: We estimate the magnitude of - * the logarithm and adjust the precision upwards. - * x/10 < x/(1+x) < ln(1+x), for 0 < x < 1 - * ln(1+x) < x, for -1 < x < 0 + /* v is close to 1: Estimate the magnitude of the logarithm. + * If v = 1 or ln(v) will underflow, skip the loop. Otherwise, + * adjust the precision upwards in order to obtain a sufficient + * number of significant digits. + * + * 1) x/(1+x) < ln(1+x) < x, for x > -1, x != 0 + * + * 2) (v-1)/v < ln(v) < v-1 */ - mpd_qsub(&tmp, &one, &v, &varcontext, &varcontext.status); - maxprec -= (tmp.exp < 0) ? tmp.exp : 0; - maxprec++; + mpd_t *lower = &tmp; + mpd_t *upper = &vtmp; + int cmp = _mpd_cmp(&v, &one); + + varcontext.round = MPD_ROUND_CEILING; + varcontext.prec = maxprec; + mpd_qsub(upper, &v, &one, &varcontext, &varcontext.status); + varcontext.round = MPD_ROUND_FLOOR; + mpd_qdiv(lower, upper, &v, &varcontext, &varcontext.status); + varcontext.round = MPD_ROUND_TRUNC; + + if (cmp < 0) { + _mpd_ptrswap(&upper, &lower); + } + if (mpd_adjexp(upper) < mpd_etiny(ctx)) { + _settriple(z, (cmp<0), 1, mpd_etiny(ctx)-1); + goto postloop; + } + if (mpd_adjexp(lower) < 0) { + maxprec = maxprec - mpd_adjexp(lower); + } } i = ln_schedule_prec(klist, maxprec, 2); @@ -4143,9 +4170,11 @@ mpd_qadd(z, z, &tmp, &maxcontext, status); } +postloop: mpd_update_ln10(maxprec+2, status); mpd_qmul_ssize(&tmp, &mpd_ln10, t, &maxcontext, status); - mpd_qadd(result, &tmp, z, &maxcontext, status); + varcontext.prec = maxprec+2; + mpd_qadd(result, &tmp, z, &varcontext, status); finish: @@ -4160,6 +4189,7 @@ uint32_t *status) { mpd_context_t workctx; + mpd_ssize_t adjexp, t; if (mpd_isspecial(a)) { if (mpd_qcheck_nan(result, a, ctx, status)) { @@ -4180,6 +4210,27 @@ mpd_seterror(result, MPD_Invalid_operation, status); return; } + if (_mpd_cmp(a, &one) == 0) { + _settriple(result, MPD_POS, 0, 0); + return; + } + /* Check if the result will overflow. + * + * 1) adjexp(a) + 1 > log10(a) >= adjexp(a) + * + * 2) |log10(a)| >= adjexp(a), if adjexp(a) >= 0 + * |log10(a)| > -adjexp(a)-1, if adjexp(a) < 0 + * + * 3) |log(a)| > 2*|log10(a)| + */ + adjexp = mpd_adjexp(a); + t = (adjexp < 0) ? -adjexp-1 : adjexp; + t *= 2; + if (mpd_exp_digits(t)-1 > ctx->emax) { + *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; + mpd_setspecial(result, (adjexp<0), MPD_INF); + return; + } workctx = *ctx; workctx.round = MPD_ROUND_HALF_EVEN; @@ -4196,6 +4247,7 @@ a = &aa; } + workctx.clamp = 0; prec = ctx->prec + 3; while (1) { workctx.prec = prec; @@ -4204,10 +4256,11 @@ result->exp + result->digits-workctx.prec-1); workctx.prec = ctx->prec; - mpd_qadd(&t1, result, &ulp, &workctx, status); - mpd_qsub(&t2, result, &ulp, &workctx, status); + mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status); + mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status); if (mpd_isspecial(result) || mpd_iszerocoeff(result) || mpd_qcmp(&t1, &t2, status) == 0) { + workctx.clamp = ctx->clamp; mpd_qfinalize(result, &workctx, status); break; } @@ -4232,9 +4285,9 @@ mpd_context_t workctx; mpd_maxcontext(&workctx); - workctx.prec = ctx->prec + a->digits + 3; + workctx.prec = ctx->prec + 3; _mpd_qln(result, a, &workctx, status); - mpd_update_ln10(ctx->prec + 3, status); + mpd_update_ln10(workctx.prec, status); workctx = *ctx; workctx.round = MPD_ROUND_HALF_EVEN; @@ -4247,6 +4300,7 @@ uint32_t *status) { mpd_context_t workctx; + mpd_ssize_t adjexp, t; workctx = *ctx; workctx.round = MPD_ROUND_HALF_EVEN; @@ -4281,6 +4335,20 @@ mpd_qfinalize(result, &workctx, status); return; } + /* Check if the result will overflow. + * + * 1) adjexp(a) + 1 > log10(a) >= adjexp(a) + * + * 2) |log10(a)| >= adjexp(a), if adjexp(a) >= 0 + * |log10(a)| > -adjexp(a)-1, if adjexp(a) < 0 + */ + adjexp = mpd_adjexp(a); + t = (adjexp < 0) ? -adjexp-1 : adjexp; + if (mpd_exp_digits(t)-1 > ctx->emax) { + *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded; + mpd_setspecial(result, (adjexp<0), MPD_INF); + return; + } if (ctx->allcr) { MPD_NEW_STATIC(t1, 0,0,0,0); @@ -4294,6 +4362,7 @@ a = &aa; } + workctx.clamp = 0; prec = ctx->prec + 3; while (1) { workctx.prec = prec; @@ -4302,10 +4371,11 @@ result->exp + result->digits-workctx.prec-1); workctx.prec = ctx->prec; - mpd_qadd(&t1, result, &ulp, &workctx, status); - mpd_qsub(&t2, result, &ulp, &workctx, status); + mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status); + mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status); if (mpd_isspecial(result) || mpd_iszerocoeff(result) || mpd_qcmp(&t1, &t2, status) == 0) { + workctx.clamp = ctx->clamp; mpd_qfinalize(result, &workctx, status); break; } @@ -5367,6 +5437,7 @@ mpd_workcontext(&workctx, ctx); workctx.prec += (exp->digits + exp->exp + 2); workctx.round = MPD_ROUND_HALF_EVEN; + workctx.clamp = 0; if (mpd_isnegative(exp)) { mpd_qdiv(&tbase, &one, base, &workctx, status); if (*status&MPD_Errors) { @@ -5637,6 +5708,7 @@ workctx.prec = (base->digits > ctx->prec) ? base->digits : ctx->prec; workctx.prec += (4 + MPD_EXPDIGITS); workctx.round = MPD_ROUND_HALF_EVEN; + workctx.allcr = ctx->allcr; mpd_qln(result, base, &workctx, &workctx.status); mpd_qmul(result, result, &texp, &workctx, &workctx.status); @@ -5952,10 +6024,8 @@ return; } - if (mpd_issubnormal(result, ctx)) { - *status |= MPD_Subnormal; - } *status |= workstatus; + mpd_qfinalize(result, ctx, status); } void @@ -6378,14 +6448,14 @@ */ static void _mpd_qbarrett_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, - const mpd_context_t *ctx, uint32_t *status) + uint32_t *status) { mpd_context_t workctx; mpd_t *qq = q, *rr = r; mpd_t aa, bb; int k; - workctx = *ctx; + mpd_maxcontext(&workctx); _mpd_copy_shared(&aa, a); _mpd_copy_shared(&bb, b); From python-checkins at python.org Sat Jun 5 11:11:28 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 11:11:28 +0200 (CEST) Subject: [Python-checkins] r81721 - python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Message-ID: <20100605091128.536DDEE993@mail.python.org> Author: stefan.krah Date: Sat Jun 5 11:11:28 2010 New Revision: 81721 Log: _mpd_qbarrett_divmod does not take a context arg any longer. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Sat Jun 5 11:11:28 2010 @@ -7323,9 +7323,9 @@ } - { /* some compilers need a new block here for the declaration of r */ + { MPD_NEW_STATIC(r,0,0,0,0); - _mpd_qbarrett_divmod(q, &r, a, b, ctx, status); + _mpd_qbarrett_divmod(q, &r, a, b, status); rem = !mpd_iszerocoeff(&r); mpd_del(&r); newsize = q->len; @@ -7453,7 +7453,7 @@ } } - _mpd_qbarrett_divmod(q, r, a, b, ctx, status); + _mpd_qbarrett_divmod(q, r, a, b, status); if (mpd_isinfinite(q) || q->digits > ctx->prec) { *status |= MPD_Division_impossible; goto nanresult; From python-checkins at python.org Sat Jun 5 11:21:38 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 11:21:38 +0200 (CEST) Subject: [Python-checkins] r81722 - python/branches/py3k-cdecimal/Modules/cdecimal/typearith.h Message-ID: <20100605092138.4E651EE9BD@mail.python.org> Author: stefan.krah Date: Sat Jun 5 11:21:38 2010 New Revision: 81722 Log: Add fast arithmetic for non-amd64 platforms. Tested on ppc64/AIX. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/typearith.h Modified: python/branches/py3k-cdecimal/Modules/cdecimal/typearith.h ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/typearith.h (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/typearith.h Sat Jun 5 11:21:38 2010 @@ -22,13 +22,13 @@ */ #if defined(CONFIG_64) -#if defined(__GNUC__) && defined(__x86_64__) +#if defined(__GNUC__) && defined(__x86_64__) && !defined(TEST_UINT128_T) static inline void _mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) { mpd_uint_t h, l; - asm( "mulq %3\n\t"\ + asm ( "mulq %3\n\t"\ : "=d" (h), "=a" (l)\ : "%a" (a), "rm" (b)\ : "cc" @@ -54,7 +54,29 @@ *r = rr; } /* END __GNUC__ (amd64) */ +#elif defined(HAVE_UINT128_T) +static inline void +_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b) +{ + __uint128_t hl; + + hl = (__uint128_t)a * b; + + *hi = hl >> 64; + *lo = (mpd_uint_t)hl; +} +static inline void +_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo, + mpd_uint_t d) +{ + __uint128_t hl; + + hl = ((__uint128_t)hi<<64) + lo; + *q = (mpd_uint_t)(hl / d); /* quotient is known to fit */ + *r = (mpd_uint_t)(hl - (__uint128_t)(*q) * d); +} +/* END HAVE_UINT128_T */ #elif defined(_MSC_VER) #include #pragma intrinsic(_umul128) From python-checkins at python.org Sat Jun 5 11:32:09 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 11:32:09 +0200 (CEST) Subject: [Python-checkins] r81723 - python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h Message-ID: <20100605093209.DFA08EE9DD@mail.python.org> Author: stefan.krah Date: Sat Jun 5 11:32:09 2010 New Revision: 81723 Log: Whitespace Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h Sat Jun 5 11:32:09 2010 @@ -142,7 +142,7 @@ /* Official name */ #define MPD_Insufficient_storage MPD_Malloc_error - + /* IEEE 754 interchange format contexts */ #define MPD_IEEE_CONTEXT_MAX_BITS 512 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */ #define MPD_DECIMAL32 32 From nnorwitz at gmail.com Sat Jun 5 12:23:05 2010 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 5 Jun 2010 06:23:05 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20100605102305.GA32015@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [0, 0, 69] references, sum=69 Less important issues: ---------------------- From python-checkins at python.org Sat Jun 5 12:39:42 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 12:39:42 +0200 (CEST) Subject: [Python-checkins] r81724 - python/trunk/Lib/unittest/loader.py Message-ID: <20100605103942.55BC6EE9AE@mail.python.org> Author: michael.foord Date: Sat Jun 5 12:39:42 2010 New Revision: 81724 Log: unittest TestLoader test discovery filename matching done in a method. This makes it easier to override the matching strategy in subclasses. No behaviour change in actual implementation. Modified: python/trunk/Lib/unittest/loader.py Modified: python/trunk/Lib/unittest/loader.py ============================================================================== --- python/trunk/Lib/unittest/loader.py (original) +++ python/trunk/Lib/unittest/loader.py Sat Jun 5 12:39:42 2010 @@ -230,6 +230,10 @@ __import__(name) return sys.modules[name] + def _match_path(self, path, full_path, pattern): + # override this method to use alternative matching strategy + return fnmatch(path, pattern) + def _find_tests(self, start_dir, pattern): """Used by discovery. Yields test suites it loads.""" paths = os.listdir(start_dir) @@ -240,26 +244,26 @@ if not VALID_MODULE_NAME.match(path): # valid Python identifiers only continue - - if fnmatch(path, pattern): - # if the test file matches, load it - name = self._get_name_from_path(full_path) - try: - module = self._get_module_from_name(name) - except: - yield _make_failed_import_test(name, self.suiteClass) - else: - mod_file = os.path.abspath(getattr(module, '__file__', full_path)) - realpath = os.path.splitext(mod_file)[0] - fullpath_noext = os.path.splitext(full_path)[0] - if realpath.lower() != fullpath_noext.lower(): - module_dir = os.path.dirname(realpath) - mod_name = os.path.splitext(os.path.basename(full_path))[0] - expected_dir = os.path.dirname(full_path) - msg = ("%r module incorrectly imported from %r. Expected %r. " - "Is this module globally installed?") - raise ImportError(msg % (mod_name, module_dir, expected_dir)) - yield self.loadTestsFromModule(module) + if not self._match_path(path, full_path, pattern): + continue + # if the test file matches, load it + name = self._get_name_from_path(full_path) + try: + module = self._get_module_from_name(name) + except: + yield _make_failed_import_test(name, self.suiteClass) + else: + mod_file = os.path.abspath(getattr(module, '__file__', full_path)) + realpath = os.path.splitext(mod_file)[0] + fullpath_noext = os.path.splitext(full_path)[0] + if realpath.lower() != fullpath_noext.lower(): + module_dir = os.path.dirname(realpath) + mod_name = os.path.splitext(os.path.basename(full_path))[0] + expected_dir = os.path.dirname(full_path) + msg = ("%r module incorrectly imported from %r. Expected %r. " + "Is this module globally installed?") + raise ImportError(msg % (mod_name, module_dir, expected_dir)) + yield self.loadTestsFromModule(module) elif os.path.isdir(full_path): if not os.path.isfile(os.path.join(full_path, '__init__.py')): continue From python-checkins at python.org Sat Jun 5 12:45:41 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 12:45:41 +0200 (CEST) Subject: [Python-checkins] r81725 - in python/branches/py3k: Lib/unittest/loader.py Message-ID: <20100605104541.5E2CBEE9BA@mail.python.org> Author: michael.foord Date: Sat Jun 5 12:45:41 2010 New Revision: 81725 Log: Merged revisions 81724 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81724 | michael.foord | 2010-06-05 11:39:42 +0100 (Sat, 05 Jun 2010) | 1 line unittest TestLoader test discovery filename matching done in a method. This makes it easier to override the matching strategy in subclasses. No behaviour change in actual implementation. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/loader.py Modified: python/branches/py3k/Lib/unittest/loader.py ============================================================================== --- python/branches/py3k/Lib/unittest/loader.py (original) +++ python/branches/py3k/Lib/unittest/loader.py Sat Jun 5 12:45:41 2010 @@ -235,6 +235,10 @@ __import__(name) return sys.modules[name] + def _match_path(self, path, full_path, pattern): + # override this method to use alternative matching strategy + return fnmatch(path, pattern) + def _find_tests(self, start_dir, pattern): """Used by discovery. Yields test suites it loads.""" paths = os.listdir(start_dir) @@ -245,26 +249,26 @@ if not VALID_MODULE_NAME.match(path): # valid Python identifiers only continue - - if fnmatch(path, pattern): - # if the test file matches, load it - name = self._get_name_from_path(full_path) - try: - module = self._get_module_from_name(name) - except: - yield _make_failed_import_test(name, self.suiteClass) - else: - mod_file = os.path.abspath(getattr(module, '__file__', full_path)) - realpath = os.path.splitext(mod_file)[0] - fullpath_noext = os.path.splitext(full_path)[0] - if realpath.lower() != fullpath_noext.lower(): - module_dir = os.path.dirname(realpath) - mod_name = os.path.splitext(os.path.basename(full_path))[0] - expected_dir = os.path.dirname(full_path) - msg = ("%r module incorrectly imported from %r. Expected %r. " - "Is this module globally installed?") - raise ImportError(msg % (mod_name, module_dir, expected_dir)) - yield self.loadTestsFromModule(module) + if not self._match_path(path, full_path, pattern): + continue + # if the test file matches, load it + name = self._get_name_from_path(full_path) + try: + module = self._get_module_from_name(name) + except: + yield _make_failed_import_test(name, self.suiteClass) + else: + mod_file = os.path.abspath(getattr(module, '__file__', full_path)) + realpath = os.path.splitext(mod_file)[0] + fullpath_noext = os.path.splitext(full_path)[0] + if realpath.lower() != fullpath_noext.lower(): + module_dir = os.path.dirname(realpath) + mod_name = os.path.splitext(os.path.basename(full_path))[0] + expected_dir = os.path.dirname(full_path) + msg = ("%r module incorrectly imported from %r. Expected %r. " + "Is this module globally installed?") + raise ImportError(msg % (mod_name, module_dir, expected_dir)) + yield self.loadTestsFromModule(module) elif os.path.isdir(full_path): if not os.path.isfile(os.path.join(full_path, '__init__.py')): continue From python-checkins at python.org Sat Jun 5 13:11:28 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 13:11:28 +0200 (CEST) Subject: [Python-checkins] r81726 - python/branches/py3k-cdecimal/Lib/test/decimal_tests.py Message-ID: <20100605111128.451FEEE9C7@mail.python.org> Author: stefan.krah Date: Sat Jun 5 13:11:28 2010 New Revision: 81726 Log: 1) Add nested with-statements to the threading test. 2) Add nested with-statements and garbage collection stress tests to WithStatementTest(). 3) Test the context templates and IEEEContext(). Modified: python/branches/py3k-cdecimal/Lib/test/decimal_tests.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_tests.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_tests.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_tests.py Sat Jun 5 13:11:28 2010 @@ -1299,28 +1299,68 @@ d1 = Decimal(1) d3 = Decimal(3) test1 = d1/d3 + + cls.finish1.set() cls.synchro.wait() + test2 = d1/d3 - cls.finish1.set() + with localcontext() as c2: + cls.assertTrue(c2.flags[Inexact]) + cls.assertRaises(DivisionByZero, c2.divide, d1, 0) + cls.assertTrue(c2.flags[DivisionByZero]) + with localcontext() as c3: + cls.assertTrue(c3.flags[Inexact]) + cls.assertTrue(c3.flags[DivisionByZero]) + cls.assertRaises(InvalidOperation, c3.compare, d1, Decimal('sNaN')) + cls.assertTrue(c3.flags[InvalidOperation]) + del c3 + cls.assertFalse(c2.flags[InvalidOperation]) + del c2 cls.assertEqual(test1, Decimal('0.333333333333333333333333')) cls.assertEqual(test2, Decimal('0.333333333333333333333333')) + + c1 = getcontext() + cls.assertTrue(c1.flags[Inexact]) + for sig in Overflow, Underflow, DivisionByZero, InvalidOperation: + cls.assertFalse(c1.flags[sig]) return def thfunc2(cls): d1 = Decimal(1) d3 = Decimal(3) test1 = d1/d3 + thiscontext = getcontext() thiscontext.prec = 18 test2 = d1/d3 + + with localcontext() as c2: + cls.assertTrue(c2.flags[Inexact]) + cls.assertRaises(Overflow, c2.multiply, Decimal('1e425000000'), 999) + cls.assertTrue(c2.flags[Overflow]) + with localcontext(thiscontext) as c3: + cls.assertTrue(c3.flags[Inexact]) + cls.assertFalse(c3.flags[Overflow]) + c3.traps[Underflow] = True + cls.assertRaises(Underflow, c3.divide, Decimal('1e-425000000'), 999) + cls.assertTrue(c3.flags[Underflow]) + del c3 + cls.assertFalse(c2.flags[Underflow]) + cls.assertFalse(c2.traps[Underflow]) + del c2 + cls.synchro.set() cls.finish2.set() cls.assertEqual(test1, Decimal('0.333333333333333333333333')) cls.assertEqual(test2, Decimal('0.333333333333333333')) - return + cls.assertFalse(thiscontext.traps[Underflow]) + cls.assertTrue(thiscontext.flags[Inexact]) + for sig in Overflow, Underflow, DivisionByZero, InvalidOperation: + cls.assertFalse(thiscontext.flags[sig]) + return class DecimalUseOfContextTest(unittest.TestCase): '''Unit tests for Use of Context cases in Decimal.''' @@ -1328,21 +1368,23 @@ try: import threading except ImportError: - threading = None + self.skipTest("importing threading failed") # Take care executing this test from IDLE, there's an issue in threading # that hangs IDLE and I couldn't find it def test_threading(self): + if HAVE_CDECIMAL and not HAVE_THREADS: + self.skipTest("compiled without threading") # Test the "threading isolation" of a Context. Also test changing # the DefaultContext, which acts as a template for the thread-local # contexts. - - # XXX Must re-enable if compiled with USE_THREAD_LOCAL_STORAGE! - if HAVE_CDECIMAL: return - - saveprec = DefaultContext.prec + save_prec = DefaultContext.prec + save_emax = DefaultContext.Emax + save_emin = DefaultContext.Emin DefaultContext.prec = 24 + DefaultContext.Emax = 425000000 + DefaultContext.Emin = -425000000 self.synchro = threading.Event() self.finish1 = threading.Event() @@ -1357,13 +1399,15 @@ self.finish1.wait() self.finish2.wait() - DefaultContext.prec = saveprec + for sig in (Inexact, Overflow, Underflow, DivisionByZero, + InvalidOperation): + self.assertFalse(DefaultContext.flags[sig]) + + DefaultContext.prec = save_prec + DefaultContext.Emax = save_emax + DefaultContext.Emin = save_emin return - if threading is None: - del test_threading - - class DecimalUsabilityTest(unittest.TestCase): '''Unit tests for Usability cases of Decimal.''' @@ -1462,6 +1506,9 @@ Decimal("56531E100"), ]) + if HAVE_CDECIMAL: + self.skipTest("new hashing scheme and float comparisons not " + "implemented yet") # check that hash(d) == hash(int(d)) for integral values for value in test_values: self.assertEqual(hash(value), hash(int(value))) @@ -1472,15 +1519,14 @@ self.assertTrue(hash(Decimal('Inf'))) self.assertTrue(hash(Decimal('-Inf'))) - if not HAVE_CDECIMAL: # XXX float comparisons not implemented yet. - # check that the hashes of a Decimal float match when they - # represent exactly the same values - test_strings = ['inf', '-Inf', '0.0', '-.0e1', - '34.0', '2.5', '112390.625', '-0.515625'] - for s in test_strings: - f = float(s) - d = Decimal(s) - self.assertEqual(hash(f), hash(d)) + # check that the hashes of a Decimal float match when they + # represent exactly the same values + test_strings = ['inf', '-Inf', '0.0', '-.0e1', + '34.0', '2.5', '112390.625', '-0.515625'] + for s in test_strings: + f = float(s) + d = Decimal(s) + self.assertEqual(hash(f), hash(d)) # check that the value of the hash doesn't depend on the # current context (issue #1757) @@ -1957,6 +2003,7 @@ self.assertNotEqual(id(c), id(d)) self.assertNotEqual(id(c.flags), id(d.flags)) self.assertNotEqual(id(c.traps), id(d.traps)) + self.assertEqual(c.flags, d.flags) def test_abs(self): c = Context() @@ -2416,6 +2463,81 @@ self.assertIsNot(new_ctx, set_ctx, 'did not copy the context') self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context') + def test_nested_with_statements(self): + # Use a copy of the supplied context in the block + orig_ctx = getcontext() + orig_ctx.clear_flags() + new_ctx = Context(Emax=384) + with localcontext() as c1: + self.assertEqual(c1.flags, orig_ctx.flags) + self.assertEqual(c1.traps, orig_ctx.traps) + c1.traps[Clamped] = True + c1.Emin = -383 + self.assertRaises(Clamped, c1.create_decimal, '0e-999') + self.assertTrue(c1.flags[Clamped]) + with localcontext(new_ctx) as c2: + self.assertEqual(c2.flags, new_ctx.flags) + self.assertEqual(c2.traps, new_ctx.traps) + self.assertRaises(Overflow, c2.power, Decimal('3.4e200'), 2) + self.assertFalse(c2.flags[Clamped]) + self.assertTrue(c2.flags[Overflow]) + del c2 + self.assertFalse(c1.flags[Overflow]) + del c1 + self.assertNotEqual(orig_ctx.Emin, -383) + self.assertFalse(orig_ctx.flags[Clamped]) + self.assertFalse(orig_ctx.flags[Overflow]) + self.assertFalse(new_ctx.flags[Clamped]) + self.assertFalse(new_ctx.flags[Overflow]) + + def test_with_statements_gc1(self): + with localcontext() as c1: + del c1 + with localcontext() as c2: + del c2 + with localcontext() as c3: + del c3 + with localcontext() as c4: + del c4 + + def test_with_statements_gc2(self): + with localcontext() as c1: + with localcontext(c1) as c2: + del c1 + with localcontext(c2) as c3: + del c2 + with localcontext(c3) as c4: + del c3 + del c4 + + def test_with_statements_gc3(self): + with localcontext() as c1: + del c1 + n1 = Context(prec=1) + setcontext(n1) + with localcontext(n1) as c2: + del n1 + self.assertEqual(c2.prec, 1) + del c2 + n2 = Context(prec=2) + setcontext(n2) + del n2 + self.assertEqual(getcontext().prec, 2) + n3 = Context(prec=3) + setcontext(n3) + self.assertEqual(getcontext().prec, 3) + with localcontext(n3) as c3: + del n3 + self.assertEqual(c3.prec, 3) + del c3 + n4 = Context(prec=4) + setcontext(n4) + del n4 + self.assertEqual(getcontext().prec, 4) + with localcontext() as c4: + self.assertEqual(c4.prec, 4) + del c4 + class ContextFlags(unittest.TestCase): def test_flags_irrelevant(self): # check that the result (numeric result + flags raised) of an @@ -2468,6 +2590,65 @@ "operation raises different flags depending on flags set: " + "expected %s, got %s" % (expected_flags, new_flags)) +class SpecialContexts(unittest.TestCase): + def test_context_templates(self): + basic_context_prec = BasicContext.prec + extended_context_prec = ExtendedContext.prec + + BasicContext.prec = ExtendedContext.prec = 441 + + for template in BasicContext, ExtendedContext: + setcontext(template) + c = getcontext() + self.assertIsNot(c, template) + self.assertEqual(c.prec, 441) + + BasicContext.prec = basic_context_prec + ExtendedContext.prec = extended_context_prec + + def test_default_context(self): + default_context_prec = DefaultContext.prec + + c = getcontext() + saveprec = c.prec + + DefaultContext.prec = 961 + c = getcontext() + self.assertEqual(c.prec, saveprec) + + setcontext(DefaultContext) + c = getcontext() + self.assertIsNot(c, DefaultContext) + self.assertEqual(c.prec, 961) + + DefaultContext.prec = default_context_prec + + def test_ieee_context(self): + def assert_rest(self, context): + self.assertEqual(context.clamp, 1) + for v in context.traps: + self.assertFalse(v) + for v in context.flags: + self.assertFalse(v) + + c = IEEEContext(DECIMAL32) + self.assertEqual(c.prec, 7) + self.assertEqual(c.Emax, 96) + self.assertEqual(c.Emin, -95) + assert_rest(self, c) + + c = IEEEContext(DECIMAL64) + self.assertEqual(c.prec, 16) + self.assertEqual(c.Emax, 384) + self.assertEqual(c.Emin, -383) + assert_rest(self, c) + + c = IEEEContext(DECIMAL128) + self.assertEqual(c.prec, 34) + self.assertEqual(c.Emax, 6144) + self.assertEqual(c.Emin, -6143) + assert_rest(self, c) + def test_main(arith=False, verbose=None, todo_tests=None, debug=None): """ Execute the tests. @@ -2492,7 +2673,8 @@ ContextAPItests, DecimalTest, WithStatementTest, - ContextFlags + ContextFlags, + SpecialContexts ] else: test_classes = [DecimalTest] @@ -2514,7 +2696,10 @@ try: run_unittest(*test_classes) if todo_tests is None: - import decimal as DecimalModule + if HAVE_CDECIMAL: + import cdecimal as DecimalModule + else: + import decimal as DecimalModule run_doctest(DecimalModule, verbose) finally: setcontext(ORIGINAL_CONTEXT) From python-checkins at python.org Sat Jun 5 13:23:51 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 13:23:51 +0200 (CEST) Subject: [Python-checkins] r81727 - python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py Message-ID: <20100605112351.D27A5EE9BF@mail.python.org> Author: stefan.krah Date: Sat Jun 5 13:23:51 2010 New Revision: 81727 Log: Add tests for contexts with small Emin/Emax, IEEE and random contexts. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py Sat Jun 5 13:23:51 2010 @@ -15,8 +15,11 @@ import cdecimal, decimal import sys, inspect -import platform +import array + from copy import copy +from randdec import * +from randfloat import * py_minor = sys.version_info[1] @@ -109,8 +112,7 @@ self.d.Emax = val def getround(self): - assert(self.f.rounding == self.d.rounding) - return self.f.rounding + return self.d.rounding def setround(self, val): self.f.rounding = val @@ -133,9 +135,9 @@ self.d._clamp = val prec = property(getprec, setprec) - emin = property(getemin, setemin) - emax = property(getemax, setemax) - round = property(getround, setround) + Emin = property(getemin, setemin) + Emax = property(getemax, setemax) + rounding = property(getround, setround) clamp = property(getclamp, setclamp) capitals = property(getcapitals, setcapitals) @@ -170,6 +172,8 @@ # We don't want exceptions so that we can compare the status flags. context = Context() +context.Emin = cdecimal.MIN_EMIN +context.Emax = cdecimal.MAX_EMAX context.clear_traps() # When creating decimals, cdecimal is ultimately limited by the maximum @@ -209,7 +213,7 @@ decimal: %s\n\n" class CdecException(ArithmeticError): - def __init__(self, result, funcname, operands): + def __init__(self, result, funcname, operands, fctxstr, dctxstr): self.errstring = "Error in %s(%s" % (funcname, operands[0]) for op in operands[1:]: self.errstring += ", %s" % op @@ -226,7 +230,7 @@ str(dec_tuple)) else: self.errstring += _exc_fmt_obj % (str(result[0]), str(result[1])) - self.errstring += "%s\n%s\n\n" % (str(context.f), str(context.d)) + self.errstring += "%s\n%s\n\n" % (fctxstr, dctxstr) def __str__(self): return self.errstring @@ -255,6 +259,32 @@ b = dec.next_minus() return abs(a - b) + def un_resolve_ulp(self, result, funcname, operands): + """Results of cdecimal's power function are currently not always + correctly rounded. Check if the cdecimal result differs by less + than 1 ULP from the correctly rounded decimal.py result.""" + mpdstr = str(result.mpd) + mpdresult = decimal.Decimal(mpdstr) + decresult = result.dec + deculp = self.ulp(decresult) + op = operands[0].dec + tmpctx = context.d.copy() + tmpctx.prec *= 2 + # result, recalculated at double precision + dpresult = getattr(op, funcname)(context=tmpctx) + mpddiff = abs(dpresult - mpdresult) + if mpddiff >= deculp: + print("deculp: %d dpresult: %s mpdresult: %s" % + (deculp, dpresult, mpdresult)) + return False # not simply a disagreement, but wrong + decdiff = abs(dpresult - decresult) + if decdiff >= deculp: + print("deculp: %d dpresult: %s mpdresult: %s" % + (deculp, dpresult, mpdresult)) + return False # not simply a disagreement, but wrong + self.ulpdiff += 1 + return True + def bin_resolve_ulp(self, result, funcname, operands): """Results of cdecimal's power function are currently not always correctly rounded. Check if the cdecimal result differs by less @@ -271,13 +301,29 @@ dpresult = getattr(op1, funcname)(op2, context=tmpctx) mpddiff = abs(dpresult - mpdresult) if mpddiff >= deculp: + print("deculp: %d dpresult: %s mpdresult: %s" % + (deculp, dpresult, mpdresult)) return False # not simply a disagreement, but wrong decdiff = abs(dpresult - decresult) if decdiff >= deculp: + print("deculp: %d dpresult: %s mpdresult: %s" % + (deculp, dpresult, mpdresult)) return False # not simply a disagreement, but wrong self.ulpdiff += 1 return True + def exp(self, result, operands): + if context.f.allcr: return False + return self.un_resolve_ulp(result, "exp", operands) + + def log10(self, result, operands): + if context.f.allcr: return False + return self.un_resolve_ulp(result, "log10", operands) + + def ln(self, result, operands): + if context.f.allcr: return False + return self.un_resolve_ulp(result, "ln", operands) + def __pow__(self, result, operands): """See DIFFERENCES.txt""" if operands[2] is not None: # three argument __pow__ @@ -342,19 +388,29 @@ def default(self, result, operands): return False - __ge__ = __gt__ = __le__ = __lt__ = __repr__ = __str__ = \ - __ne__ = __eq__ = default + __ge__ = __gt__ = __le__ = __lt__ = __repr__ = __str__ = default if py_minor >= 2: def __hash__(self, result, operands): - c = operands[0] - if c.mpd.is_infinite(): - # Hashing infinities changed in 3.2 + # New hashing scheme in r81486 is not yet implemented. + return True + __ne__ = __eq__ = default + + if py_minor <= 2: + # Actually <= 1, but this is quite recent in 3.2, so + # not all installed 3.2 versions have it. + def __eq__(self, result, operands): + """cdecimal raises for all sNaN comparisons""" + if operands[0].mpd.is_snan() or operands[1].mpd.is_snan(): return True - # If a Decimal instance is exactly representable as a float - # then (in 3.2) its hash matches that of the float. - f = float(c.dec) - if decimal.Decimal.from_float(f) == c.dec: + __ne__ = __eq__ + + if py_minor <= 1: + # Fixed in release31-maint, but a lot of distributed + # versions do not have the fix yet. + def is_normal(self, result, operands): + # Issue7099 + if operands[0].mpd.is_normal(): return True @@ -374,7 +430,8 @@ if result[0] != result[1] or not context.assert_eq_status(): if obj_known_disagreement(result, funcname, operands): return # skip known disagreements - raise CdecException(result, funcname, operands) + raise CdecException(result, funcname, operands, + str(context.f), str(context.d)) class cdec(object): @@ -416,7 +473,8 @@ or not context.assert_eq_status(): if cdec_known_disagreement(self, funcname, operands): return # skip known disagreements - raise CdecException(self, funcname, operands) + raise CdecException(self, funcname, operands, + str(context.f), str(context.d)) def unaryfunc(self, funcname): "unary function returning a cdec" @@ -437,7 +495,7 @@ return c def obj_unaryfunc(self, funcname): - "unary function returning a cdec" + "unary function returning an object other than a cdec" context.clear_status() r_mpd = getattr(self.mpd, funcname)() r_dec = getattr(self.dec, funcname)() @@ -834,11 +892,8 @@ if isinstance(third, cdec): third_mpd = third.mpd third_dec = third.dec - if (third is not None): - c.mpd = getattr(self.mpd, 'powmod')(other_mpd, third_mpd) - else: - c.mpd = getattr(self.mpd, 'pow')(other_mpd) - c.dec = getattr(context.d, 'power')(self.dec, other_dec, third_dec) + c.mpd = pow(self.mpd, other_mpd, third_mpd) + c.dec = pow(self.dec, other_dec, third_dec) c.verify('power', (self, other, third)) return c @@ -908,333 +963,363 @@ sys.stdout.write(''.join((str(fmt), '\n'))) sys.stdout.flush() -def test_unary(method, prec_lst, iter): +def test_method(method, testspecs, testfunc): log("testing %s ...", method) - for prec in prec_lst: - log(" prec: %d", prec) - context.prec = prec - for round in sorted(decround): - context.round = round - rprec = 10**prec - exprange = cdecimal.MAX_EMAX - if method in ['__int__', '__long__', '__trunc__', 'to_integral', \ - 'to_integral_value', 'to_integral_value']: - exprange = 9999 - for a in un_close_to_pow10(prec, exprange, iter): - try: - x = cdec(a) - getattr(x, method)() - except CdecException as err: - log(err) - for a in un_close_numbers(prec, exprange, -exprange, iter): - try: - x = cdec(a) - getattr(x, method)() - except CdecException as err: - log(err) - for a in un_incr_digits_tuple(prec, exprange, iter): - try: - x = cdec(a) - getattr(x, method)() - except CdecException as err: - log(err) - for i in range(1000): - try: - s = randdec(prec, exprange) - x = cdec(s) - getattr(x, method)() - except CdecException as err: - log(err) - except OverflowError: - pass - try: - s = randtuple(prec, exprange) - x = cdec(s) - getattr(x, method)() - except CdecException as err: - log(err) - except OverflowError: - pass + for spec in testspecs: + if 'samples' in spec: + spec['prec'] = sorted(random.sample(range(1, 101), spec['samples'])) + for prec in spec['prec']: + context.prec = prec + for expts in spec['expts']: + emin, emax = expts + if emin == 'rand': + context.Emin = random.randrange(-1000, 0) + context.Emax = random.randrange(prec, 1000) + else: + context.Emin, context.Emax = emin, emax + if prec > context.Emax: continue + log(" prec: %d emin: %d emax: %d", + (context.prec, context.Emin, context.Emax)) + restr_range = 9999 if context.Emax > 9999 else context.Emax+99 + for rounding in sorted(decround): + context.rounding = rounding + context.capitals = random.randrange(2) + if spec['clamp'] == 2: + context.clamp = random.randrange(2) + else: + context.clamp = spec['clamp'] + exprange = context.f.Emax + testfunc(method, prec, exprange, restr_range, spec['iter']) + +def test_unary(method, prec, exprange, restr_range, iter): + if method in ['__int__', '__long__', '__trunc__', 'to_integral', + 'to_integral_value', 'to_integral_value']: + exprange = restr_range + for a in un_close_to_pow10(prec, exprange, iter): + try: + x = cdec(a) + getattr(x, method)() + except CdecException as err: + log(err) + for a in un_close_numbers(prec, exprange, -exprange, iter): + try: + x = cdec(a) + getattr(x, method)() + except CdecException as err: + log(err) + for a in un_incr_digits_tuple(prec, exprange, iter): + try: + x = cdec(a) + getattr(x, method)() + except CdecException as err: + log(err) + for a in un_randfloat(): + try: + x = cdec(a) + getattr(x, method)() + except CdecException as err: + log(err) + for i in range(1000): + try: + s = randdec(prec, exprange) + x = cdec(s) + getattr(x, method)() + except CdecException as err: + log(err) + except OverflowError: + pass + try: + s = randtuple(prec, exprange) + x = cdec(s) + getattr(x, method)() + except CdecException as err: + log(err) + except OverflowError: + pass -def test_un_logical(method, prec_lst, iter): - log("testing %s ...", method) - for prec in prec_lst: - log(" prec: %d", prec) - context.prec = prec - for round in sorted(decround): - context.round = round - for a in logical_un_incr_digits(prec, iter): - try: - x = cdec(a) - getattr(x, method)() - except CdecException as err: - log(err) - for i in range(1000): - try: - s = randdec(prec, 999999) - x = cdec(s) - getattr(x, method)() - except CdecException as err: - log(err) - except OverflowError: - pass +def test_un_logical(method, prec, exprange, restr_range, iter): + for a in logical_un_incr_digits(prec, iter): + try: + x = cdec(a) + getattr(x, method)() + except CdecException as err: + log(err) + for i in range(1000): + try: + s = randdec(prec, restr_range) + x = cdec(s) + getattr(x, method)() + except CdecException as err: + log(err) + except OverflowError: + pass + +def test_binary(method, prec, exprange, restr_range, iter): + if method in ['__pow__', '__rpow__', 'power']: + exprange = restr_range + for a, b in bin_close_to_pow10(prec, exprange, iter): + try: + x = cdec(a) + y = cdec(b) + getattr(x, method)(y) + except CdecException as err: + log(err) + for a, b in bin_close_numbers(prec, exprange, -exprange, iter): + try: + x = cdec(a) + y = cdec(b) + getattr(x, method)(y) + except CdecException as err: + log(err) + for a, b in bin_incr_digits(prec, exprange, iter): + try: + x = cdec(a) + y = cdec(b) + getattr(x, method)(y) + except CdecException as err: + log(err) + for a, b in bin_randfloat(): + try: + x = cdec(a) + y = cdec(b) + getattr(x, method)(y) + except CdecException as err: + log(err) + for i in range(1000): + s1 = randdec(prec, exprange) + s2 = randdec(prec, exprange) + try: + x = cdec(s1) + y = cdec(s2) + getattr(x, method)(y) + except CdecException as err: + log(err) -def test_binary(method, prec_lst, iter): - log("testing %s ...", method) - for prec in prec_lst: - log(" prec: %d", prec) - context.prec = prec - for round in sorted(decround): - context.round = round - exprange = cdecimal.MAX_EMAX - if method in ['__pow__', '__rpow__', 'power']: - exprange = 99999 - for a, b in bin_close_to_pow10(prec, exprange, iter): - try: - x = cdec(a) - y = cdec(b) - getattr(x, method)(y) - except CdecException as err: - log(err) - for a, b in bin_close_numbers(prec, exprange, -exprange, iter): - try: - x = cdec(a) - y = cdec(b) - getattr(x, method)(y) - except CdecException as err: - log(err) - for a, b in bin_incr_digits(prec, exprange, iter): - try: - x = cdec(a) - y = cdec(b) - getattr(x, method)(y) - except CdecException as err: - log(err) - for i in range(1000): - s1 = randdec(prec, exprange) - s2 = randdec(prec, exprange) - try: - x = cdec(s1) - y = cdec(s2) - getattr(x, method)(y) - except CdecException as err: - log(err) +def test_bin_logical(method, prec, exprange, restr_range, iter): + for a, b in logical_bin_incr_digits(prec, iter): + try: + x = cdec(a) + y = cdec(b) + getattr(x, method)(y) + except CdecException as err: + log(err) + for i in range(1000): + s1 = randdec(prec, restr_range) + s2 = randdec(prec, restr_range) + try: + x = cdec(s1) + y = cdec(s2) + getattr(x, method)(y) + except CdecException as err: + log(err) + +def test_ternary(method, prec, exprange, restr_range, iter): + if method in ['__pow__', 'power']: + exprange = restr_range + for a, b, c in tern_close_numbers(prec, exprange, -exprange, iter): + try: + x = cdec(a) + y = cdec(b) + z = cdec(c) + getattr(x, method)(y, z) + except CdecException as err: + log(err) + for a, b, c in tern_incr_digits(prec, exprange, iter): + try: + x = cdec(a) + y = cdec(b) + z = cdec(c) + getattr(x, method)(y, z) + except CdecException as err: + log(err) + for a, b, c in tern_randfloat(): + try: + x = cdec(a) + y = cdec(b) + z = cdec(c) + getattr(x, method)(y, z) + except CdecException as err: + log(err) + for i in range(1000): + s1 = randdec(prec, 2*exprange) + s2 = randdec(prec, 2*exprange) + s3 = randdec(prec, 2*exprange) + try: + x = cdec(s1) + y = cdec(s2) + z = cdec(s3) + getattr(x, method)(y, z) + except CdecException as err: + log(err) -def test_bin_logical(method, prec_lst, iter): - log("testing %s ...", method) - for prec in prec_lst: - log(" prec: %d", prec) - context.prec = prec - for round in sorted(decround): - context.round = round - for a, b in logical_bin_incr_digits(prec, iter): - try: - x = cdec(a) - y = cdec(b) - getattr(x, method)(y) - except CdecException as err: - log(err) - for i in range(1000): - s1 = randdec(prec, 999999) - s2 = randdec(prec, 999999) - try: - x = cdec(s1) - y = cdec(s2) - getattr(x, method)(y) - except CdecException as err: - log(err) +def test_format(method, prec, exprange, restr_range, iter): + for a in un_incr_digits_tuple(prec, restr_range, iter): + context.clear_status() + try: + fmt = rand_format(chr(random.randrange(32, 128))) + x = format(context.f.create_decimal(a), fmt) + y = format(context.d.create_decimal(a), fmt) + except Exception as err: + print(err, fmt) + continue + if x != y: + print(context.f) + print(context.d) + print("\n%s %s" % (a, fmt)) + print("%s %s\n" % (x, y)) + for i in range(1000): + context.clear_status() + try: + a = randdec(99, 9999) + fmt = rand_format(chr(random.randrange(32, 128))) + x = format(context.f.create_decimal(a), fmt) + y = format(context.d.create_decimal(a), fmt) + except Exception as err: + print(err, fmt) + continue + if x != y: + print(context.f) + print(context.d) + print("\n%s %s" % (a, fmt)) + print("%s %s\n" % (x, y)) -def test_ternary(method, prec_lst, iter): - log("testing %s ...", method) - for prec in prec_lst: - log(" prec: %d", prec) - context.prec = prec - for round in sorted(decround): - context.round = round - exprange = cdecimal.MAX_EMAX - if method in ['__pow__', 'power']: - exprange = 99999 - for a, b, c in tern_close_numbers(prec, exprange, -exprange, iter): - try: - x = cdec(a) - y = cdec(b) - z = cdec(c) - getattr(x, method)(y, z) - except CdecException as err: - log(err) - for a, b, c in tern_incr_digits(prec, exprange, iter): - try: - x = cdec(a) - y = cdec(b) - z = cdec(c) - getattr(x, method)(y, z) - except CdecException as err: - log(err) - for i in range(1000): - s1 = randdec(prec, 2*exprange) - s2 = randdec(prec, 2*exprange) - s3 = randdec(prec, 2*exprange) - try: - x = cdec(s1) - y = cdec(s2) - z = cdec(s3) - getattr(x, method)(y, z) - except CdecException as err: - log(err) - -def test_format(prec_lst, iter): - log("testing format") - for prec in prec_lst: - log(" prec: %d", prec) - context.prec = prec - for round in sorted(decround): - context.round = round - for a in un_incr_digits_tuple(prec, 9999, iter): - try: - fmt = rand_format(chr(random.randrange(32, 128))) - x = format(context.f.create_decimal(a), fmt) - y = format(context.d.create_decimal(a), fmt) - except Exception as err: - print(err, fmt) - continue - if x != y: - print(context.f) - print(context.d) - print("\n%s %s" % (a, fmt)) - print("%s %s\n" % (x, y)) - for i in range(1000): - try: - a = randdec(99, 9999) - fmt = rand_format(chr(random.randrange(32, 128))) - x = format(context.f.create_decimal(a), fmt) - y = format(context.d.create_decimal(a), fmt) - except Exception as err: - print(err, fmt) - continue - if x != y: - print(context.f) - print(context.d) - print("\n%s %s" % (a, fmt)) - print("%s %s\n" % (x, y)) - -def test_locale(prec_lst, iter): - import array - log("testing locale") - for prec in prec_lst: - log(" prec: %d", prec) - context.prec = prec - for round in sorted(decround): - context.round = round - for a in un_incr_digits_tuple(prec, 9999, iter): - try: - fmt = rand_locale() - x = format(context.f.create_decimal(a), fmt) - y = format(context.d.create_decimal(a), fmt) - except Exception as err: - print(err, fmt) - continue - if x != y: - print(context.f) - print(context.d) - print(locale.setlocale(locale.LC_NUMERIC)) - print("%s %s" % (a, fmt)) - print(list(array.array('u', x))) - print(list(array.array('u', y))) - for i in range(1000): - try: - a = randdec(99, 9999) - fmt = rand_locale() - x = format(context.f.create_decimal(a), fmt) - y = format(context.d.create_decimal(a), fmt) - except Exception as err: - print(err, fmt) - continue - if x != y: - print(context.f) - print(context.d) - print(locale.setlocale(locale.LC_NUMERIC)) - print("%s %s" % (a, fmt)) - print(list(array.array('u', x))) - print(list(array.array('u', y))) - -def test_round(prec_lst, iter): - log("testing round") - for prec in prec_lst: - log(" prec: %d", prec) - context.prec = 99 - for round in sorted(decround): - context.round = round - for a in un_incr_digits_tuple(prec, 9999, 1): - try: - n = random.randrange(10) - x = (context.f.create_decimal(a)).__round__(n) - y = (context.d.create_decimal(a)).__round__(n) - except Exception as err: - print(err) - continue - if str(x) != str(y): - print(context.f) - print(context.d) - print("\n%s %s" % (a, n)) - print("%s %s\n" % (x, y)) - exit(1) - for i in range(1000): - try: - a = randdec(99, 9999) - n = random.randrange(10) - x = context.f.create_decimal(a).__round__(n) - y = context.d.create_decimal(a).__round__(n) - except Exception as err: - print(err) - continue - if str(x) != str(y): - print(context.f) - print(context.d) - print("\n%s %s" % (a, n)) - print("%s %s\n" % (x, y)) - -def test_from_float(prec_lst): - log("testing from_float ...") - for prec in prec_lst: - log(" prec: %d", prec) - context.prec = prec - for round in sorted(decround): - context.round = round - exprange = 384 - for i in range(1000): - intpart = str(random.randrange(100000000000000000000000000000000000000)) - fracpart = str(random.randrange(100000000000000000000000000000000000000)) - exp = str(random.randrange(-384, 384)) - fstring = intpart + '.' + fracpart + 'e' + exp - f = float(fstring) - try: - c = cdec(f) - except CdecException as err: - log(err) +def test_locale(method, prec, exprange, restr_range, iter): + for a in un_incr_digits_tuple(prec, restr_range, iter): + context.clear_status() + try: + fmt = rand_locale() + x = format(context.f.create_decimal(a), fmt) + y = format(context.d.create_decimal(a), fmt) + except Exception as err: + print(err, fmt) + continue + if x != y: + print(context.f) + print(context.d) + print(locale.setlocale(locale.LC_NUMERIC)) + print("%s %s" % (a, fmt)) + print(list(array.array('u', x))) + print(list(array.array('u', y))) + for i in range(1000): + context.clear_status() + try: + a = randdec(99, 9999) + fmt = rand_locale() + x = format(context.f.create_decimal(a), fmt) + y = format(context.d.create_decimal(a), fmt) + except Exception as err: + print(err, fmt) + continue + if x != y: + print(context.f) + print(context.d) + print(locale.setlocale(locale.LC_NUMERIC)) + print("%s %s" % (a, fmt)) + print(list(array.array('u', x))) + print(list(array.array('u', y))) + +def test_round(method, prec, exprange, restr_range, iter): + for a in un_incr_digits_tuple(prec, restr_range, 1): + context.clear_status() + try: + n = random.randrange(10) + x = (context.f.create_decimal(a)).__round__(n) + y = (context.d.create_decimal(a)).__round__(n) + except Exception as err: + print(err) + continue + if str(x) != str(y): + print(context.f) + print(context.d) + print("\n%s %s" % (a, n)) + print("%s %s\n" % (x, y)) + exit(1) + for i in range(1000): + context.clear_status() + try: + a = randdec(99, 9999) + n = random.randrange(10) + x = context.f.create_decimal(a).__round__(n) + y = context.d.create_decimal(a).__round__(n) + except Exception as err: + print(err) + continue + if str(x) != str(y): + print(context.f) + print(context.d) + print("\n%s %s" % (a, n)) + print("%s %s\n" % (x, y)) + +def test_from_float(method, prec, exprange, restr_range, iter): + for rounding in sorted(decround): + context.rounding = rounding + exprange = 384 + for i in range(1000): + intpart = str(random.randrange(100000000000000000000000000000000000000)) + fracpart = str(random.randrange(100000000000000000000000000000000000000)) + exp = str(random.randrange(-384, 384)) + fstring = intpart + '.' + fracpart + 'e' + exp + f = float(fstring) + try: + c = cdec(f) + except CdecException as err: + log(err) if __name__ == '__main__': - from randdec import * import time - import sys - - samples = 1 - iter = 1 + randseed = int(time.time()) + random.seed(randseed) - if '--short' in sys.argv: - samples = 1 - iter = 1 - elif '--medium' in sys.argv: - samples = 1 - iter = None - elif '--long' in sys.argv: - samples = 5 - iter = None + base_expts = [(cdecimal.MIN_EMIN, cdecimal.MAX_EMAX)] + if cdecimal.MAX_EMAX == 999999999999999999: + base_expts.append((-999999999, 999999999)) + + base = { + 'name': 'base', + 'expts': base_expts, + 'prec': [], + 'clamp': 2, + 'iter': None, + 'samples': None, + } + small = { + 'name': 'small', + 'prec': [1, 2, 3, 4, 5], + 'expts': [(-1,1), (-2,2), (-3,3), (-4,4), (-5,5)], + 'clamp': 2, + 'iter': None + } + ieee = [ + {'name': 'decimal32', 'prec': [7], 'expts': [(-95, 96)], 'clamp': 1, 'iter': None}, + {'name': 'decimal64', 'prec': [16], 'expts': [(-383, 384)], 'clamp': 1, 'iter': None}, + {'name': 'decimal128', 'prec': [34], 'expts': [(-6143, 6144)], 'clamp': 1, 'iter': None} + ] + + if '--medium' in sys.argv: + base['expts'].append(('rand', 'rand')) + base['samples'] = None + testspecs = [small, ieee, base] + if '--long' in sys.argv: + base['expts'].append(('rand', 'rand')) + base['samples'] = 5 + testspecs = [small, ieee, base] elif '--all' in sys.argv: - samples = 100 - iter = None + base['expts'].append(('rand', 'rand')) + base['samples'] = 100 + testspecs = [small, ieee, base] + else: # --short + rand_ieee = random.choice(ieee) + base['iter'] = small['iter'] = rand_ieee['iter'] = 1 + base['samples'] = 1 + base['expts'] = [random.choice(base_expts)] + prec = random.randrange(1, 6) + small['prec'] = [prec] + small['expts'] = [(-prec, prec)] + testspecs = [small, rand_ieee, base] + all_decimal_methods = set(dir(cdecimal.Decimal) + dir(decimal.Decimal)) all_cdec_methods = [m for m in dir(cdec) if m in all_decimal_methods] @@ -1273,37 +1358,30 @@ ternary_methods.sort() - x = int(time.time()) - random.seed(x) - log("\nRandom seed: %d\n\n", x) + log("\nRandom seed: %d\n\n", randseed) log("Skipping tests: \n\n%s\n", untested_methods) for method in unary_methods: - prec_lst = sorted(random.sample(range(1, 101), samples)) - test_unary(method, prec_lst, iter) + test_method(method, testspecs, test_unary) for method in binary_methods: - prec_lst = sorted(random.sample(range(1, 101), samples)) - test_binary(method, prec_lst, iter) + test_method(method, testspecs, test_binary) for method in ternary_methods: - prec_lst = sorted(random.sample(range(1, 101), samples)) - test_ternary(method, prec_lst, iter) + test_method(method, testspecs, test_ternary) - prec_lst = sorted(random.sample(range(1, 101), samples)) - test_un_logical('logical_invert', prec_lst, iter) + test_method('logical_invert', testspecs, test_un_logical) for method in ['logical_and', 'logical_or', 'logical_xor']: - prec_lst = sorted(random.sample(range(1, 101), samples)) - test_bin_logical(method, prec_lst, iter) + test_method(method, testspecs, test_bin_logical) + if py_minor >= 2: # Some tests will fail with 3.1, since alignment has been changed # in decimal.py 3.2. from genlocale import * - prec_lst = sorted(random.sample(range(1, 101), samples)) - test_format(prec_lst, iter) - test_locale(prec_lst, iter) - test_round(prec_lst, iter) - test_from_float(prec_lst) + test_method('format', testspecs, test_format) + test_method('locale', testspecs, test_locale) + test_method('round', testspecs, test_round) + test_method('from_float', testspecs, test_from_float) From python-checkins at python.org Sat Jun 5 13:23:51 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 13:23:51 +0200 (CEST) Subject: [Python-checkins] r81728 - in python/trunk/Lib/unittest: case.py test/test_case.py Message-ID: <20100605112351.DE8DCEE9DB@mail.python.org> Author: michael.foord Date: Sat Jun 5 13:23:51 2010 New Revision: 81728 Log: Issue 8351. Suppress large diffs in unittest.TestCase.assertSequenceEqual. Modified: python/trunk/Lib/unittest/case.py python/trunk/Lib/unittest/test/test_case.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Sat Jun 5 13:23:51 2010 @@ -13,7 +13,7 @@ ) __unittest = True - +TRUNCATED_DIFF = '\n[diff truncated...]' class SkipTest(Exception): """ @@ -589,7 +589,8 @@ failUnlessRaises = _deprecate(assertRaises) failIf = _deprecate(assertFalse) - def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): + def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None, + max_diff=80*8): """An equality assertion for ordered sequences (like lists and tuples). For the purposes of this function, a valid ordered sequence type is one @@ -602,6 +603,7 @@ datatype should be enforced. msg: Optional message to use on failure instead of a list of differences. + max_diff: Maximum size off the diff, larger diffs are not shown """ if seq_type is not None: seq_type_name = seq_type.__name__ @@ -684,9 +686,14 @@ except (TypeError, IndexError, NotImplementedError): differing += ('Unable to index element %d ' 'of second %s\n' % (len1, seq_type_name)) - standardMsg = differing + '\n' + '\n'.join( + standardMsg = differing + diffMsg = '\n' + '\n'.join( difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) + if max_diff is None or len(diffMsg) <= max_diff: + standardMsg += diffMsg + else: + standardMsg += diffMsg[:max_diff] + TRUNCATED_DIFF msg = self._formatMessage(msg, standardMsg) self.fail(msg) Modified: python/trunk/Lib/unittest/test/test_case.py ============================================================================== --- python/trunk/Lib/unittest/test/test_case.py (original) +++ python/trunk/Lib/unittest/test/test_case.py Sat Jun 5 13:23:51 2010 @@ -1,3 +1,5 @@ +import difflib +import pprint import re import sys @@ -588,6 +590,23 @@ self.assertRaises(self.failureException, self.assertDictEqual, [], d) self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) + def testAssertSequenceEqualMaxDiff(self): + seq1 = 'a' + 'x' * 80**2 + seq2 = 'b' + 'x' * 80**2 + diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), + pprint.pformat(seq2).splitlines())) + try: + self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)/2) + except AssertionError as e: + msg = e.args[0] + self.assertTrue(len(msg) < len(diff)) + + try: + self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)*2) + except AssertionError as e: + msg = e.args[0] + self.assertTrue(len(msg) > len(diff)) + def testAssertItemsEqual(self): a = object() self.assertItemsEqual([1, 2, 3], [3, 2, 1]) From python-checkins at python.org Sat Jun 5 13:26:24 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 13:26:24 +0200 (CEST) Subject: [Python-checkins] r81729 - python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randfloat.py Message-ID: <20100605112624.2FAFAEE9F4@mail.python.org> Author: stefan.krah Date: Sat Jun 5 13:26:23 2010 New Revision: 81729 Log: Add more random tests. Added: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randfloat.py (contents, props changed) Added: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randfloat.py ============================================================================== --- (empty file) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randfloat.py Sat Jun 5 13:26:23 2010 @@ -0,0 +1,250 @@ +# Copyright (c) 2010 Python Software Foundation. All Rights Reserved. +# Adapted from Python's Lib/test/test_strtod.py (by Mark Dickinson) + +# Tests for the correctly-rounded string -> float conversions +# introduced in Python 2.7 and 3.1. + +import random + +TEST_SIZE = 16 + + +def test_short_halfway_cases(): + # exact halfway cases with a small number of significant digits + for k in 0, 5, 10, 15, 20: + # upper = smallest integer >= 2**54/5**k + upper = -(-2**54//5**k) + # lower = smallest odd number >= 2**53/5**k + lower = -(-2**53//5**k) + if lower % 2 == 0: + lower += 1 + for i in range(10 * TEST_SIZE): + # Select a random odd n in [2**53/5**k, + # 2**54/5**k). Then n * 10**k gives a halfway case + # with small number of significant digits. + n, e = random.randrange(lower, upper, 2), k + + # Remove any additional powers of 5. + while n % 5 == 0: + n, e = n // 5, e + 1 + assert n % 10 in (1, 3, 7, 9) + + # Try numbers of the form n * 2**p2 * 10**e, p2 >= 0, + # until n * 2**p2 has more than 20 significant digits. + digits, exponent = n, e + while digits < 10**20: + s = '{}e{}'.format(digits, exponent) + yield s + # Same again, but with extra trailing zeros. + s = '{}e{}'.format(digits * 10**40, exponent - 40) + yield s + digits *= 2 + + # Try numbers of the form n * 5**p2 * 10**(e - p5), p5 + # >= 0, with n * 5**p5 < 10**20. + digits, exponent = n, e + while digits < 10**20: + s = '{}e{}'.format(digits, exponent) + yield s + # Same again, but with extra trailing zeros. + s = '{}e{}'.format(digits * 10**40, exponent - 40) + yield s + digits *= 5 + exponent -= 1 + +def test_halfway_cases(): + # test halfway cases for the round-half-to-even rule + for i in range(1000): + for j in range(TEST_SIZE): + # bit pattern for a random finite positive (or +0.0) float + bits = random.randrange(2047*2**52) + + # convert bit pattern to a number of the form m * 2**e + e, m = divmod(bits, 2**52) + if e: + m, e = m + 2**52, e - 1 + e -= 1074 + + # add 0.5 ulps + m, e = 2*m + 1, e - 1 + + # convert to a decimal string + if e >= 0: + digits = m << e + exponent = 0 + else: + # m * 2**e = (m * 5**-e) * 10**e + digits = m * 5**-e + exponent = e + s = '{}e{}'.format(digits, exponent) + yield s + +def test_boundaries(): + # boundaries expressed as triples (n, e, u), where + # n*10**e is an approximation to the boundary value and + # u*10**e is 1ulp + boundaries = [ + (10000000000000000000, -19, 1110), # a power of 2 boundary (1.0) + (17976931348623159077, 289, 1995), # overflow boundary (2.**1024) + (22250738585072013831, -327, 4941), # normal/subnormal (2.**-1022) + (0, -327, 4941), # zero + ] + for n, e, u in boundaries: + for j in range(1000): + for i in range(TEST_SIZE): + digits = n + random.randrange(-3*u, 3*u) + exponent = e + s = '{}e{}'.format(digits, exponent) + yield s + n *= 10 + u *= 10 + e -= 1 + +def test_underflow_boundary(): + # test values close to 2**-1075, the underflow boundary; similar + # to boundary_tests, except that the random error doesn't scale + # with n + for exponent in range(-400, -320): + base = 10**-exponent // 2**1075 + for j in range(TEST_SIZE): + digits = base + random.randrange(-1000, 1000) + s = '{}e{}'.format(digits, exponent) + yield s + +def test_bigcomp(): + for ndigs in 5, 10, 14, 15, 16, 17, 18, 19, 20, 40, 41, 50: + dig10 = 10**ndigs + for i in range(100 * TEST_SIZE): + digits = random.randrange(dig10) + exponent = random.randrange(-400, 400) + s = '{}e{}'.format(digits, exponent) + yield s + +def test_parsing(): + # make '0' more likely to be chosen than other digits + digits = '000000123456789' + signs = ('+', '-', '') + + # put together random short valid strings + # \d*[.\d*]?e + for i in range(1000): + for j in range(TEST_SIZE): + s = random.choice(signs) + intpart_len = random.randrange(5) + s += ''.join(random.choice(digits) for _ in range(intpart_len)) + if random.choice([True, False]): + s += '.' + fracpart_len = random.randrange(5) + s += ''.join(random.choice(digits) + for _ in range(fracpart_len)) + else: + fracpart_len = 0 + if random.choice([True, False]): + s += random.choice(['e', 'E']) + s += random.choice(signs) + exponent_len = random.randrange(1, 4) + s += ''.join(random.choice(digits) + for _ in range(exponent_len)) + + if intpart_len + fracpart_len: + yield s + +test_particular = [ + # squares + '1.00000000100000000025', + '1.0000000000000000000000000100000000000000000000000' #... + '00025', + '1.0000000000000000000000000000000000000000000010000' #... + '0000000000000000000000000000000000000000025', + '1.0000000000000000000000000000000000000000000000000' #... + '000001000000000000000000000000000000000000000000000' #... + '000000000025', + '0.99999999900000000025', + '0.9999999999999999999999999999999999999999999999999' #... + '999000000000000000000000000000000000000000000000000' #... + '000025', + '0.9999999999999999999999999999999999999999999999999' #... + '999999999999999999999999999999999999999999999999999' #... + '999999999999999999999999999999999999999990000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '0000000000000000000000000000025', + + '1.0000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '100000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000001', + '1.0000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '500000000000000000000000000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000005', + '1.0000000000000000000000000000000000000000000000000' #... + '000000000100000000000000000000000000000000000000000' #... + '000000000000000000250000000000000002000000000000000' #... + '000000000000000000000000000000000000000000010000000' #... + '000000000000000000000000000000000000000000000000000' #... + '0000000000000000001', + '1.0000000000000000000000000000000000000000000000000' #... + '000000000100000000000000000000000000000000000000000' #... + '000000000000000000249999999999999999999999999999999' #... + '999999999999979999999999999999999999999999999999999' #... + '999999999999999999999900000000000000000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '00000000000000000000000001', + + '0.9999999999999999999999999999999999999999999999999' #... + '999999999900000000000000000000000000000000000000000' #... + '000000000000000000249999999999999998000000000000000' #... + '000000000000000000000000000000000000000000010000000' #... + '000000000000000000000000000000000000000000000000000' #... + '0000000000000000001', + '0.9999999999999999999999999999999999999999999999999' #... + '999999999900000000000000000000000000000000000000000' #... + '000000000000000000250000001999999999999999999999999' #... + '999999999999999999999999999999999990000000000000000' #... + '000000000000000000000000000000000000000000000000000' #... + '1', + ] + + +TESTCASES = [ + [x for x in test_short_halfway_cases()], + [x for x in test_halfway_cases()], + [x for x in test_boundaries()], + [x for x in test_underflow_boundary()], + [x for x in test_bigcomp()], + [x for x in test_parsing()], + test_particular +] + +def un_randfloat(): + for i in range(1000): + l = random.choice(TESTCASES[:6]) + yield random.choice(l) + for v in test_particular: + yield v + +def bin_randfloat(): + for i in range(1000): + l1 = random.choice(TESTCASES) + l2 = random.choice(TESTCASES) + yield random.choice(l1), random.choice(l2) + +def tern_randfloat(): + for i in range(1000): + l1 = random.choice(TESTCASES) + l2 = random.choice(TESTCASES) + l3 = random.choice(TESTCASES) + yield random.choice(l1), random.choice(l2), random.choice(l3) + + +if __name__ == '__main__': + + for s in un_randfloat(): + print(s) + + for s in bin_randfloat(): + print(s) + + for s in tern_randfloat(): + print(s) From python-checkins at python.org Sat Jun 5 13:27:52 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 13:27:52 +0200 (CEST) Subject: [Python-checkins] r81730 - in python/branches/py3k: Lib/unittest/case.py Lib/unittest/test/test_case.py Message-ID: <20100605112752.DD66DEE9C7@mail.python.org> Author: michael.foord Date: Sat Jun 5 13:27:52 2010 New Revision: 81730 Log: Merged revisions 81728 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81728 | michael.foord | 2010-06-05 12:23:51 +0100 (Sat, 05 Jun 2010) | 1 line Issue 8351. Suppress large diffs in unittest.TestCase.assertSequenceEqual. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/case.py python/branches/py3k/Lib/unittest/test/test_case.py Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Sat Jun 5 13:27:52 2010 @@ -12,7 +12,7 @@ unorderable_list_difference) __unittest = True - +TRUNCATED_DIFF = '\n[diff truncated...]' class SkipTest(Exception): """ @@ -599,7 +599,8 @@ failUnlessRaises = _deprecate(assertRaises) failIf = _deprecate(assertFalse) - def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): + def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None, + max_diff=80*8): """An equality assertion for ordered sequences (like lists and tuples). For the purposes of this function, a valid ordered sequence type is one @@ -612,6 +613,7 @@ datatype should be enforced. msg: Optional message to use on failure instead of a list of differences. + max_diff: Maximum size off the diff, larger diffs are not shown """ if seq_type != None: seq_type_name = seq_type.__name__ @@ -694,9 +696,14 @@ except (TypeError, IndexError, NotImplementedError): differing += ('Unable to index element %d ' 'of second %s\n' % (len1, seq_type_name)) - standardMsg = differing + '\n' + '\n'.join( + standardMsg = differing + diffMsg = '\n' + '\n'.join( difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) + if max_diff is None or len(diffMsg) <= max_diff: + standardMsg += diffMsg + else: + standardMsg += diffMsg[:max_diff] + TRUNCATED_DIFF msg = self._formatMessage(msg, standardMsg) self.fail(msg) Modified: python/branches/py3k/Lib/unittest/test/test_case.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_case.py (original) +++ python/branches/py3k/Lib/unittest/test/test_case.py Sat Jun 5 13:27:52 2010 @@ -1,3 +1,5 @@ +import difflib +import pprint import re import sys @@ -589,6 +591,23 @@ self.assertRaises(self.failureException, self.assertDictEqual, [], d) self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) + def testAssertSequenceEqualMaxDiff(self): + seq1 = 'a' + 'x' * 80**2 + seq2 = 'b' + 'x' * 80**2 + diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), + pprint.pformat(seq2).splitlines())) + try: + self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)/2) + except AssertionError as e: + msg = e.args[0] + self.assertTrue(len(msg) < len(diff)) + + try: + self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)*2) + except AssertionError as e: + msg = e.args[0] + self.assertTrue(len(msg) > len(diff)) + def testAssertItemsEqual(self): a = object() self.assertItemsEqual([1, 2, 3], [3, 2, 1]) From python-checkins at python.org Sat Jun 5 13:30:23 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 13:30:23 +0200 (CEST) Subject: [Python-checkins] r81731 - python/branches/py3k/Lib/unittest/test/test_case.py Message-ID: <20100605113023.707EFEED81@mail.python.org> Author: michael.foord Date: Sat Jun 5 13:30:23 2010 New Revision: 81731 Log: Test fix to use floor division. Correction from merge in previous commit. Modified: python/branches/py3k/Lib/unittest/test/test_case.py Modified: python/branches/py3k/Lib/unittest/test/test_case.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_case.py (original) +++ python/branches/py3k/Lib/unittest/test/test_case.py Sat Jun 5 13:30:23 2010 @@ -597,7 +597,7 @@ diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) try: - self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)/2) + self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)//2) except AssertionError as e: msg = e.args[0] self.assertTrue(len(msg) < len(diff)) From python-checkins at python.org Sat Jun 5 13:33:09 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 13:33:09 +0200 (CEST) Subject: [Python-checkins] r81732 - python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/genlocale.py Message-ID: <20100605113309.2E71BEEDCF@mail.python.org> Author: stefan.krah Date: Sat Jun 5 13:33:09 2010 New Revision: 81732 Log: randint() signature changed Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/genlocale.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/genlocale.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/genlocale.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/genlocale.py Sat Jun 5 13:33:09 2010 @@ -141,7 +141,7 @@ testno += 1 printit(testno, s, fmt) for x in range(100): - s = randint(20, 425) + s = randint(20) testno += 1 printit(testno, s, fmt) From python-checkins at python.org Sat Jun 5 13:39:02 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 13:39:02 +0200 (CEST) Subject: [Python-checkins] r81733 - python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/ctx-deccheck.py Message-ID: <20100605113902.DE7E5EE9C7@mail.python.org> Author: stefan.krah Date: Sat Jun 5 13:39:02 2010 New Revision: 81733 Log: Fix minor bugs. Keep pychecker happy. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/ctx-deccheck.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/ctx-deccheck.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/ctx-deccheck.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/ctx-deccheck.py Sat Jun 5 13:39:02 2010 @@ -9,6 +9,7 @@ import cdecimal, decimal import sys, inspect from copy import copy +from randdec import * py_minor = sys.version_info[1] @@ -101,8 +102,7 @@ self.d.Emax = val def getround(self): - assert(self.f.rounding == self.d.rounding) - return self.f.rounding + return self.d.rounding def setround(self, val): self.f.rounding = val @@ -125,9 +125,9 @@ self.d._clamp = val prec = property(getprec, setprec) - emin = property(getemin, setemin) - emax = property(getemax, setemax) - round = property(getround, setround) + Emin = property(getemin, setemin) + Emax = property(getemax, setemax) + rounding = property(getround, setround) clamp = property(getclamp, setclamp) capitals = property(getcapitals, setcapitals) @@ -162,6 +162,8 @@ # We don't want exceptions so that we can compare the status flags. context = Context() +context.Emin = cdecimal.MIN_EMIN +context.Emax = cdecimal.MAX_EMAX context.clear_traps() @@ -180,7 +182,7 @@ decimal: %s\n\n" class CdecException(ArithmeticError): - def __init__(self, result, funcname, operands): + def __init__(self, result, funcname, operands, fctxstr, dctxstr): self.errstring = "Error in %s(%s" % (funcname, operands[0]) for op in operands[1:]: self.errstring += ", %s" % op @@ -197,7 +199,7 @@ str(dec_tuple)) else: self.errstring += _exc_fmt_obj % (str(result[0]), str(result[1])) - self.errstring += "%s\n%s\n\n" % (str(context.f), str(context.d)) + self.errstring += "%s\n%s\n\n" % (fctxstr, dctxstr) def __str__(self): return self.errstring @@ -306,14 +308,22 @@ __eq__ = __ne__ = __ge__ = __gt__ = __le__ = __lt__ = \ __repr__ = __str__ = default + if py_minor <= 1: + # Fixed in release31-maint, but a lot of distributed + # versions do not have the fix yet. + def is_normal(self, result, operands): + # Issue7099 + if operands[0].mpd.is_normal(): + return True + dhandler_cdec = dHandlerCdec() def cdec_known_disagreement(result, funcname, operands): return getattr(dhandler_cdec, funcname, dhandler_cdec.default)(result, operands) -#dhandler_obj = dHandlerObj() -#def obj_known_disagreement(result, funcname, operands): -# return getattr(dhandler_obj, funcname, dhandler_obj.default)(result, operands) +dhandler_obj = dHandlerObj() +def obj_known_disagreement(result, funcname, operands): + return getattr(dhandler_obj, funcname, dhandler_obj.default)(result, operands) def verify(result, funcname, operands): @@ -321,9 +331,10 @@ result[0] and result[1] as well as the context flags have the same values.""" if result[0] != result[1] or not context.assert_eq_status(): - #if obj_known_disagreement(result, funcname, operands): - # return # skip known disagreements - raise CdecException(result, funcname, operands) + if obj_known_disagreement(result, funcname, operands): + return # skip known disagreements + raise CdecException(result, funcname, operands, + str(context.f), str(context.d)) class cdec(object): @@ -361,7 +372,8 @@ not context.assert_eq_status(): if cdec_known_disagreement(self, funcname, operands): return # skip known disagreements - raise CdecException(self, funcname, operands) + raise CdecException(self, funcname, operands, + str(context.f), str(context.d)) def unaryfunc(self, funcname): "unary function returning a cdec, uses the context methods" @@ -419,9 +431,9 @@ third_dec = third.dec if funcname == 'power': if (third is not None): - c.mpd = getattr(context.f, 'powmod')(self.mpd, other_mpd, third_mpd) + c.mpd = context.f.powmod(self.mpd, other_mpd, third_mpd) else: - c.mpd = getattr(context.f, 'pow')(self.mpd, other_mpd) + c.mpd = context.f.pow(self.mpd, other_mpd) else: c.mpd = getattr(context.f, funcname)(self.mpd, other_mpd, third_mpd) c.dec = getattr(context.d, funcname)(self.dec, other_dec, third_dec) @@ -650,10 +662,10 @@ for prec in prec_lst: log(" prec: %d", prec) context.prec = prec - for round in sorted(decround): - context.round = round + for rounding in sorted(decround): + context.rounding = rounding rprec = 10**prec - exprange = cdecimal.MAX_EMAX + exprange = context.f.Emax if method in ['__int__', '__long__', '__trunc__', 'to_integral', \ 'to_integral_value', 'to_integral_value']: exprange = 9999 @@ -698,8 +710,8 @@ for prec in prec_lst: log(" prec: %d", prec) context.prec = prec - for round in sorted(decround): - context.round = round + for rounding in sorted(decround): + context.rounding = rounding for a in logical_un_incr_digits(prec, iter): try: x = cdec(a) @@ -721,11 +733,11 @@ for prec in prec_lst: log(" prec: %d", prec) context.prec = prec - for round in sorted(decround): - context.round = round - exprange = cdecimal.MAX_EMAX + for rounding in sorted(decround): + context.rounding = rounding + exprange = context.f.Emax if method in ['__pow__', '__rpow__', 'power']: - exprange = 99999 + exprange = 9999 for a, b in bin_close_to_pow10(prec, exprange, iter): try: x = cdec(a) @@ -762,8 +774,8 @@ for prec in prec_lst: log(" prec: %d", prec) context.prec = prec - for round in sorted(decround): - context.round = round + for rounding in sorted(decround): + context.rounding = rounding for a, b in logical_bin_incr_digits(prec, iter): try: x = cdec(a) @@ -786,11 +798,11 @@ for prec in prec_lst: log(" prec: %d", prec) context.prec = prec - for round in sorted(decround): - context.round = round - exprange = cdecimal.MAX_EMAX + for rounding in sorted(decround): + context.rounding = rounding + exprange = context.f.Emax if method in ['__pow__', 'power']: - exprange = 99999 + exprange = 9999 for a, b, c in tern_close_numbers(prec, exprange, -exprange, iter): try: x = cdec(a) @@ -824,8 +836,8 @@ for prec in prec_lst: log(" prec: %d", prec) context.prec = prec - for round in sorted(decround): - context.round = round + for rounding in sorted(decround): + context.rounding = rounding exprange = 384 for i in range(1000): intpart = str(random.randrange(100000000000000000000000000000000000000)) @@ -841,26 +853,23 @@ if __name__ == '__main__': - from randdec import * import time - import sys - samples = 1 - iter = 1 + iterations = 1 if '--short' in sys.argv: samples = 1 - iter = 1 + iterations = 1 elif '--medium' in sys.argv: samples = 1 - iter = None + iterations = None elif '--long' in sys.argv: samples = 5 - iter = None + iterations = None elif '--all' in sys.argv: samples = 100 - iter = None + iterations = None all_context_methods = set(dir(cdecimal.getcontext()) + dir(decimal.getcontext())) all_cdec_methods = [m for m in dir(cdec) if m in all_context_methods] @@ -907,22 +916,22 @@ for method in unary_methods: prec_lst = sorted(random.sample(range(1, 101), samples)) - test_unary(method, prec_lst, iter) + test_unary(method, prec_lst, iterations) for method in binary_methods: prec_lst = sorted(random.sample(range(1, 101), samples)) - test_binary(method, prec_lst, iter) + test_binary(method, prec_lst, iterations) for method in ternary_methods: prec_lst = sorted(random.sample(range(1, 101), samples)) - test_ternary(method, prec_lst, iter) + test_ternary(method, prec_lst, iterations) prec_lst = sorted(random.sample(range(1, 101), samples)) - test_un_logical('logical_invert', prec_lst, iter) + test_un_logical('logical_invert', prec_lst, iterations) for method in ['logical_and', 'logical_or', 'logical_xor']: prec_lst = sorted(random.sample(range(1, 101), samples)) - test_bin_logical(method, prec_lst, iter) + test_bin_logical(method, prec_lst, iterations) prec_lst = sorted(random.sample(range(1, 101), samples)) test_from_float(prec_lst) From python-checkins at python.org Sat Jun 5 13:45:31 2010 From: python-checkins at python.org (stefan.krah) Date: Sat, 5 Jun 2010 13:45:31 +0200 (CEST) Subject: [Python-checkins] r81734 - python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randdec.py Message-ID: <20100605114531.5739FEE993@mail.python.org> Author: stefan.krah Date: Sat Jun 5 13:45:31 2010 New Revision: 81734 Log: Whitespace; pychecker Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randdec.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randdec.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randdec.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randdec.py Sat Jun 5 13:45:31 2010 @@ -89,7 +89,7 @@ def randdec(maxprec, maxexp): return numeric_string(maxprec, maxexp) -def randint(maxprec, maxexp): +def randint(maxprec): return digits(maxprec) def rand_adjexp(maxprec, maxadjexp): @@ -125,11 +125,11 @@ # Close to 10**n -def un_close_to_pow10(prec, maxexp, iter=None): - if iter is None: +def un_close_to_pow10(prec, maxexp, itertns=None): + if itertns is None: lst = range(prec+30) else: - lst = random.sample(range(prec+30), iter) + lst = random.sample(range(prec+30), itertns) nines = [10**n - 1 for n in lst] pow10 = [10**n for n in lst] for coeff in nines: @@ -142,11 +142,11 @@ yield -coeff # Close to 10**n -def bin_close_to_pow10(prec, maxexp, iter=None): - if iter is None: +def bin_close_to_pow10(prec, maxexp, itertns=None): + if itertns is None: lst = range(prec+30) else: - lst = random.sample(range(prec+30), iter) + lst = random.sample(range(prec+30), itertns) nines = [10**n - 1 for n in lst] pow10 = [10**n for n in lst] for coeff in nines: @@ -167,80 +167,93 @@ # Close to 1: def close_to_one_greater(prec, emax, emin): rprec = 10**prec - return ''.join(("1.", '0'*random.randrange(prec), str(random.randrange(rprec)))) + return ''.join(("1.", '0'*random.randrange(prec), + str(random.randrange(rprec)))) def close_to_one_less(prec, emax, emin): rprec = 10**prec - return ''.join(("0.9", '9'*random.randrange(prec), str(random.randrange(rprec)))) + return ''.join(("0.9", '9'*random.randrange(prec), + str(random.randrange(rprec)))) # Close to 0: def close_to_zero_greater(prec, emax, emin): rprec = 10**prec - return ''.join(("0.", '0'*random.randrange(prec), str(random.randrange(rprec)))) + return ''.join(("0.", '0'*random.randrange(prec), + str(random.randrange(rprec)))) def close_to_zero_less(prec, emax, emin): rprec = 10**prec - return ''.join(("-0.", '0'*random.randrange(prec), str(random.randrange(rprec)))) + return ''.join(("-0.", '0'*random.randrange(prec), + str(random.randrange(rprec)))) # Close to emax: def close_to_emax_less(prec, emax, emin): rprec = 10**prec - return ''.join(("9.", '9'*random.randrange(prec), str(random.randrange(rprec)), "E", str(emax))) + return ''.join(("9.", '9'*random.randrange(prec), + str(random.randrange(rprec)), "E", str(emax))) def close_to_emax_greater(prec, emax, emin): rprec = 10**prec - return ''.join(("1.", '0'*random.randrange(prec), str(random.randrange(rprec)), "E", str(emax+1))) + return ''.join(("1.", '0'*random.randrange(prec), + str(random.randrange(rprec)), "E", str(emax+1))) # Close to emin: def close_to_emin_greater(prec, emax, emin): rprec = 10**prec - return ''.join(("1.", '0'*random.randrange(prec), str(random.randrange(rprec)), "E", str(emin))) + return ''.join(("1.", '0'*random.randrange(prec), + str(random.randrange(rprec)), "E", str(emin))) def close_to_emin_less(prec, emax, emin): rprec = 10**prec - return ''.join(("9.", '9'*random.randrange(prec), str(random.randrange(rprec)), "E", str(emin-1))) + return ''.join(("9.", '9'*random.randrange(prec), + str(random.randrange(rprec)), "E", str(emin-1))) # Close to etiny: def close_to_etiny_greater(prec, emax, emin): rprec = 10**prec etiny = emin - (prec - 1) - return ''.join(("1.", '0'*random.randrange(prec), str(random.randrange(rprec)), "E", str(etiny))) + return ''.join(("1.", '0'*random.randrange(prec), + str(random.randrange(rprec)), "E", str(etiny))) def close_to_etiny_less(prec, emax, emin): rprec = 10**prec etiny = emin - (prec - 1) - return ''.join(("9.", '9'*random.randrange(prec), str(random.randrange(rprec)), "E", str(etiny-1))) + return ''.join(("9.", '9'*random.randrange(prec), + str(random.randrange(rprec)), "E", str(etiny-1))) def close_to_min_etiny_greater(prec, max_prec, min_emin): rprec = 10**prec etiny = min_emin - (max_prec - 1) - return ''.join(("1.", '0'*random.randrange(prec), str(random.randrange(rprec)), "E", str(etiny))) + return ''.join(("1.", '0'*random.randrange(prec), + str(random.randrange(rprec)), "E", str(etiny))) def close_to_min_etiny_less(prec, max_prec, min_emin): rprec = 10**prec etiny = min_emin - (max_prec - 1) - return ''.join(("9.", '9'*random.randrange(prec), str(random.randrange(rprec)), "E", str(etiny-1))) + return ''.join(("9.", '9'*random.randrange(prec), + str(random.randrange(rprec)), "E", str(etiny-1))) close_funcs = [ - close_to_one_greater, close_to_one_less, close_to_zero_greater, close_to_zero_less, - close_to_emax_less, close_to_emax_greater, close_to_emin_greater, close_to_emin_less, - close_to_etiny_greater, close_to_etiny_less, close_to_min_etiny_greater, close_to_min_etiny_less + close_to_one_greater, close_to_one_less, close_to_zero_greater, + close_to_zero_less, close_to_emax_less, close_to_emax_greater, + close_to_emin_greater, close_to_emin_less, close_to_etiny_greater, + close_to_etiny_less, close_to_min_etiny_greater, close_to_min_etiny_less ] -def un_close_numbers(prec, emax, emin, iter=None): - if iter is None: - iter = 1000 - for i in range(iter): +def un_close_numbers(prec, emax, emin, itertns=None): + if itertns is None: + itertns = 1000 + for i in range(itertns): for func in close_funcs: yield func(prec, emax, emin) -def bin_close_numbers(prec, emax, emin, iter=None): - if iter is None: - iter = 1000 - for i in range(iter): +def bin_close_numbers(prec, emax, emin, itertns=None): + if itertns is None: + itertns = 1000 + for i in range(itertns): for func1 in close_funcs: for func2 in close_funcs: yield func1(prec, emax, emin), func2(prec, emax, emin) @@ -248,43 +261,50 @@ yield randdec(prec, emax), func(prec, emax, emin) yield func(prec, emax, emin), randdec(prec, emax) -def tern_close_numbers(prec, emax, emin, iter): - if iter is None: - iter = 1000 - for i in range(iter): +def tern_close_numbers(prec, emax, emin, itertns): + if itertns is None: + itertns = 1000 + for i in range(itertns): for func1 in close_funcs: for func2 in close_funcs: for func3 in close_funcs: - yield func1(prec, emax, emin), func2(prec, emax, emin), func3(prec, emax, emin) + yield (func1(prec, emax, emin), func2(prec, emax, emin), + func3(prec, emax, emin)) for func in close_funcs: - yield randdec(prec, emax), func(prec, emax, emin), func(prec, emax, emin) - yield func(prec, emax, emin), randdec(prec, emax), func(prec, emax, emin) - yield func(prec, emax, emin), func(prec, emax, emin), randdec(prec, emax) + yield (randdec(prec, emax), func(prec, emax, emin), + func(prec, emax, emin)) + yield (func(prec, emax, emin), randdec(prec, emax), + func(prec, emax, emin)) + yield (func(prec, emax, emin), func(prec, emax, emin), + randdec(prec, emax)) for func in close_funcs: - yield randdec(prec, emax), randdec(prec, emax), func(prec, emax, emin) - yield randdec(prec, emax), func(prec, emax, emin), randdec(prec, emax) - yield func(prec, emax, emin), randdec(prec, emax), randdec(prec, emax) + yield (randdec(prec, emax), randdec(prec, emax), + func(prec, emax, emin)) + yield (randdec(prec, emax), func(prec, emax, emin), + randdec(prec, emax)) + yield (func(prec, emax, emin), randdec(prec, emax), + randdec(prec, emax)) -# If iter == None, test all digit lengths up to prec + 30 -def un_incr_digits(prec, maxexp, iter): - if iter is None: +# If itertns == None, test all digit lengths up to prec + 30 +def un_incr_digits(prec, maxexp, itertns): + if itertns is None: lst = range(prec+30) else: - lst = random.sample(range(prec+30), iter) + lst = random.sample(range(prec+30), itertns) for m in lst: yield from_triple(1, ndigits(m), 0) yield from_triple(-1, ndigits(m), 0) yield from_triple(1, ndigits(m), random.randrange(maxexp)) yield from_triple(-1, ndigits(m), random.randrange(maxexp)) -# If iter == None, test all digit lengths up to prec + 30 +# If itertns == None, test all digit lengths up to prec + 30 # Also output decimals im tuple form. -def un_incr_digits_tuple(prec, maxexp, iter): - if iter is None: +def un_incr_digits_tuple(prec, maxexp, itertns): + if itertns is None: lst = range(prec+30) else: - lst = random.sample(range(prec+30), iter) + lst = random.sample(range(prec+30), itertns) for m in lst: yield from_triple(1, ndigits(m), 0) yield from_triple(-1, ndigits(m), 0) @@ -296,104 +316,103 @@ yield (0, tuple(map(int, str(ndigits(m)))), random.randrange(maxexp)) yield (1, tuple(map(int, str(ndigits(m)))), random.randrange(maxexp)) -# If iter == None, test all combinations of digit lengths up to prec + 30 -def bin_incr_digits(prec, maxexp, iter): - if iter is None: +# If itertns == None, test all combinations of digit lengths up to prec + 30 +def bin_incr_digits(prec, maxexp, itertns): + if itertns is None: lst1 = range(prec+30) lst2 = range(prec+30) else: - lst1 = random.sample(range(prec+30), iter) - lst2 = random.sample(range(prec+30), iter) + lst1 = random.sample(range(prec+30), itertns) + lst2 = random.sample(range(prec+30), itertns) for m in lst1: - self = from_triple(1, ndigits(m), 0) - yield self, self - self = from_triple(-1, ndigits(m), 0) - yield self, self - self = from_triple(1, ndigits(m), random.randrange(maxexp)) - yield self, self - self = from_triple(-1, ndigits(m), random.randrange(maxexp)) - yield self, self + x = from_triple(1, ndigits(m), 0) + yield x, x + x = from_triple(-1, ndigits(m), 0) + yield x, x + x = from_triple(1, ndigits(m), random.randrange(maxexp)) + yield x, x + x = from_triple(-1, ndigits(m), random.randrange(maxexp)) + yield x, x for m in lst1: for n in lst2: - self = from_triple(1, ndigits(m), 0) - other = from_triple(1, ndigits(n), 0) - yield self, other - self = from_triple(-1, ndigits(m), 0) - other = from_triple(1, ndigits(n), 0) - yield self, other - self = from_triple(1, ndigits(m), 0) - other = from_triple(-1, ndigits(n), 0) - yield self, other - self = from_triple(-1, ndigits(m), 0) - other = from_triple(-1, ndigits(n), 0) - yield self, other - self = from_triple(1, ndigits(m), random.randrange(maxexp)) - other = from_triple(1, ndigits(n), random.randrange(maxexp)) - yield self, other - self = from_triple(-1, ndigits(m), random.randrange(maxexp)) - other = from_triple(1, ndigits(n), random.randrange(maxexp)) - yield self, other - self = from_triple(1, ndigits(m), random.randrange(maxexp)) - other = from_triple(-1, ndigits(n), random.randrange(maxexp)) - yield self, other - self = from_triple(-1, ndigits(m), random.randrange(maxexp)) - other = from_triple(-1, ndigits(n), random.randrange(maxexp)) - yield self, other + x = from_triple(1, ndigits(m), 0) + y = from_triple(1, ndigits(n), 0) + yield x, y + x = from_triple(-1, ndigits(m), 0) + y = from_triple(1, ndigits(n), 0) + yield x, y + x = from_triple(1, ndigits(m), 0) + y = from_triple(-1, ndigits(n), 0) + yield x, y + x = from_triple(-1, ndigits(m), 0) + y = from_triple(-1, ndigits(n), 0) + yield x, y + x = from_triple(1, ndigits(m), random.randrange(maxexp)) + y = from_triple(1, ndigits(n), random.randrange(maxexp)) + yield x, y + x = from_triple(-1, ndigits(m), random.randrange(maxexp)) + y = from_triple(1, ndigits(n), random.randrange(maxexp)) + yield x, y + x = from_triple(1, ndigits(m), random.randrange(maxexp)) + y = from_triple(-1, ndigits(n), random.randrange(maxexp)) + yield x, y + x = from_triple(-1, ndigits(m), random.randrange(maxexp)) + y = from_triple(-1, ndigits(n), random.randrange(maxexp)) + yield x, y def randsign(): return (1, -1)[random.randrange(2)] -# If iter == None, test all combinations of digit lengths up to prec + 30 -def tern_incr_digits(prec, maxexp, iter): - if iter is None: +# If itertns == None, test all combinations of digit lengths up to prec + 30 +def tern_incr_digits(prec, maxexp, itertns): + if itertns is None: lst1 = range(prec+30) lst2 = range(prec+30) lst3 = range(prec+30) else: - lst1 = random.sample(range(prec+30), iter) - lst2 = random.sample(range(prec+30), iter) - lst3 = random.sample(range(prec+30), iter) + lst1 = random.sample(range(prec+30), itertns) + lst2 = random.sample(range(prec+30), itertns) + lst3 = random.sample(range(prec+30), itertns) for m in lst1: for n in lst2: for p in lst3: - self = from_triple(randsign(), ndigits(m), 0) - other = from_triple(randsign(), ndigits(n), 0) - third = from_triple(randsign(), ndigits(p), 0) - yield self, other, third + x = from_triple(randsign(), ndigits(m), 0) + y = from_triple(randsign(), ndigits(n), 0) + z = from_triple(randsign(), ndigits(p), 0) + yield x, y, z -# Tests for the 'logical' fucntions +# Tests for the 'logical' functions def bindigits(prec): z = 0 for i in range(prec): z += random.randrange(2) * 10**i return z -def logical_un_incr_digits(prec, iter): - if iter is None: +def logical_un_incr_digits(prec, itertns): + if itertns is None: lst = range(prec+30) else: - lst = random.sample(range(prec+30), iter) + lst = random.sample(range(prec+30), itertns) for m in lst: - self = from_triple(1, bindigits(m), 0) - yield self + yield from_triple(1, bindigits(m), 0) -def logical_bin_incr_digits(prec, iter): - if iter is None: +def logical_bin_incr_digits(prec, itertns): + if itertns is None: lst1 = range(prec+30) lst2 = range(prec+30) else: - lst1 = random.sample(range(prec+30), iter) - lst2 = random.sample(range(prec+30), iter) + lst1 = random.sample(range(prec+30), itertns) + lst2 = random.sample(range(prec+30), itertns) for m in lst1: - self = from_triple(1, bindigits(m), 0) - yield self, self + x = from_triple(1, bindigits(m), 0) + yield x, x for m in lst1: for n in lst2: - self = from_triple(1, bindigits(m), 0) - other = from_triple(1, bindigits(n), 0) - yield self, other + x = from_triple(1, bindigits(m), 0) + y = from_triple(1, bindigits(n), 0) + yield x, y py_major = sys.version_info[0] @@ -435,7 +454,6 @@ # Generate random format strings # [[fill]align][sign][#][0][width][.precision][type] -import string def rand_format(fill): active = sorted(random.sample(range(7), random.randrange(8))) have_align = 0 From python-checkins at python.org Sat Jun 5 13:46:59 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 13:46:59 +0200 (CEST) Subject: [Python-checkins] r81735 - python/trunk/Lib/unittest/case.py Message-ID: <20100605114659.BCA5BEE993@mail.python.org> Author: michael.foord Date: Sat Jun 5 13:46:59 2010 New Revision: 81735 Log: Extract error message truncating into a method (unittest.TestCase._truncateMessage). Modified: python/trunk/Lib/unittest/case.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Sat Jun 5 13:46:59 2010 @@ -690,13 +690,15 @@ diffMsg = '\n' + '\n'.join( difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) - if max_diff is None or len(diffMsg) <= max_diff: - standardMsg += diffMsg - else: - standardMsg += diffMsg[:max_diff] + TRUNCATED_DIFF + standardMsg = self._truncateMessage(standardMsg, diffMsg, max_diff) msg = self._formatMessage(msg, standardMsg) self.fail(msg) + def _truncateMessage(self, message, diff, max_diff): + if max_diff is None or len(diff) <= max_diff: + return message + diff + return message + diff[:max_diff] + TRUNCATED_DIFF + def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. From python-checkins at python.org Sat Jun 5 13:52:24 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 13:52:24 +0200 (CEST) Subject: [Python-checkins] r81736 - in python/trunk: Lib/test/test_descr.py Misc/NEWS Objects/typeobject.c Message-ID: <20100605115224.A74F4EE9C7@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 13:52:24 2010 New Revision: 81736 Log: Issue #8627: remove out-of-date warning about overriding __cmp__ Modified: python/trunk/Lib/test/test_descr.py python/trunk/Misc/NEWS python/trunk/Objects/typeobject.c Modified: python/trunk/Lib/test/test_descr.py ============================================================================== --- python/trunk/Lib/test/test_descr.py (original) +++ python/trunk/Lib/test/test_descr.py Sat Jun 5 13:52:24 2010 @@ -4621,7 +4621,6 @@ deprecations += [ ("classic (int|long) division", DeprecationWarning), ("coerce.. not supported", DeprecationWarning), - ("Overriding __cmp__ ", DeprecationWarning), (".+__(get|set|del)slice__ has been removed", DeprecationWarning)] with test_support.check_warnings(*deprecations): # Run all local test cases, with PTypesLongInitTest first. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Jun 5 13:52:24 2010 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #8627: Remove bogus "Overriding __cmp__ blocks inheritance of + __hash__ in 3.x" warning. + - Issue #8748: Fix two issues with comparisons between complex and integer objects. (1) The comparison could incorrectly return True in some cases (2**53+1 == complex(2**53) == 2**53), breaking transivity of equality. Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Sat Jun 5 13:52:24 2010 @@ -3723,7 +3723,6 @@ } #define OVERRIDES_HASH(x) overrides_name(x, "__hash__") -#define OVERRIDES_CMP(x) overrides_name(x, "__cmp__") #define OVERRIDES_EQ(x) overrides_name(x, "__eq__") static void @@ -3869,12 +3868,6 @@ if (base->tp_hash && (base->tp_hash != PyObject_HashNotImplemented) && !OVERRIDES_HASH(type)) { - if (OVERRIDES_CMP(type)) { - PyErr_WarnPy3k("Overriding " - "__cmp__ blocks inheritance " - "of __hash__ in 3.x", - 1); - } if (OVERRIDES_EQ(type)) { PyErr_WarnPy3k("Overriding " "__eq__ blocks inheritance " From python-checkins at python.org Sat Jun 5 13:53:12 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 13:53:12 +0200 (CEST) Subject: [Python-checkins] r81737 - python/branches/py3k Message-ID: <20100605115312.221DAEE9C7@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 13:53:11 2010 New Revision: 81737 Log: Blocked revisions 81736 via svnmerge ........ r81736 | mark.dickinson | 2010-06-05 12:52:24 +0100 (Sat, 05 Jun 2010) | 1 line Issue #8627: remove out-of-date warning about overriding __cmp__ ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Jun 5 13:59:41 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 13:59:41 +0200 (CEST) Subject: [Python-checkins] r81738 - in python/branches/release26-maint: Misc/NEWS Objects/typeobject.c Message-ID: <20100605115941.46D7CEE9C7@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 13:59:41 2010 New Revision: 81738 Log: Merged revisions 81736 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81736 | mark.dickinson | 2010-06-05 12:52:24 +0100 (Sat, 05 Jun 2010) | 1 line Issue #8627: remove out-of-date warning about overriding __cmp__ ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/typeobject.c Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Jun 5 13:59:41 2010 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #8627: Remove bogus "Overriding __cmp__ blocks inheritance of + __hash__ in 3.x" warning. + - Issue #3798: Write sys.exit() message to sys.stderr to use stderr encoding and error handler, instead of writing to the C stderr file in utf-8 Modified: python/branches/release26-maint/Objects/typeobject.c ============================================================================== --- python/branches/release26-maint/Objects/typeobject.c (original) +++ python/branches/release26-maint/Objects/typeobject.c Sat Jun 5 13:59:41 2010 @@ -3707,7 +3707,6 @@ } #define OVERRIDES_HASH(x) overrides_name(x, "__hash__") -#define OVERRIDES_CMP(x) overrides_name(x, "__cmp__") #define OVERRIDES_EQ(x) overrides_name(x, "__eq__") static void @@ -3853,12 +3852,6 @@ if (base->tp_hash && (base->tp_hash != PyObject_HashNotImplemented) && !OVERRIDES_HASH(type)) { - if (OVERRIDES_CMP(type)) { - PyErr_WarnPy3k("Overriding " - "__cmp__ blocks inheritance " - "of __hash__ in 3.x", - 1); - } if (OVERRIDES_EQ(type)) { PyErr_WarnPy3k("Overriding " "__eq__ blocks inheritance " From python-checkins at python.org Sat Jun 5 14:10:52 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 14:10:52 +0200 (CEST) Subject: [Python-checkins] r81739 - in python/trunk/Lib/unittest: case.py test/test_case.py Message-ID: <20100605121052.74F97EE9CE@mail.python.org> Author: michael.foord Date: Sat Jun 5 14:10:52 2010 New Revision: 81739 Log: Removed the new max_diff argument to assertSequenceEqual. All unittest.TestCase assert methods that use difflib to produce failure messages now truncate overly long messages. New class attribute unittest.TestCase.maxDiff to configure this if necessary. Issue 8351. Modified: python/trunk/Lib/unittest/case.py python/trunk/Lib/unittest/test/test_case.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Sat Jun 5 14:10:52 2010 @@ -13,7 +13,6 @@ ) __unittest = True -TRUNCATED_DIFF = '\n[diff truncated...]' class SkipTest(Exception): """ @@ -157,6 +156,11 @@ longMessage = False + # This attribute sets the maximum length of a diff in failure messsages + # by assert methods using difflib. It is looked up as an instance attribute + # so can be configured by individual tests if required. + maxDiff = 80*8 + # Attribute used by TestSuite for classSetUp _classSetupFailed = False @@ -589,8 +593,7 @@ failUnlessRaises = _deprecate(assertRaises) failIf = _deprecate(assertFalse) - def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None, - max_diff=80*8): + def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): """An equality assertion for ordered sequences (like lists and tuples). For the purposes of this function, a valid ordered sequence type is one @@ -603,7 +606,6 @@ datatype should be enforced. msg: Optional message to use on failure instead of a list of differences. - max_diff: Maximum size off the diff, larger diffs are not shown """ if seq_type is not None: seq_type_name = seq_type.__name__ @@ -690,14 +692,15 @@ diffMsg = '\n' + '\n'.join( difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) - standardMsg = self._truncateMessage(standardMsg, diffMsg, max_diff) + standardMsg = self._truncateMessage(standardMsg, diffMsg) msg = self._formatMessage(msg, standardMsg) self.fail(msg) - def _truncateMessage(self, message, diff, max_diff): + def _truncateMessage(self, message, diff): + max_diff = self.maxDiff if max_diff is None or len(diff) <= max_diff: return message + diff - return message + diff[:max_diff] + TRUNCATED_DIFF + return message def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. @@ -797,9 +800,10 @@ self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') if d1 != d2: - standardMsg = ('\n' + '\n'.join(difflib.ndiff( + diff = ('\n' + '\n'.join(difflib.ndiff( pprint.pformat(d1).splitlines(), pprint.pformat(d2).splitlines()))) + standardMsg = self._truncateMessage('', diff) self.fail(self._formatMessage(msg, standardMsg)) def assertDictContainsSubset(self, expected, actual, msg=None): @@ -882,8 +886,9 @@ 'Second argument is not a string')) if first != second: - standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), + diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) + standardMsg = self._truncateMessage('', diff) self.fail(self._formatMessage(msg, standardMsg)) def assertLess(self, a, b, msg=None): Modified: python/trunk/Lib/unittest/test/test_case.py ============================================================================== --- python/trunk/Lib/unittest/test/test_case.py (original) +++ python/trunk/Lib/unittest/test/test_case.py Sat Jun 5 14:10:52 2010 @@ -591,20 +591,37 @@ self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) def testAssertSequenceEqualMaxDiff(self): + self.assertEqual(self.maxDiff, 80*8) seq1 = 'a' + 'x' * 80**2 seq2 = 'b' + 'x' * 80**2 diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) + + self.maxDiff = len(diff)//2 try: - self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)/2) - except AssertionError as e: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) < len(diff)) + self.maxDiff = len(diff) * 2 + try: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: + msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') + self.assertTrue(len(msg) > len(diff)) + + self.maxDiff = None try: - self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)*2) - except AssertionError as e: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) > len(diff)) def testAssertItemsEqual(self): From python-checkins at python.org Sat Jun 5 14:14:43 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 14:14:43 +0200 (CEST) Subject: [Python-checkins] r81740 - in python/trunk: Misc/NEWS Objects/typeobject.c Message-ID: <20100605121443.C8502EE9CE@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 14:14:43 2010 New Revision: 81740 Log: Issue #8627: Fix "XXX undetected error" from unchecked PyErr_WarnPy3k return. This is just a quick fix: if the warning is turned into an exception, the exception simply gets ignored. Modified: python/trunk/Misc/NEWS python/trunk/Objects/typeobject.c Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Jun 5 14:14:43 2010 @@ -13,7 +13,10 @@ ----------------- - Issue #8627: Remove bogus "Overriding __cmp__ blocks inheritance of - __hash__ in 3.x" warning. + __hash__ in 3.x" warning. Also fix "XXX undetected error" that + arises from the "Overriding __eq__ blocks inheritance ..." warning + when turned into an exception: in this case the exception simply + gets ignored. - Issue #8748: Fix two issues with comparisons between complex and integer objects. (1) The comparison could incorrectly return True in some cases Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Sat Jun 5 14:14:43 2010 @@ -3869,10 +3869,16 @@ (base->tp_hash != PyObject_HashNotImplemented) && !OVERRIDES_HASH(type)) { if (OVERRIDES_EQ(type)) { - PyErr_WarnPy3k("Overriding " - "__eq__ blocks inheritance " - "of __hash__ in 3.x", - 1); + if (PyErr_WarnPy3k("Overriding " + "__eq__ blocks inheritance " + "of __hash__ in 3.x", + 1) < 0) + /* XXX This isn't right. If the warning is turned + into an exception, we should be communicating + the error back to the caller, but figuring out + how to clean-up in that case is tricky. See + issue 8627 for more. */ + PyErr_Clear(); } } } From python-checkins at python.org Sat Jun 5 14:15:36 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 14:15:36 +0200 (CEST) Subject: [Python-checkins] r81741 - in python/branches/release26-maint: Misc/NEWS Objects/typeobject.c Message-ID: <20100605121536.04B16EE9CE@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 14:15:35 2010 New Revision: 81741 Log: Merged revisions 81740 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81740 | mark.dickinson | 2010-06-05 13:14:43 +0100 (Sat, 05 Jun 2010) | 5 lines Issue #8627: Fix "XXX undetected error" from unchecked PyErr_WarnPy3k return. This is just a quick fix: if the warning is turned into an exception, the exception simply gets ignored. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/typeobject.c Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Jun 5 14:15:35 2010 @@ -13,7 +13,10 @@ ----------------- - Issue #8627: Remove bogus "Overriding __cmp__ blocks inheritance of - __hash__ in 3.x" warning. + __hash__ in 3.x" warning. Also fix "XXX undetected error" that + arises from the "Overriding __eq__ blocks inheritance ..." warning + when turned into an exception: in this case the exception simply + gets ignored. - Issue #3798: Write sys.exit() message to sys.stderr to use stderr encoding and error handler, instead of writing to the C stderr file in utf-8 Modified: python/branches/release26-maint/Objects/typeobject.c ============================================================================== --- python/branches/release26-maint/Objects/typeobject.c (original) +++ python/branches/release26-maint/Objects/typeobject.c Sat Jun 5 14:15:35 2010 @@ -3853,10 +3853,16 @@ (base->tp_hash != PyObject_HashNotImplemented) && !OVERRIDES_HASH(type)) { if (OVERRIDES_EQ(type)) { - PyErr_WarnPy3k("Overriding " - "__eq__ blocks inheritance " - "of __hash__ in 3.x", - 1); + if (PyErr_WarnPy3k("Overriding " + "__eq__ blocks inheritance " + "of __hash__ in 3.x", + 1) < 0) + /* XXX This isn't right. If the warning is turned + into an exception, we should be communicating + the error back to the caller, but figuring out + how to clean-up in that case is tricky. See + issue 8627 for more. */ + PyErr_Clear(); } } } From python-checkins at python.org Sat Jun 5 14:17:02 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 14:17:02 +0200 (CEST) Subject: [Python-checkins] r81742 - in python/branches/py3k: Lib/unittest/case.py Lib/unittest/test/test_case.py Message-ID: <20100605121702.9972CEE9CE@mail.python.org> Author: michael.foord Date: Sat Jun 5 14:17:02 2010 New Revision: 81742 Log: Merged revisions 81739 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81739 | michael.foord | 2010-06-05 13:10:52 +0100 (Sat, 05 Jun 2010) | 1 line Removed the new max_diff argument to assertSequenceEqual. All unittest.TestCase assert methods that use difflib to produce failure messages now truncate overly long messages. New class attribute unittest.TestCase.maxDiff to configure this if necessary. Issue 8351. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/case.py python/branches/py3k/Lib/unittest/test/test_case.py Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Sat Jun 5 14:17:02 2010 @@ -12,7 +12,6 @@ unorderable_list_difference) __unittest = True -TRUNCATED_DIFF = '\n[diff truncated...]' class SkipTest(Exception): """ @@ -169,6 +168,11 @@ longMessage = False + # This attribute sets the maximum length of a diff in failure messsages + # by assert methods using difflib. It is looked up as an instance attribute + # so can be configured by individual tests if required. + maxDiff = 80*8 + # Attribute used by TestSuite for classSetUp _classSetupFailed = False @@ -599,8 +603,7 @@ failUnlessRaises = _deprecate(assertRaises) failIf = _deprecate(assertFalse) - def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None, - max_diff=80*8): + def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): """An equality assertion for ordered sequences (like lists and tuples). For the purposes of this function, a valid ordered sequence type is one @@ -613,7 +616,6 @@ datatype should be enforced. msg: Optional message to use on failure instead of a list of differences. - max_diff: Maximum size off the diff, larger diffs are not shown """ if seq_type != None: seq_type_name = seq_type.__name__ @@ -700,13 +702,17 @@ diffMsg = '\n' + '\n'.join( difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) - if max_diff is None or len(diffMsg) <= max_diff: - standardMsg += diffMsg - else: - standardMsg += diffMsg[:max_diff] + TRUNCATED_DIFF + + standardMsg = self._truncateMessage(standardMsg, diffMsg) msg = self._formatMessage(msg, standardMsg) self.fail(msg) + def _truncateMessage(self, message, diff): + max_diff = self.maxDiff + if max_diff is None or len(diff) <= max_diff: + return message + diff + return message + def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. @@ -805,9 +811,10 @@ self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') if d1 != d2: - standardMsg = ('\n' + '\n'.join(difflib.ndiff( + diff = ('\n' + '\n'.join(difflib.ndiff( pprint.pformat(d1).splitlines(), pprint.pformat(d2).splitlines()))) + standardMsg = self._truncateMessage('', diff) self.fail(self._formatMessage(msg, standardMsg)) def assertDictContainsSubset(self, expected, actual, msg=None): @@ -924,8 +931,9 @@ 'Second argument is not a string')) if first != second: - standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), + diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) + standardMsg = self._truncateMessage('', diff) self.fail(self._formatMessage(msg, standardMsg)) def assertLess(self, a, b, msg=None): Modified: python/branches/py3k/Lib/unittest/test/test_case.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_case.py (original) +++ python/branches/py3k/Lib/unittest/test/test_case.py Sat Jun 5 14:17:02 2010 @@ -592,20 +592,38 @@ self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) def testAssertSequenceEqualMaxDiff(self): + self.assertEqual(self.maxDiff, 80*8) seq1 = 'a' + 'x' * 80**2 seq2 = 'b' + 'x' * 80**2 diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) + + self.maxDiff = len(diff)//2 try: - self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)//2) - except AssertionError as e: + + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) < len(diff)) + self.maxDiff = len(diff) * 2 try: - self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)*2) - except AssertionError as e: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: + msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') + self.assertTrue(len(msg) > len(diff)) + + self.maxDiff = None + try: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) > len(diff)) def testAssertItemsEqual(self): From python-checkins at python.org Sat Jun 5 14:38:00 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 14:38:00 +0200 (CEST) Subject: [Python-checkins] r81743 - python/branches/py3k Message-ID: <20100605123800.7820AEE9E8@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 14:38:00 2010 New Revision: 81743 Log: Blocked revisions 81740 via svnmerge ........ r81740 | mark.dickinson | 2010-06-05 13:14:43 +0100 (Sat, 05 Jun 2010) | 5 lines Issue #8627: Fix "XXX undetected error" from unchecked PyErr_WarnPy3k return. This is just a quick fix: if the warning is turned into an exception, the exception simply gets ignored. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Jun 5 14:51:21 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 14:51:21 +0200 (CEST) Subject: [Python-checkins] r81744 - python/trunk/Objects/typeobject.c Message-ID: <20100605125121.DEC74EE9C7@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 14:51:21 2010 New Revision: 81744 Log: Fix comment typo. Modified: python/trunk/Objects/typeobject.c Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Sat Jun 5 14:51:21 2010 @@ -3876,7 +3876,7 @@ /* XXX This isn't right. If the warning is turned into an exception, we should be communicating the error back to the caller, but figuring out - how to clean-up in that case is tricky. See + how to clean up in that case is tricky. See issue 8627 for more. */ PyErr_Clear(); } From python-checkins at python.org Sat Jun 5 14:52:03 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 14:52:03 +0200 (CEST) Subject: [Python-checkins] r81745 - in python/branches/release26-maint: Objects/typeobject.c Message-ID: <20100605125203.29A20EE9C7@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 14:52:03 2010 New Revision: 81745 Log: Merged revisions 81744 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81744 | mark.dickinson | 2010-06-05 13:51:21 +0100 (Sat, 05 Jun 2010) | 1 line Fix comment typo. ........ 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 Sat Jun 5 14:52:03 2010 @@ -3860,7 +3860,7 @@ /* XXX This isn't right. If the warning is turned into an exception, we should be communicating the error back to the caller, but figuring out - how to clean-up in that case is tricky. See + how to clean up in that case is tricky. See issue 8627 for more. */ PyErr_Clear(); } From python-checkins at python.org Sat Jun 5 14:52:23 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 14:52:23 +0200 (CEST) Subject: [Python-checkins] r81746 - python/branches/py3k Message-ID: <20100605125223.3E591EE9C7@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 14:52:23 2010 New Revision: 81746 Log: Blocked revisions 81744 via svnmerge ........ r81744 | mark.dickinson | 2010-06-05 13:51:21 +0100 (Sat, 05 Jun 2010) | 1 line Fix comment typo. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Jun 5 14:58:39 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 14:58:39 +0200 (CEST) Subject: [Python-checkins] r81747 - in python/trunk/Lib/unittest: case.py util.py Message-ID: <20100605125839.63890EE9C7@mail.python.org> Author: michael.foord Date: Sat Jun 5 14:58:39 2010 New Revision: 81747 Log: unittest.TestCase.assertDictEqual and assertMultilineEqual provide better default failure messages in the event of long diffs. Modified: python/trunk/Lib/unittest/case.py python/trunk/Lib/unittest/util.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Sat Jun 5 14:58:39 2010 @@ -800,10 +800,11 @@ self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') if d1 != d2: + standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) diff = ('\n' + '\n'.join(difflib.ndiff( pprint.pformat(d1).splitlines(), pprint.pformat(d2).splitlines()))) - standardMsg = self._truncateMessage('', diff) + standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertDictContainsSubset(self, expected, actual, msg=None): @@ -886,9 +887,10 @@ 'Second argument is not a string')) if first != second: + standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) - standardMsg = self._truncateMessage('', diff) + standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertLess(self, a, b, msg=None): Modified: python/trunk/Lib/unittest/util.py ============================================================================== --- python/trunk/Lib/unittest/util.py (original) +++ python/trunk/Lib/unittest/util.py Sat Jun 5 14:58:39 2010 @@ -2,12 +2,16 @@ __unittest = True - -def safe_repr(obj): +_MAX_LENGTH = 80 +def safe_repr(obj, short=False): try: - return repr(obj) + result = repr(obj) except Exception: - return object.__repr__(obj) + result = object.__repr__(obj) + if not short or len(result) < _MAX_LENGTH: + return result + return result[:_MAX_LENGTH] + ' [truncated]...' + def strclass(cls): return "%s.%s" % (cls.__module__, cls.__name__) From python-checkins at python.org Sat Jun 5 15:14:43 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 15:14:43 +0200 (CEST) Subject: [Python-checkins] r81748 - in python/branches/py3k: Lib/unittest/case.py Lib/unittest/util.py Message-ID: <20100605131443.42224EE9C3@mail.python.org> Author: michael.foord Date: Sat Jun 5 15:14:43 2010 New Revision: 81748 Log: Merged revisions 81747 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81747 | michael.foord | 2010-06-05 13:58:39 +0100 (Sat, 05 Jun 2010) | 1 line unittest.TestCase.assertDictEqual and assertMultilineEqual provide better default failure messages in the event of long diffs. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/case.py python/branches/py3k/Lib/unittest/util.py Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Sat Jun 5 15:14:43 2010 @@ -811,10 +811,11 @@ self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') if d1 != d2: + standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) diff = ('\n' + '\n'.join(difflib.ndiff( pprint.pformat(d1).splitlines(), pprint.pformat(d2).splitlines()))) - standardMsg = self._truncateMessage('', diff) + standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertDictContainsSubset(self, expected, actual, msg=None): @@ -931,9 +932,10 @@ 'Second argument is not a string')) if first != second: + standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) - standardMsg = self._truncateMessage('', diff) + standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertLess(self, a, b, msg=None): Modified: python/branches/py3k/Lib/unittest/util.py ============================================================================== --- python/branches/py3k/Lib/unittest/util.py (original) +++ python/branches/py3k/Lib/unittest/util.py Sat Jun 5 15:14:43 2010 @@ -2,12 +2,16 @@ __unittest = True - -def safe_repr(obj): +_MAX_LENGTH = 80 +def safe_repr(obj, short=False): try: - return repr(obj) + result = repr(obj) except Exception: - return object.__repr__(obj) + result = object.__repr__(obj) + if not short or len(result) < _MAX_LENGTH: + return result + return result[:_MAX_LENGTH] + ' [truncated]...' + def strclass(cls): return "%s.%s" % (cls.__module__, cls.__name__) From python-checkins at python.org Sat Jun 5 15:18:34 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 15:18:34 +0200 (CEST) Subject: [Python-checkins] r81749 - python/trunk/Lib/test/test_py3kwarn.py Message-ID: <20100605131834.0EF38EE9CE@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 15:18:33 2010 New Revision: 81749 Log: Fix test_py3kwarn not to test for __cmp__-related DeprecationWarning. Modified: python/trunk/Lib/test/test_py3kwarn.py Modified: python/trunk/Lib/test/test_py3kwarn.py ============================================================================== --- python/trunk/Lib/test/test_py3kwarn.py (original) +++ python/trunk/Lib/test/test_py3kwarn.py Sat Jun 5 15:18:33 2010 @@ -251,9 +251,7 @@ # With object as the base class class WarnOnlyCmp(object): def __cmp__(self, other): pass - self.assertEqual(len(w.warnings), 1) - self.assertWarning(None, w, - "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") + self.assertEqual(len(w.warnings), 0) w.reset() class WarnOnlyEq(object): def __eq__(self, other): pass @@ -264,9 +262,7 @@ class WarnCmpAndEq(object): def __cmp__(self, other): pass def __eq__(self, other): pass - self.assertEqual(len(w.warnings), 2) - self.assertWarning(None, w.warnings[0], - "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") + self.assertEqual(len(w.warnings), 1) self.assertWarning(None, w, "Overriding __eq__ blocks inheritance of __hash__ in 3.x") w.reset() @@ -280,9 +276,7 @@ def __hash__(self): pass class WarnOnlyCmp(DefinesAllThree): def __cmp__(self, other): pass - self.assertEqual(len(w.warnings), 1) - self.assertWarning(None, w, - "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") + self.assertEqual(len(w.warnings), 0) w.reset() class WarnOnlyEq(DefinesAllThree): def __eq__(self, other): pass @@ -293,9 +287,7 @@ class WarnCmpAndEq(DefinesAllThree): def __cmp__(self, other): pass def __eq__(self, other): pass - self.assertEqual(len(w.warnings), 2) - self.assertWarning(None, w.warnings[0], - "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") + self.assertEqual(len(w.warnings), 1) self.assertWarning(None, w, "Overriding __eq__ blocks inheritance of __hash__ in 3.x") w.reset() From python-checkins at python.org Sat Jun 5 15:24:04 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 15:24:04 +0200 (CEST) Subject: [Python-checkins] r81750 - in python/branches/release26-maint: Lib/test/test_py3kwarn.py Message-ID: <20100605132404.BCFD5EE9E8@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 15:24:04 2010 New Revision: 81750 Log: Merged revisions 81749 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81749 | mark.dickinson | 2010-06-05 14:18:33 +0100 (Sat, 05 Jun 2010) | 2 lines Fix test_py3kwarn not to test for __cmp__-related DeprecationWarning. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_py3kwarn.py Modified: python/branches/release26-maint/Lib/test/test_py3kwarn.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_py3kwarn.py (original) +++ python/branches/release26-maint/Lib/test/test_py3kwarn.py Sat Jun 5 15:24:04 2010 @@ -248,9 +248,7 @@ # With object as the base class class WarnOnlyCmp(object): def __cmp__(self, other): pass - self.assertEqual(len(w.warnings), 1) - self.assertWarning(None, w, - "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") + self.assertEqual(len(w.warnings), 0) w.reset() class WarnOnlyEq(object): def __eq__(self, other): pass @@ -261,9 +259,7 @@ class WarnCmpAndEq(object): def __cmp__(self, other): pass def __eq__(self, other): pass - self.assertEqual(len(w.warnings), 2) - self.assertWarning(None, w.warnings[0], - "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") + self.assertEqual(len(w.warnings), 1) self.assertWarning(None, w, "Overriding __eq__ blocks inheritance of __hash__ in 3.x") w.reset() @@ -277,9 +273,7 @@ def __hash__(self): pass class WarnOnlyCmp(DefinesAllThree): def __cmp__(self, other): pass - self.assertEqual(len(w.warnings), 1) - self.assertWarning(None, w, - "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") + self.assertEqual(len(w.warnings), 0) w.reset() class WarnOnlyEq(DefinesAllThree): def __eq__(self, other): pass @@ -290,9 +284,7 @@ class WarnCmpAndEq(DefinesAllThree): def __cmp__(self, other): pass def __eq__(self, other): pass - self.assertEqual(len(w.warnings), 2) - self.assertWarning(None, w.warnings[0], - "Overriding __cmp__ blocks inheritance of __hash__ in 3.x") + self.assertEqual(len(w.warnings), 1) self.assertWarning(None, w, "Overriding __eq__ blocks inheritance of __hash__ in 3.x") w.reset() From python-checkins at python.org Sat Jun 5 15:27:17 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 5 Jun 2010 15:27:17 +0200 (CEST) Subject: [Python-checkins] r81751 - python/branches/py3k Message-ID: <20100605132717.463DFEE9E0@mail.python.org> Author: mark.dickinson Date: Sat Jun 5 15:27:17 2010 New Revision: 81751 Log: Blocked revisions 81749 via svnmerge ........ r81749 | mark.dickinson | 2010-06-05 14:18:33 +0100 (Sat, 05 Jun 2010) | 2 lines Fix test_py3kwarn not to test for __cmp__-related DeprecationWarning. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Jun 5 15:38:17 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 15:38:17 +0200 (CEST) Subject: [Python-checkins] r81752 - python/trunk/Lib/unittest/case.py Message-ID: <20100605133817.1FFC4F5EF@mail.python.org> Author: michael.foord Date: Sat Jun 5 15:38:16 2010 New Revision: 81752 Log: unittest.TestCase assertion methods inform you when they have omitted an over long diff on failure. Issue 8351. Modified: python/trunk/Lib/unittest/case.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Sat Jun 5 15:38:16 2010 @@ -14,6 +14,10 @@ __unittest = True + +DIFF_OMITTED = ('\nDiff is %s characters long. ' + 'Set self.maxDiff to None to see it.') + class SkipTest(Exception): """ Raise this exception in a test to skip it. @@ -700,7 +704,7 @@ max_diff = self.maxDiff if max_diff is None or len(diff) <= max_diff: return message + diff - return message + return message + (DIFF_OMITTED % len(diff)) def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. From python-checkins at python.org Sat Jun 5 15:48:27 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 15:48:27 +0200 (CEST) Subject: [Python-checkins] r81753 - in python/trunk/Lib/unittest: case.py test/test_case.py Message-ID: <20100605134827.69F29EEA4D@mail.python.org> Author: michael.foord Date: Sat Jun 5 15:48:27 2010 New Revision: 81753 Log: Fix unittest tests after previous commit. Modified: python/trunk/Lib/unittest/case.py python/trunk/Lib/unittest/test/test_case.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Sat Jun 5 15:48:27 2010 @@ -891,7 +891,7 @@ 'Second argument is not a string')) if first != second: - standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) + standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True)) diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) standardMsg = self._truncateMessage(standardMsg, diff) Modified: python/trunk/Lib/unittest/test/test_case.py ============================================================================== --- python/trunk/Lib/unittest/test/test_case.py (original) +++ python/trunk/Lib/unittest/test/test_case.py Sat Jun 5 15:48:27 2010 @@ -807,7 +807,7 @@ A test case is the smallest unit of testing. [...] You may provide your own implementation that does not subclass from TestCase, of course. """ - sample_text_error = b""" + sample_text_error = b"""\ - http://www.python.org/doc/2.3/lib/module-unittest.html ? ^ + http://www.python.org/doc/2.4.1/lib/module-unittest.html @@ -818,15 +818,18 @@ ? +++++++++++++++++++++ + own implementation that does not subclass from TestCase, of course. """ - + self.maxDiff = None for type_changer in (lambda x: x, lambda x: x.decode('utf8')): try: self.assertMultiLineEqual(type_changer(sample_text), type_changer(revised_sample_text)) except self.failureException, e: + # need to remove the first line of the error message + error = str(e).encode('utf8').split('\n', 1)[1] + # assertMultiLineEqual is hooked up as the default for # unicode strings - so we can't use it for this check - self.assertTrue(sample_text_error == str(e).encode('utf8')) + self.assertTrue(sample_text_error == error) def testAssertIsNone(self): self.assertIsNone(None) From python-checkins at python.org Sat Jun 5 15:49:56 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 15:49:56 +0200 (CEST) Subject: [Python-checkins] r81754 - in python/branches/py3k: Lib/unittest/case.py Message-ID: <20100605134956.E8DDEEE993@mail.python.org> Author: michael.foord Date: Sat Jun 5 15:49:56 2010 New Revision: 81754 Log: Merged revisions 81752 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81752 | michael.foord | 2010-06-05 14:38:16 +0100 (Sat, 05 Jun 2010) | 1 line unittest.TestCase assertion methods inform you when they have omitted an over long diff on failure. Issue 8351. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/case.py Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Sat Jun 5 15:49:56 2010 @@ -13,6 +13,10 @@ __unittest = True + +DIFF_OMITTED = ('\nDiff is %s characters long. ' + 'Set self.maxDiff to None to see it.') + class SkipTest(Exception): """ Raise this exception in a test to skip it. @@ -711,7 +715,7 @@ max_diff = self.maxDiff if max_diff is None or len(diff) <= max_diff: return message + diff - return message + return message + (DIFF_OMITTED % len(diff)) def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. From python-checkins at python.org Sat Jun 5 15:57:23 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 15:57:23 +0200 (CEST) Subject: [Python-checkins] r81755 - in python/branches/py3k: Lib/unittest/case.py Lib/unittest/test/test_case.py Message-ID: <20100605135723.A1369EE9D9@mail.python.org> Author: michael.foord Date: Sat Jun 5 15:57:23 2010 New Revision: 81755 Log: Merged revisions 81753 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81753 | michael.foord | 2010-06-05 14:48:27 +0100 (Sat, 05 Jun 2010) | 1 line Fix unittest tests after previous commit. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/case.py python/branches/py3k/Lib/unittest/test/test_case.py Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Sat Jun 5 15:57:23 2010 @@ -936,7 +936,7 @@ 'Second argument is not a string')) if first != second: - standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) + standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True)) diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) standardMsg = self._truncateMessage(standardMsg, diff) Modified: python/branches/py3k/Lib/unittest/test/test_case.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_case.py (original) +++ python/branches/py3k/Lib/unittest/test/test_case.py Sat Jun 5 15:57:23 2010 @@ -776,7 +776,7 @@ A test case is the smallest unit of testing. [...] You may provide your own implementation that does not subclass from TestCase, of course. """ - sample_text_error = """ + sample_text_error = """\ - http://www.python.org/doc/2.3/lib/module-unittest.html ? ^ + http://www.python.org/doc/2.4.1/lib/module-unittest.html @@ -787,13 +787,16 @@ ? +++++++++++++++++++++ + own implementation that does not subclass from TestCase, of course. """ - + self.maxDiff = None try: self.assertMultiLineEqual(sample_text, revised_sample_text) except self.failureException as e: + # need to remove the first line of the error message + error = str(e).split('\n', 1)[1] + # no fair testing ourself with ourself, and assertEqual is used for strings # so can't use assertEqual either. Just use assertTrue. - self.assertTrue(sample_text_error == str(e)) + self.assertTrue(sample_text_error == error) def testAssertIsNone(self): self.assertIsNone(None) From python-checkins at python.org Sat Jun 5 16:54:26 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Sat, 5 Jun 2010 16:54:26 +0200 (CEST) Subject: [Python-checkins] r81756 - in python/trunk: Doc/library/time.rst Misc/NEWS Modules/timemodule.c Message-ID: <20100605145426.57A41C974@mail.python.org> Author: alexander.belopolsky Date: Sat Jun 5 16:54:26 2010 New Revision: 81756 Log: Issue #8899: time.struct_time now has class and atribute docstrings. Modified: python/trunk/Doc/library/time.rst python/trunk/Misc/NEWS python/trunk/Modules/timemodule.c Modified: python/trunk/Doc/library/time.rst ============================================================================== --- python/trunk/Doc/library/time.rst (original) +++ python/trunk/Doc/library/time.rst Sat Jun 5 16:54:26 2010 @@ -87,25 +87,26 @@ +=======+===================+=================================+ | 0 | :attr:`tm_year` | (for example, 1993) | +-------+-------------------+---------------------------------+ - | 1 | :attr:`tm_mon` | range [1,12] | + | 1 | :attr:`tm_mon` | range [1, 12] | +-------+-------------------+---------------------------------+ - | 2 | :attr:`tm_mday` | range [1,31] | + | 2 | :attr:`tm_mday` | range [1, 31] | +-------+-------------------+---------------------------------+ - | 3 | :attr:`tm_hour` | range [0,23] | + | 3 | :attr:`tm_hour` | range [0, 23] | +-------+-------------------+---------------------------------+ - | 4 | :attr:`tm_min` | range [0,59] | + | 4 | :attr:`tm_min` | range [0, 59] | +-------+-------------------+---------------------------------+ - | 5 | :attr:`tm_sec` | range [0,61]; see **(1)** in | + | 5 | :attr:`tm_sec` | range [0, 61]; see **(1)** in | | | | :func:`strftime` description | +-------+-------------------+---------------------------------+ - | 6 | :attr:`tm_wday` | range [0,6], Monday is 0 | + | 6 | :attr:`tm_wday` | range [0, 6], Monday is 0 | +-------+-------------------+---------------------------------+ - | 7 | :attr:`tm_yday` | range [1,366] | + | 7 | :attr:`tm_yday` | range [1, 366] | +-------+-------------------+---------------------------------+ | 8 | :attr:`tm_isdst` | 0, 1 or -1; see below | +-------+-------------------+---------------------------------+ - Note that unlike the C structure, the month value is a range of 1-12, not 0-11. + Note that unlike the C structure, the month value is a range of [1, 12], + not [0, 11]. A year value will be handled as described under "Year 2000 (Y2K) issues" above. A ``-1`` argument as the daylight savings flag, passed to :func:`mktime` will usually result in the correct daylight savings state to be filled in. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Jun 5 16:54:26 2010 @@ -52,6 +52,8 @@ Library ------- +- Issue #8899: time.struct_time now has class and atribute docstrings. + - Issue #4487: email now accepts as charset aliases all codec aliases accepted by the codecs module. Modified: python/trunk/Modules/timemodule.c ============================================================================== --- python/trunk/Modules/timemodule.c (original) +++ python/trunk/Modules/timemodule.c Sat Jun 5 16:54:26 2010 @@ -216,21 +216,27 @@ a floating point number for subsecond precision."); static PyStructSequence_Field struct_time_type_fields[] = { - {"tm_year", NULL}, - {"tm_mon", NULL}, - {"tm_mday", NULL}, - {"tm_hour", NULL}, - {"tm_min", NULL}, - {"tm_sec", NULL}, - {"tm_wday", NULL}, - {"tm_yday", NULL}, - {"tm_isdst", NULL}, + {"tm_year", "year, for example, 1993"}, + {"tm_mon", "month of year, range [1, 12]"}, + {"tm_mday", "day of month, range [1, 31]"}, + {"tm_hour", "hours, range [0, 23]"}, + {"tm_min", "minutes, range [0, 59]"}, + {"tm_sec", "seconds, range [0, 61])"}, + {"tm_wday", "day of week, range [0, 6], Monday is 0"}, + {"tm_yday", "day of year, range [1, 366]"}, + {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"}, {0} }; static PyStructSequence_Desc struct_time_type_desc = { "time.struct_time", - NULL, + "The time value as returned by gmtime(), localtime(), and strptime(), and\n" + " accepted by asctime(), mktime() and strftime(). May be considered as a\n" + " sequence of 9 integers.\n\n" + " Note that several fields' values are not the same as those defined by\n" + " the C language standard for struct tm. For example, the value of the\n" + " field tm_year is the actual year, not year - 1900. See individual\n" + " fields' descriptions for details.", struct_time_type_fields, 9, }; From python-checkins at python.org Sat Jun 5 17:04:51 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Sat, 5 Jun 2010 17:04:51 +0200 (CEST) Subject: [Python-checkins] r81757 - in python/branches/py3k: Doc/library/time.rst Misc/NEWS Modules/timemodule.c Message-ID: <20100605150451.7934DEEA29@mail.python.org> Author: alexander.belopolsky Date: Sat Jun 5 17:04:51 2010 New Revision: 81757 Log: Merged revisions 81756 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81756 | alexander.belopolsky | 2010-06-05 10:54:26 -0400 (Sat, 05 Jun 2010) | 1 line Issue #8899: time.struct_time now has class and atribute docstrings. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/time.rst python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/timemodule.c Modified: python/branches/py3k/Doc/library/time.rst ============================================================================== --- python/branches/py3k/Doc/library/time.rst (original) +++ python/branches/py3k/Doc/library/time.rst Sat Jun 5 17:04:51 2010 @@ -81,30 +81,31 @@ :func:`gmtime`, :func:`localtime`, and :func:`strptime` also offer attribute names for individual fields. - +-------+------------------+------------------------------+ - | Index | Attribute | Values | - +=======+==================+==============================+ - | 0 | :attr:`tm_year` | (for example, 1993) | - +-------+------------------+------------------------------+ - | 1 | :attr:`tm_mon` | range [1,12] | - +-------+------------------+------------------------------+ - | 2 | :attr:`tm_mday` | range [1,31] | - +-------+------------------+------------------------------+ - | 3 | :attr:`tm_hour` | range [0,23] | - +-------+------------------+------------------------------+ - | 4 | :attr:`tm_min` | range [0,59] | - +-------+------------------+------------------------------+ - | 5 | :attr:`tm_sec` | range [0,61]; see **(1)** in | - | | | :func:`strftime` description | - +-------+------------------+------------------------------+ - | 6 | :attr:`tm_wday` | range [0,6], Monday is 0 | - +-------+------------------+------------------------------+ - | 7 | :attr:`tm_yday` | range [1,366] | - +-------+------------------+------------------------------+ - | 8 | :attr:`tm_isdst` | 0, 1 or -1; see below | - +-------+------------------+------------------------------+ + +-------+-------------------+---------------------------------+ + | Index | Attribute | Values | + +=======+===================+=================================+ + | 0 | :attr:`tm_year` | (for example, 1993) | + +-------+-------------------+---------------------------------+ + | 1 | :attr:`tm_mon` | range [1, 12] | + +-------+-------------------+---------------------------------+ + | 2 | :attr:`tm_mday` | range [1, 31] | + +-------+-------------------+---------------------------------+ + | 3 | :attr:`tm_hour` | range [0, 23] | + +-------+-------------------+---------------------------------+ + | 4 | :attr:`tm_min` | range [0, 59] | + +-------+-------------------+---------------------------------+ + | 5 | :attr:`tm_sec` | range [0, 61]; see **(1)** in | + | | | :func:`strftime` description | + +-------+-------------------+---------------------------------+ + | 6 | :attr:`tm_wday` | range [0, 6], Monday is 0 | + +-------+-------------------+---------------------------------+ + | 7 | :attr:`tm_yday` | range [1, 366] | + +-------+-------------------+---------------------------------+ + | 8 | :attr:`tm_isdst` | 0, 1 or -1; see below | + +-------+-------------------+---------------------------------+ - Note that unlike the C structure, the month value is a range of 1-12, not 0-11. + Note that unlike the C structure, the month value is a range of [1, 12], + not [0, 11]. A year value will be handled as described under "Year 2000 (Y2K) issues" above. A ``-1`` argument as the daylight savings flag, passed to :func:`mktime` will usually result in the correct daylight savings state to be filled in. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jun 5 17:04:51 2010 @@ -398,6 +398,8 @@ Library ------- +- Issue #8899: time.struct_time now has class and atribute docstrings. + - Issue #6470: Drop UNC prefix in FixTk. - Issue #4768: base64 encoded email body parts were incorrectly stored as Modified: python/branches/py3k/Modules/timemodule.c ============================================================================== --- python/branches/py3k/Modules/timemodule.c (original) +++ python/branches/py3k/Modules/timemodule.c Sat Jun 5 17:04:51 2010 @@ -208,21 +208,27 @@ a floating point number for subsecond precision."); static PyStructSequence_Field struct_time_type_fields[] = { - {"tm_year", NULL}, - {"tm_mon", NULL}, - {"tm_mday", NULL}, - {"tm_hour", NULL}, - {"tm_min", NULL}, - {"tm_sec", NULL}, - {"tm_wday", NULL}, - {"tm_yday", NULL}, - {"tm_isdst", NULL}, + {"tm_year", "year, for example, 1993"}, + {"tm_mon", "month of year, range [1, 12]"}, + {"tm_mday", "day of month, range [1, 31]"}, + {"tm_hour", "hours, range [0, 23]"}, + {"tm_min", "minutes, range [0, 59]"}, + {"tm_sec", "seconds, range [0, 61])"}, + {"tm_wday", "day of week, range [0, 6], Monday is 0"}, + {"tm_yday", "day of year, range [1, 366]"}, + {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"}, {0} }; static PyStructSequence_Desc struct_time_type_desc = { "time.struct_time", - NULL, + "The time value as returned by gmtime(), localtime(), and strptime(), and\n" + " accepted by asctime(), mktime() and strftime(). May be considered as a\n" + " sequence of 9 integers.\n\n" + " Note that several fields' values are not the same as those defined by\n" + " the C language standard for struct tm. For example, the value of the\n" + " field tm_year is the actual year, not year - 1900. See individual\n" + " fields' descriptions for details.", struct_time_type_fields, 9, }; From python-checkins at python.org Sat Jun 5 19:51:07 2010 From: python-checkins at python.org (ezio.melotti) Date: Sat, 5 Jun 2010 19:51:07 +0200 (CEST) Subject: [Python-checkins] r81758 - in python/trunk: Lib/test/test_codeccallbacks.py Lib/test/test_unicode.py Objects/unicodeobject.c Message-ID: <20100605175107.6C11FEE993@mail.python.org> Author: ezio.melotti Date: Sat Jun 5 19:51:07 2010 New Revision: 81758 Log: Update PyUnicode_DecodeUTF8 from RFC 2279 to RFC 3629. 1) #8271: when a byte sequence is invalid, only the start byte and all the valid continuation bytes are now replaced by U+FFFD, instead of replacing the number of bytes specified by the start byte. See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf (pages 94-95); 2) 5- and 6-bytes-long UTF-8 sequences are now considered invalid (no changes in behavior); 3) Add code and tests to reject surrogates (U+D800-U+DFFF) as defined in RFC 3629, but leave it commented out since it's not backward compatible; 4) Change the error messages "unexpected code byte" to "invalid start byte" and "invalid data" to "invalid continuation byte"; 5) Add an extensive set of tests in test_unicode; 6) Fix test_codeccallbacks because it was failing after this change. Modified: python/trunk/Lib/test/test_codeccallbacks.py python/trunk/Lib/test/test_unicode.py python/trunk/Objects/unicodeobject.c Modified: python/trunk/Lib/test/test_codeccallbacks.py ============================================================================== --- python/trunk/Lib/test/test_codeccallbacks.py (original) +++ python/trunk/Lib/test/test_codeccallbacks.py Sat Jun 5 19:51:07 2010 @@ -153,28 +153,30 @@ sout += "\\U%08x" % sys.maxunicode self.assertEqual(sin.encode("iso-8859-15", "backslashreplace"), sout) - def test_decoderelaxedutf8(self): - # This is the test for a decoding callback handler, - # that relaxes the UTF-8 minimal encoding restriction. - # A null byte that is encoded as "\xc0\x80" will be - # decoded as a null byte. All other illegal sequences - # will be handled strictly. + def test_decoding_callbacks(self): + # This is a test for a decoding callback handler + # that allows the decoding of the invalid sequence + # "\xc0\x80" and returns "\x00" instead of raising an error. + # All other illegal sequences will be handled strictly. def relaxedutf8(exc): if not isinstance(exc, UnicodeDecodeError): raise TypeError("don't know how to handle %r" % exc) - if exc.object[exc.start:exc.end].startswith("\xc0\x80"): + if exc.object[exc.start:exc.start+2] == "\xc0\x80": return (u"\x00", exc.start+2) # retry after two bytes else: raise exc - codecs.register_error( - "test.relaxedutf8", relaxedutf8) + codecs.register_error("test.relaxedutf8", relaxedutf8) + # all the "\xc0\x80" will be decoded to "\x00" sin = "a\x00b\xc0\x80c\xc3\xbc\xc0\x80\xc0\x80" sout = u"a\x00b\x00c\xfc\x00\x00" self.assertEqual(sin.decode("utf-8", "test.relaxedutf8"), sout) + + # "\xc0\x81" is not valid and a UnicodeDecodeError will be raised sin = "\xc0\x80\xc0\x81" - self.assertRaises(UnicodeError, sin.decode, "utf-8", "test.relaxedutf8") + self.assertRaises(UnicodeDecodeError, sin.decode, + "utf-8", "test.relaxedutf8") def test_charmapencode(self): # For charmap encodings the replacement string will be Modified: python/trunk/Lib/test/test_unicode.py ============================================================================== --- python/trunk/Lib/test/test_unicode.py (original) +++ python/trunk/Lib/test/test_unicode.py Sat Jun 5 19:51:07 2010 @@ -600,6 +600,164 @@ # * strict decoding testing for all of the # UTF8_ERROR cases in PyUnicode_DecodeUTF8 + def test_utf8_decode_valid_sequences(self): + sequences = [ + # single byte + ('\x00', u'\x00'), ('a', u'a'), ('\x7f', u'\x7f'), + # 2 bytes + ('\xc2\x80', u'\x80'), ('\xdf\xbf', u'\u07ff'), + # 3 bytes + ('\xe0\xa0\x80', u'\u0800'), ('\xed\x9f\xbf', u'\ud7ff'), + ('\xee\x80\x80', u'\uE000'), ('\xef\xbf\xbf', u'\uffff'), + # 4 bytes + ('\xF0\x90\x80\x80', u'\U00010000'), + ('\xf4\x8f\xbf\xbf', u'\U0010FFFF') + ] + for seq, res in sequences: + self.assertEqual(seq.decode('utf-8'), res) + + for ch in map(unichr, range(0, sys.maxunicode)): + self.assertEqual(ch, ch.encode('utf-8').decode('utf-8')) + + def test_utf8_decode_invalid_sequences(self): + # continuation bytes in a sequence of 2, 3, or 4 bytes + continuation_bytes = map(chr, range(0x80, 0xC0)) + # start bytes of a 2-byte sequence equivalent to codepoints < 0x7F + invalid_2B_seq_start_bytes = map(chr, range(0xC0, 0xC2)) + # start bytes of a 4-byte sequence equivalent to codepoints > 0x10FFFF + invalid_4B_seq_start_bytes = map(chr, range(0xF5, 0xF8)) + invalid_start_bytes = ( + continuation_bytes + invalid_2B_seq_start_bytes + + invalid_4B_seq_start_bytes + map(chr, range(0xF7, 0x100)) + ) + + for byte in invalid_start_bytes: + self.assertRaises(UnicodeDecodeError, byte.decode, 'utf-8') + + for sb in invalid_2B_seq_start_bytes: + for cb in continuation_bytes: + self.assertRaises(UnicodeDecodeError, (sb+cb).decode, 'utf-8') + + for sb in invalid_4B_seq_start_bytes: + for cb1 in continuation_bytes[:3]: + for cb3 in continuation_bytes[:3]: + self.assertRaises(UnicodeDecodeError, + (sb+cb1+'\x80'+cb3).decode, 'utf-8') + + for cb in map(chr, range(0x80, 0xA0)): + self.assertRaises(UnicodeDecodeError, + ('\xE0'+cb+'\x80').decode, 'utf-8') + self.assertRaises(UnicodeDecodeError, + ('\xE0'+cb+'\xBF').decode, 'utf-8') + # XXX: surrogates shouldn't be valid UTF-8! + # see http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf + # (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt + #for cb in map(chr, range(0xA0, 0xC0)): + #sys.__stdout__.write('\\xED\\x%02x\\x80\n' % ord(cb)) + #self.assertRaises(UnicodeDecodeError, + #('\xED'+cb+'\x80').decode, 'utf-8') + #self.assertRaises(UnicodeDecodeError, + #('\xED'+cb+'\xBF').decode, 'utf-8') + for cb in map(chr, range(0x80, 0x90)): + self.assertRaises(UnicodeDecodeError, + ('\xF0'+cb+'\x80\x80').decode, 'utf-8') + self.assertRaises(UnicodeDecodeError, + ('\xF0'+cb+'\xBF\xBF').decode, 'utf-8') + for cb in map(chr, range(0x90, 0xC0)): + self.assertRaises(UnicodeDecodeError, + ('\xF4'+cb+'\x80\x80').decode, 'utf-8') + self.assertRaises(UnicodeDecodeError, + ('\xF4'+cb+'\xBF\xBF').decode, 'utf-8') + + def test_issue8271(self): + # Issue #8271: when a byte sequence is invalid, only the start byte + # and all the valid continuation bytes should be replaced by U+FFFD, + # not the number of bytes specified by the start byte. + # See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf (page 95, + # table 3-8, Row 2) for more information about the algorithm used. + FFFD = u'\ufffd' + sequences = [ + # invalid start bytes + ('\x80', FFFD), # continuation byte + ('\x80\x80', FFFD*2), # 2 continuation bytes + ('\xc0', FFFD), + ('\xc0\xc0', FFFD*2), + ('\xc1', FFFD), + ('\xc1\xc0', FFFD*2), + ('\xc0\xc1', FFFD*2), + # with start byte of a 2-byte sequence + ('\xc2', FFFD), # only the start byte + ('\xc2\xc2', FFFD*2), # 2 start bytes + ('\xc2\xc2\xc2', FFFD*3), # 2 start bytes + ('\xc2\x41', FFFD+'A'), # invalid continuation byte + # with start byte of a 3-byte sequence + ('\xe1', FFFD), # only the start byte + ('\xe1\xe1', FFFD*2), # 2 start bytes + ('\xe1\xe1\xe1', FFFD*3), # 3 start bytes + ('\xe1\xe1\xe1\xe1', FFFD*4), # 4 start bytes + ('\xe1\x80', FFFD), # only 1 continuation byte + ('\xe1\x41', FFFD+'A'), # invalid continuation byte + ('\xe1\x41\x80', FFFD+'A'+FFFD), # invalid cb followed by valid cb + ('\xe1\x41\x41', FFFD+'AA'), # 2 invalid continuation bytes + ('\xe1\x80\x41', FFFD+'A'), # only 1 valid continuation byte + ('\xe1\x80\xe1\x41', FFFD*2+'A'), # 1 valid and the other invalid + ('\xe1\x41\xe1\x80', FFFD+'A'+FFFD), # 1 invalid and the other valid + # with start byte of a 4-byte sequence + ('\xf1', FFFD), # only the start byte + ('\xf1\xf1', FFFD*2), # 2 start bytes + ('\xf1\xf1\xf1', FFFD*3), # 3 start bytes + ('\xf1\xf1\xf1\xf1', FFFD*4), # 4 start bytes + ('\xf1\xf1\xf1\xf1\xf1', FFFD*5), # 5 start bytes + ('\xf1\x80', FFFD), # only 1 continuation bytes + ('\xf1\x80\x80', FFFD), # only 2 continuation bytes + ('\xf1\x80\x41', FFFD+'A'), # 1 valid cb and 1 invalid + ('\xf1\x80\x41\x41', FFFD+'AA'), # 1 valid cb and 1 invalid + ('\xf1\x80\x80\x41', FFFD+'A'), # 2 valid cb and 1 invalid + ('\xf1\x41\x80', FFFD+'A'+FFFD), # 1 invalid cv and 1 valid + ('\xf1\x41\x80\x80', FFFD+'A'+FFFD*2), # 1 invalid cb and 2 invalid + ('\xf1\x41\x80\x41', FFFD+'A'+FFFD+'A'), # 2 invalid cb and 1 invalid + ('\xf1\x41\x41\x80', FFFD+'AA'+FFFD), # 1 valid cb and 1 invalid + ('\xf1\x41\xf1\x80', FFFD+'A'+FFFD), + ('\xf1\x41\x80\xf1', FFFD+'A'+FFFD*2), + ('\xf1\xf1\x80\x41', FFFD*2+'A'), + ('\xf1\x41\xf1\xf1', FFFD+'A'+FFFD*2), + # with invalid start byte of a 4-byte sequence (rfc2279) + ('\xf5', FFFD), # only the start byte + ('\xf5\xf5', FFFD*2), # 2 start bytes + ('\xf5\x80', FFFD*2), # only 1 continuation byte + ('\xf5\x80\x80', FFFD*3), # only 2 continuation byte + ('\xf5\x80\x80\x80', FFFD*4), # 3 continuation bytes + ('\xf5\x80\x41', FFFD*2+'A'), # 1 valid cb and 1 invalid + ('\xf5\x80\x41\xf5', FFFD*2+'A'+FFFD), + ('\xf5\x41\x80\x80\x41', FFFD+'A'+FFFD*2+'A'), + # with invalid start byte of a 5-byte sequence (rfc2279) + ('\xf8', FFFD), # only the start byte + ('\xf8\xf8', FFFD*2), # 2 start bytes + ('\xf8\x80', FFFD*2), # only one continuation byte + ('\xf8\x80\x41', FFFD*2 + 'A'), # 1 valid cb and 1 invalid + ('\xf8\x80\x80\x80\x80', FFFD*5), # invalid 5 bytes seq with 5 bytes + # with invalid start byte of a 6-byte sequence (rfc2279) + ('\xfc', FFFD), # only the start byte + ('\xfc\xfc', FFFD*2), # 2 start bytes + ('\xfc\x80\x80', FFFD*3), # only 2 continuation bytes + ('\xfc\x80\x80\x80\x80\x80', FFFD*6), # 6 continuation bytes + # invalid start byte + ('\xfe', FFFD), + ('\xfe\x80\x80', FFFD*3), + # other sequences + ('\xf1\x80\x41\x42\x43', u'\ufffd\x41\x42\x43'), + ('\xf1\x80\xff\x42\x43', u'\ufffd\ufffd\x42\x43'), + ('\xf1\x80\xc2\x81\x43', u'\ufffd\x81\x43'), + ('\x61\xF1\x80\x80\xE1\x80\xC2\x62\x80\x63\x80\xBF\x64', + u'\x61\uFFFD\uFFFD\uFFFD\x62\uFFFD\x63\uFFFD\uFFFD\x64'), + ] + for n, (seq, res) in enumerate(sequences): + self.assertRaises(UnicodeDecodeError, seq.decode, 'utf-8', 'strict') + self.assertEqual(seq.decode('utf-8', 'replace'), res) + self.assertEqual((seq+'b').decode('utf-8', 'replace'), res+'b') + self.assertEqual(seq.decode('utf-8', 'ignore'), + res.replace(u'\uFFFD', '')) + def test_codecs_idna(self): # Test whether trailing dot is preserved self.assertEqual(u"www.python.org.".encode("idna"), "www.python.org.") Modified: python/trunk/Objects/unicodeobject.c ============================================================================== --- python/trunk/Objects/unicodeobject.c (original) +++ python/trunk/Objects/unicodeobject.c Sat Jun 5 19:51:07 2010 @@ -1863,24 +1863,24 @@ static char utf8_code_length[256] = { - /* Map UTF-8 encoded prefix byte to sequence length. zero means - illegal prefix. see RFC 2279 for details */ + /* Map UTF-8 encoded prefix byte to sequence length. Zero means + illegal prefix. See RFC 3629 for details */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00-0F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70-7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0-BF */ + 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* C0-C1 + C2-CF */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* D0-DF */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* E0-EF */ + 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0-F4 + F5-FF */ }; PyObject *PyUnicode_DecodeUTF8(const char *s, @@ -1897,6 +1897,7 @@ { const char *starts = s; int n; + int k; Py_ssize_t startinpos; Py_ssize_t endinpos; Py_ssize_t outpos; @@ -1939,7 +1940,9 @@ else { errmsg = "unexpected end of data"; startinpos = s-starts; - endinpos = size; + endinpos = startinpos+1; + for (k=1; (k < size-startinpos) && ((s[k]&0xC0) == 0x80); k++) + endinpos++; goto utf8Error; } } @@ -1947,7 +1950,7 @@ switch (n) { case 0: - errmsg = "unexpected code byte"; + errmsg = "invalid start byte"; startinpos = s-starts; endinpos = startinpos+1; goto utf8Error; @@ -1960,70 +1963,67 @@ case 2: if ((s[1] & 0xc0) != 0x80) { - errmsg = "invalid data"; + errmsg = "invalid continuation byte"; startinpos = s-starts; - endinpos = startinpos+2; + endinpos = startinpos + 1; goto utf8Error; } ch = ((s[0] & 0x1f) << 6) + (s[1] & 0x3f); - if (ch < 0x80) { - startinpos = s-starts; - endinpos = startinpos+2; - errmsg = "illegal encoding"; - goto utf8Error; - } - else - *p++ = (Py_UNICODE)ch; + assert ((ch > 0x007F) && (ch <= 0x07FF)); + *p++ = (Py_UNICODE)ch; break; case 3: + /* XXX: surrogates shouldn't be valid UTF-8! + see http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf + (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt + Uncomment the 2 lines below to make them invalid, + codepoints: d800-dfff; UTF-8: \xed\xa0\x80-\xed\xbf\xbf. */ if ((s[1] & 0xc0) != 0x80 || - (s[2] & 0xc0) != 0x80) { - errmsg = "invalid data"; + (s[2] & 0xc0) != 0x80 || + ((unsigned char)s[0] == 0xE0 && + (unsigned char)s[1] < 0xA0)/* || + ((unsigned char)s[0] == 0xED && + (unsigned char)s[1] > 0x9F)*/) { + errmsg = "invalid continuation byte"; startinpos = s-starts; - endinpos = startinpos+3; + endinpos = startinpos + 1; + + /* if s[1] first two bits are 1 and 0, then the invalid + continuation byte is s[2], so increment endinpos by 1, + if not, s[1] is invalid and endinpos doesn't need to + be incremented. */ + if ((s[1] & 0xC0) == 0x80) + endinpos++; goto utf8Error; } ch = ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + (s[2] & 0x3f); - if (ch < 0x0800) { - /* Note: UTF-8 encodings of surrogates are considered - legal UTF-8 sequences; - - XXX For wide builds (UCS-4) we should probably try - to recombine the surrogates into a single code - unit. - */ - errmsg = "illegal encoding"; - startinpos = s-starts; - endinpos = startinpos+3; - goto utf8Error; - } - else - *p++ = (Py_UNICODE)ch; + assert ((ch > 0x07FF) && (ch <= 0xFFFF)); + *p++ = (Py_UNICODE)ch; break; case 4: if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || - (s[3] & 0xc0) != 0x80) { - errmsg = "invalid data"; + (s[3] & 0xc0) != 0x80 || + ((unsigned char)s[0] == 0xF0 && + (unsigned char)s[1] < 0x90) || + ((unsigned char)s[0] == 0xF4 && + (unsigned char)s[1] > 0x8F)) { + errmsg = "invalid continuation byte"; startinpos = s-starts; - endinpos = startinpos+4; + endinpos = startinpos + 1; + if ((s[1] & 0xC0) == 0x80) { + endinpos++; + if ((s[2] & 0xC0) == 0x80) + endinpos++; + } goto utf8Error; } ch = ((s[0] & 0x7) << 18) + ((s[1] & 0x3f) << 12) + - ((s[2] & 0x3f) << 6) + (s[3] & 0x3f); - /* validate and convert to UTF-16 */ - if ((ch < 0x10000) /* minimum value allowed for 4 - byte encoding */ - || (ch > 0x10ffff)) /* maximum value allowed for - UTF-16 */ - { - errmsg = "illegal encoding"; - startinpos = s-starts; - endinpos = startinpos+4; - goto utf8Error; - } + ((s[2] & 0x3f) << 6) + (s[3] & 0x3f); + assert ((ch > 0xFFFF) && (ch <= 0x10ffff)); + #ifdef Py_UNICODE_WIDE *p++ = (Py_UNICODE)ch; #else @@ -2039,13 +2039,6 @@ *p++ = (Py_UNICODE)(0xDC00 + (ch & 0x03FF)); #endif break; - - default: - /* Other sizes are only needed for UCS-4 */ - errmsg = "unsupported Unicode code range"; - startinpos = s-starts; - endinpos = startinpos+n; - goto utf8Error; } s += n; continue; From benjamin at python.org Sat Jun 5 20:55:09 2010 From: benjamin at python.org (Benjamin Peterson) Date: Sat, 5 Jun 2010 13:55:09 -0500 Subject: [Python-checkins] r81706 - in python/trunk: Lib/test/test_descr.py Objects/abstract.c In-Reply-To: <4C0A05E5.3030105@gmail.com> References: <20100605003251.2A9BCEECF3@mail.python.org> <4C0A05E5.3030105@gmail.com> Message-ID: 2010/6/5 Nick Coghlan : > On 05/06/10 10:32, benjamin.peterson wrote: >> >> - ? ?/* Initialize cached value */ >> - ? ?if (str__format__ == NULL) { >> - ? ? ? ?/* Initialize static variable needed by _PyType_Lookup */ >> - ? ? ? ?str__format__ = PyString_InternFromString("__format__"); >> - ? ? ? ?if (str__format__ == NULL) >> - ? ? ? ? ? ?goto done; >> - ? ?} >> - > > Why kill the microoptimisation here? Looking the string up in the intern > dict every time (as these changes do) is a waste of cycles. Since avoiding > it is pretty easy using this common idiom, it's generally worth doing. Yes, but that's only applicable to classic classes, which I can't say I care much about. -- Regards, Benjamin From python-checkins at python.org Sat Jun 5 21:21:32 2010 From: python-checkins at python.org (ezio.melotti) Date: Sat, 5 Jun 2010 21:21:32 +0200 (CEST) Subject: [Python-checkins] r81759 - in python/trunk: Lib/test/test_unicode.py Misc/NEWS Message-ID: <20100605192132.CB127EE99D@mail.python.org> Author: ezio.melotti Date: Sat Jun 5 21:21:32 2010 New Revision: 81759 Log: Add a NEWS entry for r81758 and clarify a comment. Modified: python/trunk/Lib/test/test_unicode.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_unicode.py ============================================================================== --- python/trunk/Lib/test/test_unicode.py (original) +++ python/trunk/Lib/test/test_unicode.py Sat Jun 5 21:21:32 2010 @@ -670,9 +670,9 @@ ('\xF4'+cb+'\xBF\xBF').decode, 'utf-8') def test_issue8271(self): - # Issue #8271: when a byte sequence is invalid, only the start byte - # and all the valid continuation bytes should be replaced by U+FFFD, - # not the number of bytes specified by the start byte. + # Issue #8271: during the decoding of an invalid UTF-8 byte sequence, + # only the start byte and the continuation byte(s) are now considered + # invalid, instead of the number of bytes specified by the start byte. # See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf (page 95, # table 3-8, Row 2) for more information about the algorithm used. FFFD = u'\ufffd' Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Jun 5 21:21:32 2010 @@ -12,6 +12,14 @@ Core and Builtins ----------------- +- Issue #8271: during the decoding of an invalid UTF-8 byte sequence, only the + start byte and the continuation byte(s) are now considered invalid, instead + of the number of bytes specified by the start byte. + E.g.: '\xf1\x80AB'.decode('utf-8', 'replace') now returns u'\ufffdAB' and + replaces with U+FFFD only the start byte ('\xf1') and the continuation byte + ('\x80') even if '\xf1' is the start byte of a 4-bytes sequence. + Previous versions returned a single u'\ufffd'. + - Issue #8627: Remove bogus "Overriding __cmp__ blocks inheritance of __hash__ in 3.x" warning. Also fix "XXX undetected error" that arises from the "Overriding __eq__ blocks inheritance ..." warning From python-checkins at python.org Sat Jun 5 21:38:42 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 21:38:42 +0200 (CEST) Subject: [Python-checkins] r81760 - python/trunk/Lib/unittest/suite.py Message-ID: <20100605193842.72663C9AF@mail.python.org> Author: michael.foord Date: Sat Jun 5 21:38:42 2010 New Revision: 81760 Log: Issue 8302. SkipTest exception is setUpClass or setUpModule is now reported as a skip rather than an error. Modified: python/trunk/Lib/unittest/suite.py Modified: python/trunk/Lib/unittest/suite.py ============================================================================== --- python/trunk/Lib/unittest/suite.py (original) +++ python/trunk/Lib/unittest/suite.py Sat Jun 5 21:38:42 2010 @@ -130,9 +130,12 @@ if setUpClass is not None: try: setUpClass() - except: + except Exception as e: currentClass._classSetupFailed = True - self._addClassSetUpError(result, currentClass) + className = util.strclass(currentClass) + errorName = 'classSetUp (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) + def _get_previous_module(self, result): previousModule = None @@ -150,7 +153,6 @@ self._handleModuleTearDown(result) - result._moduleSetUpFailed = False try: module = sys.modules[currentModule] @@ -160,10 +162,18 @@ if setUpModule is not None: try: setUpModule() - except: + except Exception, e: result._moduleSetUpFailed = True - error = _ErrorHolder('setUpModule (%s)' % currentModule) - result.addError(error, sys.exc_info()) + errorName = 'setUpModule (%s)' % currentModule + self._addClassOrModuleLevelException(result, e, errorName) + + def _addClassOrModuleLevelException(self, result, exception, errorName): + error = _ErrorHolder(errorName) + addSkip = getattr(result, 'addSkip', None) + if addSkip is not None and isinstance(exception, case.SkipTest): + addSkip(error, str(exception)) + else: + result.addError(error, sys.exc_info()) def _handleModuleTearDown(self, result): previousModule = self._get_previous_module(result) @@ -181,9 +191,9 @@ if tearDownModule is not None: try: tearDownModule() - except: - error = _ErrorHolder('tearDownModule (%s)' % previousModule) - result.addError(error, sys.exc_info()) + except Exception as e: + errorName = 'tearDownModule (%s)' % previousModule + self._addClassOrModuleLevelException(result, e, errorName) def _tearDownPreviousClass(self, test, result): previousClass = getattr(result, '_previousTestClass', None) @@ -201,18 +211,10 @@ if tearDownClass is not None: try: tearDownClass() - except: - self._addClassTearDownError(result) - - def _addClassTearDownError(self, result): - className = util.strclass(result._previousTestClass) - error = _ErrorHolder('classTearDown (%s)' % className) - result.addError(error, sys.exc_info()) - - def _addClassSetUpError(self, result, klass): - className = util.strclass(klass) - error = _ErrorHolder('classSetUp (%s)' % className) - result.addError(error, sys.exc_info()) + except Exception, e: + className = util.strclass(previousClass) + errorName = 'classTearDown (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) class _ErrorHolder(object): From python-checkins at python.org Sat Jun 5 21:51:38 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 21:51:38 +0200 (CEST) Subject: [Python-checkins] r81761 - python/trunk/Misc/NEWS Message-ID: <20100605195138.EA83FEEA2@mail.python.org> Author: michael.foord Date: Sat Jun 5 21:51:38 2010 New Revision: 81761 Log: Updated NEWS file. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Jun 5 21:51:38 2010 @@ -60,6 +60,13 @@ Library ------- +- Issue #8302: SkipTest in unittest.TestCase.setUpClass or setUpModule is now + reported as a skip rather than an error. + +- Issue #8351: Excessively large diffs due to + unittest.TestCase.assertSequenceEqual are no longer included in failure + reports. + - Issue #8899: time.struct_time now has class and atribute docstrings. - Issue #4487: email now accepts as charset aliases all codec aliases From python-checkins at python.org Sat Jun 5 21:58:25 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 21:58:25 +0200 (CEST) Subject: [Python-checkins] r81762 - python/branches/py3k Message-ID: <20100605195825.3885CEE993@mail.python.org> Author: michael.foord Date: Sat Jun 5 21:58:25 2010 New Revision: 81762 Log: Blocked revisions 81761 via svnmerge ........ r81761 | michael.foord | 2010-06-05 20:51:38 +0100 (Sat, 05 Jun 2010) | 1 line Updated NEWS file. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Jun 5 22:33:43 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 22:33:43 +0200 (CEST) Subject: [Python-checkins] r81763 - python/trunk/Lib/unittest/test/test_case.py Message-ID: <20100605203343.7A882EEA6E@mail.python.org> Author: michael.foord Date: Sat Jun 5 22:33:43 2010 New Revision: 81763 Log: Tests for unittest.TestCase.maxDiff. Modified: python/trunk/Lib/unittest/test/test_case.py Modified: python/trunk/Lib/unittest/test/test_case.py ============================================================================== --- python/trunk/Lib/unittest/test/test_case.py (original) +++ python/trunk/Lib/unittest/test/test_case.py Sat Jun 5 22:33:43 2010 @@ -596,6 +596,8 @@ seq2 = 'b' + 'x' * 80**2 diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) + # the +1 is the leading \n added by assertSequenceEqual + omitted = unittest.case.DIFF_OMITTED % (len(diff) + 1,) self.maxDiff = len(diff)//2 try: @@ -605,6 +607,7 @@ else: self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) < len(diff)) + self.assertIn(omitted, msg) self.maxDiff = len(diff) * 2 try: @@ -614,6 +617,7 @@ else: self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) > len(diff)) + self.assertNotIn(omitted, msg) self.maxDiff = None try: @@ -623,6 +627,41 @@ else: self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) > len(diff)) + self.assertNotIn(omitted, msg) + + def testTruncateMessage(self): + self.maxDiff = 1 + message = self._truncateMessage('foo', 'bar') + omitted = unittest.case.DIFF_OMITTED % len('bar') + self.assertEqual(message, 'foo' + omitted) + + self.maxDiff = None + message = self._truncateMessage('foo', 'bar') + self.assertEqual(message, 'foobar') + + def testAssertDictEqualTruncates(self): + test = unittest.TestCase('assertEqual') + def truncate(msg, diff): + return 'foo' + test._truncateMessage = truncate + try: + test.assertDictEqual({}, {1: 0}) + except self.failureException as e: + self.assertEqual(str(e), 'foo') + else: + self.fail('assertDictEqual did not fail') + + def testAssertMultiLineEqualTruncates(self): + test = unittest.TestCase('assertEqual') + def truncate(msg, diff): + return 'foo' + test._truncateMessage = truncate + try: + test.assertMultiLineEqual('foo', 'bar') + except self.failureException as e: + self.assertEqual(str(e), 'foo') + else: + self.fail('assertMultiLineEqual did not fail') def testAssertItemsEqual(self): a = object() From python-checkins at python.org Sat Jun 5 22:59:00 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 22:59:00 +0200 (CEST) Subject: [Python-checkins] r81764 - in python/trunk/Lib/unittest: suite.py test/test_case.py test/test_setups.py Message-ID: <20100605205900.7B510EEA06@mail.python.org> Author: michael.foord Date: Sat Jun 5 22:59:00 2010 New Revision: 81764 Log: Tests for issue 8302, skipped test in a setUpClass or a setUpModule are reported as skips rather than errors. Modified: python/trunk/Lib/unittest/suite.py python/trunk/Lib/unittest/test/test_case.py python/trunk/Lib/unittest/test/test_setups.py Modified: python/trunk/Lib/unittest/suite.py ============================================================================== --- python/trunk/Lib/unittest/suite.py (original) +++ python/trunk/Lib/unittest/suite.py Sat Jun 5 22:59:00 2010 @@ -133,7 +133,7 @@ except Exception as e: currentClass._classSetupFailed = True className = util.strclass(currentClass) - errorName = 'classSetUp (%s)' % className + errorName = 'setUpClass (%s)' % className self._addClassOrModuleLevelException(result, e, errorName) @@ -213,7 +213,7 @@ tearDownClass() except Exception, e: className = util.strclass(previousClass) - errorName = 'classTearDown (%s)' % className + errorName = 'tearDownClass (%s)' % className self._addClassOrModuleLevelException(result, e, errorName) Modified: python/trunk/Lib/unittest/test/test_case.py ============================================================================== --- python/trunk/Lib/unittest/test/test_case.py (original) +++ python/trunk/Lib/unittest/test/test_case.py Sat Jun 5 22:59:00 2010 @@ -639,6 +639,10 @@ message = self._truncateMessage('foo', 'bar') self.assertEqual(message, 'foobar') + self.maxDiff = 4 + message = self._truncateMessage('foo', 'bar') + self.assertEqual(message, 'foobar') + def testAssertDictEqualTruncates(self): test = unittest.TestCase('assertEqual') def truncate(msg, diff): Modified: python/trunk/Lib/unittest/test/test_setups.py ============================================================================== --- python/trunk/Lib/unittest/test/test_setups.py (original) +++ python/trunk/Lib/unittest/test/test_setups.py Sat Jun 5 22:59:00 2010 @@ -112,7 +112,7 @@ self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), - 'classSetUp (%s.BrokenTest)' % __name__) + 'setUpClass (%s.BrokenTest)' % __name__) def test_error_in_teardown_class(self): class Test(unittest.TestCase): @@ -145,7 +145,7 @@ error, _ = result.errors[0] self.assertEqual(str(error), - 'classTearDown (%s.Test)' % __name__) + 'tearDownClass (%s.Test)' % __name__) def test_class_not_torndown_when_setup_fails(self): class Test(unittest.TestCase): @@ -400,6 +400,45 @@ error, _ = result.errors[0] self.assertEqual(str(error), 'tearDownModule (Module)') + def test_skiptest_in_setupclass(self): + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + raise unittest.SkipTest('foo') + def test_one(self): + pass + def test_two(self): + pass + + result = self.runTests(Test) + self.assertEqual(result.testsRun, 0) + self.assertEqual(len(result.errors), 0) + self.assertEqual(len(result.skipped), 1) + skipped = result.skipped[0][0] + self.assertEqual(str(skipped), 'setUpClass (%s.Test)' % __name__) + + def test_skiptest_in_setupmodule(self): + class Test(unittest.TestCase): + def test_one(self): + pass + def test_two(self): + pass + + class Module(object): + @staticmethod + def setUpModule(): + raise unittest.SkipTest('foo') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + result = self.runTests(Test) + self.assertEqual(result.testsRun, 0) + self.assertEqual(len(result.errors), 0) + self.assertEqual(len(result.skipped), 1) + skipped = result.skipped[0][0] + self.assertEqual(str(skipped), 'setUpModule (Module)') + if __name__ == '__main__': unittest.main() From python-checkins at python.org Sat Jun 5 23:01:08 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 23:01:08 +0200 (CEST) Subject: [Python-checkins] r81765 - in python/branches/py3k: Lib/unittest/test/test_case.py Message-ID: <20100605210108.8EFADEE99D@mail.python.org> Author: michael.foord Date: Sat Jun 5 23:01:08 2010 New Revision: 81765 Log: Merged revisions 81763 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81763 | michael.foord | 2010-06-05 21:33:43 +0100 (Sat, 05 Jun 2010) | 1 line Tests for unittest.TestCase.maxDiff. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/test/test_case.py Modified: python/branches/py3k/Lib/unittest/test/test_case.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_case.py (original) +++ python/branches/py3k/Lib/unittest/test/test_case.py Sat Jun 5 23:01:08 2010 @@ -597,6 +597,8 @@ seq2 = 'b' + 'x' * 80**2 diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) + # the +1 is the leading \n added by assertSequenceEqual + omitted = unittest.case.DIFF_OMITTED % (len(diff) + 1,) self.maxDiff = len(diff)//2 try: @@ -607,6 +609,7 @@ else: self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) < len(diff)) + self.assertIn(omitted, msg) self.maxDiff = len(diff) * 2 try: @@ -616,6 +619,7 @@ else: self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) > len(diff)) + self.assertNotIn(omitted, msg) self.maxDiff = None try: @@ -625,6 +629,41 @@ else: self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) > len(diff)) + self.assertNotIn(omitted, msg) + + def testTruncateMessage(self): + self.maxDiff = 1 + message = self._truncateMessage('foo', 'bar') + omitted = unittest.case.DIFF_OMITTED % len('bar') + self.assertEqual(message, 'foo' + omitted) + + self.maxDiff = None + message = self._truncateMessage('foo', 'bar') + self.assertEqual(message, 'foobar') + + def testAssertDictEqualTruncates(self): + test = unittest.TestCase('assertEqual') + def truncate(msg, diff): + return 'foo' + test._truncateMessage = truncate + try: + test.assertDictEqual({}, {1: 0}) + except self.failureException as e: + self.assertEqual(str(e), 'foo') + else: + self.fail('assertDictEqual did not fail') + + def testAssertMultiLineEqualTruncates(self): + test = unittest.TestCase('assertEqual') + def truncate(msg, diff): + return 'foo' + test._truncateMessage = truncate + try: + test.assertMultiLineEqual('foo', 'bar') + except self.failureException as e: + self.assertEqual(str(e), 'foo') + else: + self.fail('assertMultiLineEqual did not fail') def testAssertItemsEqual(self): a = object() From python-checkins at python.org Sat Jun 5 23:12:23 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 23:12:23 +0200 (CEST) Subject: [Python-checkins] r81766 - in python/branches/py3k: Lib/unittest/suite.py Lib/unittest/test/test_case.py Lib/unittest/test/test_setups.py Message-ID: <20100605211223.60A75EE99D@mail.python.org> Author: michael.foord Date: Sat Jun 5 23:12:23 2010 New Revision: 81766 Log: Merged revisions 81764 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81764 | michael.foord | 2010-06-05 21:59:00 +0100 (Sat, 05 Jun 2010) | 1 line Tests for issue 8302, skipped test in a setUpClass or a setUpModule are reported as skips rather than errors. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/suite.py python/branches/py3k/Lib/unittest/test/test_case.py python/branches/py3k/Lib/unittest/test/test_setups.py Modified: python/branches/py3k/Lib/unittest/suite.py ============================================================================== --- python/branches/py3k/Lib/unittest/suite.py (original) +++ python/branches/py3k/Lib/unittest/suite.py Sat Jun 5 23:12:23 2010 @@ -127,9 +127,11 @@ if setUpClass is not None: try: setUpClass() - except: + except Exception as e: currentClass._classSetupFailed = True - self._addClassSetUpError(result, currentClass) + className = util.strclass(currentClass) + errorName = 'setUpClass (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) def _get_previous_module(self, result): previousModule = None @@ -157,10 +159,18 @@ if setUpModule is not None: try: setUpModule() - except: + except Exception as e: result._moduleSetUpFailed = True - error = _ErrorHolder('setUpModule (%s)' % currentModule) - result.addError(error, sys.exc_info()) + errorName = 'setUpModule (%s)' % currentModule + self._addClassOrModuleLevelException(result, e, errorName) + + def _addClassOrModuleLevelException(self, result, exception, errorName): + error = _ErrorHolder(errorName) + addSkip = getattr(result, 'addSkip', None) + if addSkip is not None and isinstance(exception, case.SkipTest): + addSkip(error, str(exception)) + else: + result.addError(error, sys.exc_info()) def _handleModuleTearDown(self, result): previousModule = self._get_previous_module(result) @@ -178,9 +188,9 @@ if tearDownModule is not None: try: tearDownModule() - except: - error = _ErrorHolder('tearDownModule (%s)' % previousModule) - result.addError(error, sys.exc_info()) + except Exception as e: + errorName = 'tearDownModule (%s)' % previousModule + self._addClassOrModuleLevelException(result, e, errorName) def _tearDownPreviousClass(self, test, result): previousClass = getattr(result, '_previousTestClass', None) @@ -198,18 +208,11 @@ if tearDownClass is not None: try: tearDownClass() - except: - self._addClassTearDownError(result) + except Exception as e: + className = util.strclass(previousClass) + errorName = 'tearDownClass (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) - def _addClassTearDownError(self, result): - className = util.strclass(result._previousTestClass) - error = _ErrorHolder('classTearDown (%s)' % className) - result.addError(error, sys.exc_info()) - - def _addClassSetUpError(self, result, klass): - className = util.strclass(klass) - error = _ErrorHolder('classSetUp (%s)' % className) - result.addError(error, sys.exc_info()) class _ErrorHolder(object): Modified: python/branches/py3k/Lib/unittest/test/test_case.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_case.py (original) +++ python/branches/py3k/Lib/unittest/test/test_case.py Sat Jun 5 23:12:23 2010 @@ -641,6 +641,10 @@ message = self._truncateMessage('foo', 'bar') self.assertEqual(message, 'foobar') + self.maxDiff = 4 + message = self._truncateMessage('foo', 'bar') + self.assertEqual(message, 'foobar') + def testAssertDictEqualTruncates(self): test = unittest.TestCase('assertEqual') def truncate(msg, diff): Modified: python/branches/py3k/Lib/unittest/test/test_setups.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_setups.py (original) +++ python/branches/py3k/Lib/unittest/test/test_setups.py Sat Jun 5 23:12:23 2010 @@ -111,7 +111,7 @@ self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), - 'classSetUp (%s.BrokenTest)' % __name__) + 'setUpClass (%s.BrokenTest)' % __name__) def test_error_in_teardown_class(self): class Test(unittest.TestCase): @@ -144,7 +144,7 @@ error, _ = result.errors[0] self.assertEqual(str(error), - 'classTearDown (%s.Test)' % __name__) + 'tearDownClass (%s.Test)' % __name__) def test_class_not_torndown_when_setup_fails(self): class Test(unittest.TestCase): @@ -398,3 +398,46 @@ self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), 'tearDownModule (Module)') + + def test_skiptest_in_setupclass(self): + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + raise unittest.SkipTest('foo') + def test_one(self): + pass + def test_two(self): + pass + + result = self.runTests(Test) + self.assertEqual(result.testsRun, 0) + self.assertEqual(len(result.errors), 0) + self.assertEqual(len(result.skipped), 1) + skipped = result.skipped[0][0] + self.assertEqual(str(skipped), 'setUpClass (%s.Test)' % __name__) + + def test_skiptest_in_setupmodule(self): + class Test(unittest.TestCase): + def test_one(self): + pass + def test_two(self): + pass + + class Module(object): + @staticmethod + def setUpModule(): + raise unittest.SkipTest('foo') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + result = self.runTests(Test) + self.assertEqual(result.testsRun, 0) + self.assertEqual(len(result.errors), 0) + self.assertEqual(len(result.skipped), 1) + skipped = result.skipped[0][0] + self.assertEqual(str(skipped), 'setUpModule (Module)') + + +if __name__ == '__main__': + unittest.main() From python-checkins at python.org Sat Jun 5 23:57:03 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 23:57:03 +0200 (CEST) Subject: [Python-checkins] r81767 - python/trunk/Doc/library/unittest.rst Message-ID: <20100605215703.28CAFEEA06@mail.python.org> Author: michael.foord Date: Sat Jun 5 23:57:03 2010 New Revision: 81767 Log: Documentation updates for issues 8302 and 8351 (truncating excessive diffs in unittest failure messages and reporting SkipTest exceptions in setUpClass and setUpModule as skips rather than errors). Modified: python/trunk/Doc/library/unittest.rst Modified: python/trunk/Doc/library/unittest.rst ============================================================================== --- python/trunk/Doc/library/unittest.rst (original) +++ python/trunk/Doc/library/unittest.rst Sat Jun 5 23:57:03 2010 @@ -1150,6 +1150,21 @@ .. versionadded:: 2.7 + .. attribute:: maxDiff + + This attribute controls the maximum length of diffs output by assert + methods that report diffs on failure. It defaults to 80*8 characters. + Assert methods affected by this attribute are + :meth:`assertSequenceEqual` (including all the sequence comparison + methods that delegate to it), :meth:`assertDictEqual` and + :meth:`assertMultiLineEqual`. + + Setting ``maxDiff`` to None means that there is no maximum length of + diffs. + + .. versionadded:: 2.7 + + Testing frameworks can use the following methods to collect information on the test: @@ -1848,7 +1863,9 @@ If an exception is raised during a ``setUpClass`` then the tests in the class are not run and the ``tearDownClass`` is not run. Skipped classes will not -have ``setUpClass`` or ``tearDownClass`` run. +have ``setUpClass`` or ``tearDownClass`` run. If the exception is a +``SkipTest`` exception then the class will be reported as having been skipped +instead of as an error. setUpModule and tearDownModule @@ -1863,7 +1880,9 @@ closeConnection() If an exception is raised in a ``setUpModule`` then none of the tests in the -module will be run and the ``tearDownModule`` will not be run. +module will be run and the ``tearDownModule`` will not be run. If the exception is a +``SkipTest`` exception then the module will be reported as having been skipped +instead of as an error. Signal Handling From python-checkins at python.org Sat Jun 5 23:59:55 2010 From: python-checkins at python.org (michael.foord) Date: Sat, 5 Jun 2010 23:59:55 +0200 (CEST) Subject: [Python-checkins] r81768 - in python/branches/py3k: Doc/library/unittest.rst Message-ID: <20100605215955.AF8C1EEA9B@mail.python.org> Author: michael.foord Date: Sat Jun 5 23:59:55 2010 New Revision: 81768 Log: Merged revisions 81767 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81767 | michael.foord | 2010-06-05 22:57:03 +0100 (Sat, 05 Jun 2010) | 1 line Documentation updates for issues 8302 and 8351 (truncating excessive diffs in unittest failure messages and reporting SkipTest exceptions in setUpClass and setUpModule as skips rather than errors). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/unittest.rst Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Sat Jun 5 23:59:55 2010 @@ -1168,6 +1168,21 @@ .. versionadded:: 3.1 + .. attribute:: maxDiff + + This attribute controls the maximum length of diffs output by assert + methods that report diffs on failure. It defaults to 80*8 characters. + Assert methods affected by this attribute are + :meth:`assertSequenceEqual` (including all the sequence comparison + methods that delegate to it), :meth:`assertDictEqual` and + :meth:`assertMultiLineEqual`. + + Setting ``maxDiff`` to None means that there is no maximum length of + diffs. + + .. versionadded:: 3.2 + + Testing frameworks can use the following methods to collect information on the test: @@ -1862,7 +1877,9 @@ If an exception is raised during a ``setUpClass`` then the tests in the class are not run and the ``tearDownClass`` is not run. Skipped classes will not -have ``setUpClass`` or ``tearDownClass`` run. +have ``setUpClass`` or ``tearDownClass`` run. If the exception is a +``SkipTest`` exception then the class will be reported as having been skipped +instead of as an error. setUpModule and tearDownModule @@ -1877,7 +1894,9 @@ closeConnection() If an exception is raised in a ``setUpModule`` then none of the tests in the -module will be run and the ``tearDownModule`` will not be run. +module will be run and the ``tearDownModule`` will not be run. If the exception is a +``SkipTest`` exception then the module will be reported as having been skipped +instead of as an error. Signal Handling From python-checkins at python.org Sun Jun 6 00:28:11 2010 From: python-checkins at python.org (ezio.melotti) Date: Sun, 6 Jun 2010 00:28:11 +0200 (CEST) Subject: [Python-checkins] r81769 - python/trunk/Lib/test/test_shutil.py Message-ID: <20100605222811.04A20EEA64@mail.python.org> Author: ezio.melotti Date: Sun Jun 6 00:28:10 2010 New Revision: 81769 Log: Replace deprecated fail* methods with the equivalent assert* ones. Modified: python/trunk/Lib/test/test_shutil.py Modified: python/trunk/Lib/test/test_shutil.py ============================================================================== --- python/trunk/Lib/test/test_shutil.py (original) +++ python/trunk/Lib/test/test_shutil.py Sun Jun 6 00:28:10 2010 @@ -751,8 +751,8 @@ self._set_shutil_open(_open) shutil.copyfile('srcfile', 'destfile') - self.failUnless(srcfile._entered) - self.failUnless(srcfile._exited_with[0] is IOError) + self.assertTrue(srcfile._entered) + self.assertTrue(srcfile._exited_with[0] is IOError) self.assertEqual(srcfile._exited_with[1].args, ('Cannot open "destfile"',)) @@ -771,10 +771,10 @@ self._set_shutil_open(_open) shutil.copyfile('srcfile', 'destfile') - self.failUnless(srcfile._entered) - self.failUnless(destfile._entered) - self.failUnless(destfile._raised) - self.failUnless(srcfile._exited_with[0] is IOError) + self.assertTrue(srcfile._entered) + self.assertTrue(destfile._entered) + self.assertTrue(destfile._raised) + self.assertTrue(srcfile._exited_with[0] is IOError) self.assertEqual(srcfile._exited_with[1].args, ('Cannot close',)) @@ -794,11 +794,11 @@ self.assertRaises(IOError, shutil.copyfile, 'srcfile', 'destfile') - self.failUnless(srcfile._entered) - self.failUnless(destfile._entered) - self.failIf(destfile._raised) - self.failUnless(srcfile._exited_with[0] is None) - self.failUnless(srcfile._raised) + self.assertTrue(srcfile._entered) + self.assertTrue(destfile._entered) + self.assertFalse(destfile._raised) + self.assertTrue(srcfile._exited_with[0] is None) + self.assertTrue(srcfile._raised) def test_main(): From solipsis at pitrou.net Sun Jun 6 01:26:20 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 6 Jun 2010 01:26:20 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81765): sum=0 Message-ID: <20100605232620.DF2A71788A@ns6635.ovh.net> py3k results for svn r81765 (hg cset 59d0e4dba3e5) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogM6TCkA', '-x'] From python-checkins at python.org Sun Jun 6 01:58:40 2010 From: python-checkins at python.org (michael.foord) Date: Sun, 6 Jun 2010 01:58:40 +0200 (CEST) Subject: [Python-checkins] r81770 - python/trunk/Lib/unittest/case.py Message-ID: <20100605235840.CB047EEABC@mail.python.org> Author: michael.foord Date: Sun Jun 6 01:58:40 2010 New Revision: 81770 Log: Code formatting change. Modified: python/trunk/Lib/unittest/case.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Sun Jun 6 01:58:40 2010 @@ -163,6 +163,7 @@ # This attribute sets the maximum length of a diff in failure messsages # by assert methods using difflib. It is looked up as an instance attribute # so can be configured by individual tests if required. + maxDiff = 80*8 # Attribute used by TestSuite for classSetUp From python-checkins at python.org Sun Jun 6 01:59:34 2010 From: python-checkins at python.org (michael.foord) Date: Sun, 6 Jun 2010 01:59:34 +0200 (CEST) Subject: [Python-checkins] r81771 - in python/branches/py3k: Lib/unittest/case.py Message-ID: <20100605235934.4E635C9E8@mail.python.org> Author: michael.foord Date: Sun Jun 6 01:59:34 2010 New Revision: 81771 Log: Merged revisions 81770 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81770 | michael.foord | 2010-06-06 00:58:40 +0100 (Sun, 06 Jun 2010) | 1 line Code formatting change. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/case.py Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Sun Jun 6 01:59:34 2010 @@ -175,6 +175,7 @@ # This attribute sets the maximum length of a diff in failure messsages # by assert methods using difflib. It is looked up as an instance attribute # so can be configured by individual tests if required. + maxDiff = 80*8 # Attribute used by TestSuite for classSetUp From python-checkins at python.org Sun Jun 6 02:22:09 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 02:22:09 +0200 (CEST) Subject: [Python-checkins] r81772 - 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: <20100606002209.EA353EEA64@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 02:22:09 2010 New Revision: 81772 Log: bump version to 2.7 rc1 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 Sun Jun 6 02:22:09 2010 @@ -23,11 +23,11 @@ #define PY_MAJOR_VERSION 2 #define PY_MINOR_VERSION 7 #define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA -#define PY_RELEASE_SERIAL 2 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "2.7b2+" +#define PY_VERSION "2.7rc1" /*--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 Sun Jun 6 02:22:09 2010 @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "2.7b2" +__version__ = "2.7rc1" #--end constants-- Modified: python/trunk/Lib/idlelib/idlever.py ============================================================================== --- python/trunk/Lib/idlelib/idlever.py (original) +++ python/trunk/Lib/idlelib/idlever.py Sun Jun 6 02:22:09 2010 @@ -1 +1 @@ -IDLE_VERSION = "2.7b2" +IDLE_VERSION = "2.7rc1" Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Jun 6 02:22:09 2010 @@ -7,7 +7,7 @@ What's New in Python 2.7 Release Candidate 1? ============================================= -*Release date: XXXX-XX-XX* +*Release date: 2010-06-05* 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 Sun Jun 6 02:22:09 2010 @@ -39,7 +39,7 @@ %define name python #--start constants-- -%define version 2.7b2 +%define version 2.7rc1 %define libver 2.7 #--end constants-- %define release 1pydotorg Modified: python/trunk/README ============================================================================== --- python/trunk/README (original) +++ python/trunk/README Sun Jun 6 02:22:09 2010 @@ -1,5 +1,5 @@ -This is Python version 2.7 beta 2 -================================= +This is Python version 2.7 release candidate 1 +============================================== Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Python Software Foundation. From python-checkins at python.org Sun Jun 6 02:49:28 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 02:49:28 +0200 (CEST) Subject: [Python-checkins] r81773 - python/trunk/Lib/pydoc_data/topics.py Message-ID: <20100606004928.1F267EEA27@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 02:49:27 2010 New Revision: 81773 Log: update pydoc-topics Modified: python/trunk/Lib/pydoc_data/topics.py Modified: python/trunk/Lib/pydoc_data/topics.py ============================================================================== --- python/trunk/Lib/pydoc_data/topics.py (original) +++ python/trunk/Lib/pydoc_data/topics.py Sun Jun 6 02:49:27 2010 @@ -1,4 +1,4 @@ -# Autogenerated by Sphinx on Sat May 8 12:01:30 2010 +# Autogenerated by Sphinx on Sat Jun 5 19:26:01 2010 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', From python-checkins at python.org Sun Jun 6 02:50:58 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 02:50:58 +0200 (CEST) Subject: [Python-checkins] r81774 - python/trunk/Doc/library/urllib.rst Message-ID: <20100606005058.EC8C3EEA80@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 02:50:58 2010 New Revision: 81774 Log: remove extra space Modified: python/trunk/Doc/library/urllib.rst Modified: python/trunk/Doc/library/urllib.rst ============================================================================== --- python/trunk/Doc/library/urllib.rst (original) +++ python/trunk/Doc/library/urllib.rst Sun Jun 6 02:50:58 2010 @@ -236,7 +236,7 @@ .. function:: urlencode(query[, doseq]) - Convert a mapping object or a sequence of two-element tuples to a + Convert a mapping object or a sequence of two-element tuples to a "url-encoded" string, suitable to pass to :func:`urlopen` above as the optional *data* argument. This is useful to pass a dictionary of form fields to a ``POST`` request. The resulting string is a series of From python-checkins at python.org Sun Jun 6 02:54:29 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 02:54:29 +0200 (CEST) Subject: [Python-checkins] r81775 - python/trunk/Doc/library/urllib.rst Message-ID: <20100606005429.C1A09EEA27@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 02:54:29 2010 New Revision: 81775 Log: fix sphinx warning with an extra space Modified: python/trunk/Doc/library/urllib.rst Modified: python/trunk/Doc/library/urllib.rst ============================================================================== --- python/trunk/Doc/library/urllib.rst (original) +++ python/trunk/Doc/library/urllib.rst Sun Jun 6 02:54:29 2010 @@ -245,7 +245,7 @@ two-element tuples is used as the *query* argument, the first element of each tuple is a key and the second is a value. The value element in itself can be a sequence and in that case, if the optional parameter *doseq* is - evaluates to *True*, individual ``key=value`` pairs separated by ``'&'``are + evaluates to *True*, individual ``key=value`` pairs separated by ``'&'`` are generated for each element of the value sequence for the key. The order of parameters in the encoded string will match the order of parameter tuples in the sequence. The :mod:`urlparse` module provides the functions From python-checkins at python.org Sun Jun 6 02:55:14 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 02:55:14 +0200 (CEST) Subject: [Python-checkins] r81776 - python/tags/r27rc1 Message-ID: <20100606005514.4361FEEA27@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 02:55:14 2010 New Revision: 81776 Log: tag 2.7's first release candidate Added: python/tags/r27rc1/ - copied from r81775, /python/trunk/ From python-checkins at python.org Sun Jun 6 04:09:34 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 04:09:34 +0200 (CEST) Subject: [Python-checkins] r81777 - in python/trunk: Include/patchlevel.h Misc/NEWS Message-ID: <20100606020934.1DB5DEEAD0@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 04:09:33 2010 New Revision: 81777 Log: careening towards 2.7rc2 we go 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 Sun Jun 6 04:09:33 2010 @@ -27,7 +27,7 @@ #define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "2.7rc1" +#define PY_VERSION "2.7rc1+" /*--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 Sun Jun 6 04:09:33 2010 @@ -4,6 +4,18 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) +What's New in Python release candidate 2? +========================================= + +*Release date: XXXX-XX-XX* + +Core and Builtins +----------------- + +Library +------- + + What's New in Python 2.7 Release Candidate 1? ============================================= From python-checkins at python.org Sun Jun 6 04:14:27 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 04:14:27 +0200 (CEST) Subject: [Python-checkins] r81778 - python/branches/py3k Message-ID: <20100606021427.AF67DEE9FD@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 04:14:27 2010 New Revision: 81778 Log: Blocked revisions 81772-81773,81777 via svnmerge ........ r81772 | benjamin.peterson | 2010-06-05 19:22:09 -0500 (Sat, 05 Jun 2010) | 1 line bump version to 2.7 rc1 ........ r81773 | benjamin.peterson | 2010-06-05 19:49:27 -0500 (Sat, 05 Jun 2010) | 1 line update pydoc-topics ........ r81777 | benjamin.peterson | 2010-06-05 21:09:33 -0500 (Sat, 05 Jun 2010) | 1 line careening towards 2.7rc2 we go ........ Modified: python/branches/py3k/ (props changed) From ncoghlan at gmail.com Sun Jun 6 04:18:28 2010 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sun, 06 Jun 2010 12:18:28 +1000 Subject: [Python-checkins] r81706 - in python/trunk: Lib/test/test_descr.py Objects/abstract.c In-Reply-To: References: <20100605003251.2A9BCEECF3@mail.python.org> <4C0A05E5.3030105@gmail.com> Message-ID: <4C0B0574.1050502@gmail.com> On 06/06/10 04:55, Benjamin Peterson wrote: >> Why kill the microoptimisation here? Looking the string up in the intern >> dict every time (as these changes do) is a waste of cycles. Since avoiding >> it is pretty easy using this common idiom, it's generally worth doing. > > Yes, but that's only applicable to classic classes, which I can't say > I care much about. Ah, true, you do still have it cached in the new-style code. No worries then. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From python-checkins at python.org Sun Jun 6 04:32:09 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 04:32:09 +0200 (CEST) Subject: [Python-checkins] r81779 - in python/branches/py3k: Doc/library/urllib.parse.rst Message-ID: <20100606023209.4E7D7EECC2@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 04:32:09 2010 New Revision: 81779 Log: Merged revisions 81774-81775 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81774 | benjamin.peterson | 2010-06-05 19:50:58 -0500 (Sat, 05 Jun 2010) | 1 line remove extra space ........ r81775 | benjamin.peterson | 2010-06-05 19:54:29 -0500 (Sat, 05 Jun 2010) | 1 line fix sphinx warning with an extra space ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/urllib.parse.rst Modified: python/branches/py3k/Doc/library/urllib.parse.rst ============================================================================== --- python/branches/py3k/Doc/library/urllib.parse.rst (original) +++ python/branches/py3k/Doc/library/urllib.parse.rst Sun Jun 6 04:32:09 2010 @@ -312,7 +312,7 @@ .. function:: urlencode(query, doseq=False) - Convert a mapping object or a sequence of two-element tuples to a + Convert a mapping object or a sequence of two-element tuples to a "url-encoded" string, suitable to pass to :func:`urlopen` above as the optional *data* argument. This is useful to pass a dictionary of form fields to a ``POST`` request. The resulting string is a series of @@ -321,7 +321,7 @@ two-element tuples is used as the *query* argument, the first element of each tuple is a key and the second is a value. The value element in itself can be a sequence and in that case, if the optional parameter *doseq* is - evaluates to *True*, individual ``key=value`` pairs separated by ``'&'``are + evaluates to *True*, individual ``key=value`` pairs separated by ``'&'`` are generated for each element of the value sequence for the key. The order of parameters in the encoded string will match the order of parameter tuples in the sequence. This module provides the functions :func:`parse_qs` and From python-checkins at python.org Sun Jun 6 04:40:38 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 04:40:38 +0200 (CEST) Subject: [Python-checkins] r81780 - python/branches/py3k/Doc/library/sqlite3.rst Message-ID: <20100606024038.578DBEEC85@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 04:40:38 2010 New Revision: 81780 Log: fix typo Modified: python/branches/py3k/Doc/library/sqlite3.rst Modified: python/branches/py3k/Doc/library/sqlite3.rst ============================================================================== --- python/branches/py3k/Doc/library/sqlite3.rst (original) +++ python/branches/py3k/Doc/library/sqlite3.rst Sun Jun 6 04:40:38 2010 @@ -231,7 +231,7 @@ .. versionadded:: 3.2 - :cont:`True` if a transaction is active (there are uncommitted changes), + :const:`True` if a transaction is active (there are uncommitted changes), :const:`False` otherwise. Read-only attribute. From python-checkins at python.org Sun Jun 6 04:41:24 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 04:41:24 +0200 (CEST) Subject: [Python-checkins] r81781 - python/branches/py3k/Doc/library/winreg.rst Message-ID: <20100606024124.A76BCEECB3@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 04:41:24 2010 New Revision: 81781 Log: reST indentation nit Modified: python/branches/py3k/Doc/library/winreg.rst Modified: python/branches/py3k/Doc/library/winreg.rst ============================================================================== --- python/branches/py3k/Doc/library/winreg.rst (original) +++ python/branches/py3k/Doc/library/winreg.rst Sun Jun 6 04:41:24 2010 @@ -111,7 +111,7 @@ The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx Windows API function, which is specific to 64-bit versions of Windows. See the `RegDeleteKeyEx documentation - `__. + `__. *key* is an already open key, or one of the predefined :ref:`HKEY_* constants `. From python-checkins at python.org Sun Jun 6 04:44:41 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 04:44:41 +0200 (CEST) Subject: [Python-checkins] r81782 - python/branches/py3k/Doc/tools/sphinxext/pyspecific.py Message-ID: <20100606024441.D0052EECCE@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 04:44:41 2010 New Revision: 81782 Log: bltn-file-objects don't exist in python3 Modified: python/branches/py3k/Doc/tools/sphinxext/pyspecific.py Modified: python/branches/py3k/Doc/tools/sphinxext/pyspecific.py ============================================================================== --- python/branches/py3k/Doc/tools/sphinxext/pyspecific.py (original) +++ python/branches/py3k/Doc/tools/sphinxext/pyspecific.py Sun Jun 6 04:44:41 2010 @@ -78,7 +78,7 @@ 'assert', 'assignment', 'atom-identifiers', 'atom-literals', 'attribute-access', 'attribute-references', 'augassign', 'binary', 'bitwise', 'bltin-code-objects', 'bltin-ellipsis-object', - 'bltin-file-objects', 'bltin-null-object', 'bltin-type-objects', 'booleans', + 'bltin-null-object', 'bltin-type-objects', 'booleans', 'break', 'callable-types', 'calls', 'class', 'comparisons', 'compound', 'context-managers', 'continue', 'conversions', 'customization', 'debugger', 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'execmodel', From python-checkins at python.org Sun Jun 6 04:51:17 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 6 Jun 2010 04:51:17 +0200 (CEST) Subject: [Python-checkins] r81783 - in python/branches/release31-maint: Doc/tools/sphinxext/pyspecific.py Message-ID: <20100606025117.AA18BEE9E3@mail.python.org> Author: benjamin.peterson Date: Sun Jun 6 04:51:17 2010 New Revision: 81783 Log: Merged revisions 81782 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81782 | benjamin.peterson | 2010-06-05 21:44:41 -0500 (Sat, 05 Jun 2010) | 1 line bltn-file-objects don't exist in python3 ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/tools/sphinxext/pyspecific.py Modified: python/branches/release31-maint/Doc/tools/sphinxext/pyspecific.py ============================================================================== --- python/branches/release31-maint/Doc/tools/sphinxext/pyspecific.py (original) +++ python/branches/release31-maint/Doc/tools/sphinxext/pyspecific.py Sun Jun 6 04:51:17 2010 @@ -78,7 +78,7 @@ 'assert', 'assignment', 'atom-identifiers', 'atom-literals', 'attribute-access', 'attribute-references', 'augassign', 'binary', 'bitwise', 'bltin-code-objects', 'bltin-ellipsis-object', - 'bltin-file-objects', 'bltin-null-object', 'bltin-type-objects', 'booleans', + 'bltin-null-object', 'bltin-type-objects', 'booleans', 'break', 'callable-types', 'calls', 'class', 'comparisons', 'compound', 'context-managers', 'continue', 'conversions', 'customization', 'debugger', 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'execmodel', From python-checkins at python.org Sun Jun 6 12:13:18 2010 From: python-checkins at python.org (stefan.krah) Date: Sun, 6 Jun 2010 12:13:18 +0200 (CEST) Subject: [Python-checkins] r81784 - python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Message-ID: <20100606101318.3A516EEA03@mail.python.org> Author: stefan.krah Date: Sun Jun 6 12:13:18 2010 New Revision: 81784 Log: In rare corner cases, exp, ln and log10 did not set Underflow. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Sun Jun 6 12:13:18 2010 @@ -1606,6 +1606,20 @@ } } +/* Transcendental functions do not always set Underflow reliably, + * since they only use as much precision as is necessary for correct + * rounding. If a result like 1.0000000000e-101 is finalized, there + * is no rounding digit that would trigger Underflow. But we can + * assume Inexact, so a short check suffices. */ +static inline void +mpd_check_underflow(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status) +{ + if (mpd_adjexp(dec) < ctx->emin && !mpd_iszero(dec) && + dec->exp < mpd_etiny(ctx)) { + *status |= MPD_Underflow; + } +} + /* Check if a normal number must be rounded after the exponent has been checked. */ static inline void _mpd_check_round(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status) @@ -3868,6 +3882,7 @@ if (mpd_isspecial(result) || mpd_iszerocoeff(result) || mpd_qcmp(&t1, &t2, status) == 0) { workctx.clamp = ctx->clamp; + mpd_check_underflow(result, &workctx, status); mpd_qfinalize(result, &workctx, status); break; } @@ -3880,6 +3895,7 @@ } else { _mpd_qexp(result, a, &workctx, status); + mpd_check_underflow(result, &workctx, status); mpd_qfinalize(result, &workctx, status); } } @@ -4261,6 +4277,7 @@ if (mpd_isspecial(result) || mpd_iszerocoeff(result) || mpd_qcmp(&t1, &t2, status) == 0) { workctx.clamp = ctx->clamp; + mpd_check_underflow(result, &workctx, status); mpd_qfinalize(result, &workctx, status); break; } @@ -4273,6 +4290,7 @@ } else { _mpd_qln(result, a, &workctx, status); + mpd_check_underflow(result, &workctx, status); mpd_qfinalize(result, &workctx, status); } } @@ -4376,6 +4394,7 @@ if (mpd_isspecial(result) || mpd_iszerocoeff(result) || mpd_qcmp(&t1, &t2, status) == 0) { workctx.clamp = ctx->clamp; + mpd_check_underflow(result, &workctx, status); mpd_qfinalize(result, &workctx, status); break; } @@ -4388,6 +4407,7 @@ } else { _mpd_qlog10(result, a, &workctx, status); + mpd_check_underflow(result, &workctx, status); } } From python-checkins at python.org Sun Jun 6 12:20:38 2010 From: python-checkins at python.org (stefan.krah) Date: Sun, 6 Jun 2010 12:20:38 +0200 (CEST) Subject: [Python-checkins] r81785 - python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randfloat.py Message-ID: <20100606102038.3D1B2EEA6D@mail.python.org> Author: stefan.krah Date: Sun Jun 6 12:20:38 2010 New Revision: 81785 Log: Test setting of Underflow in ln corner cases. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randfloat.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randfloat.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randfloat.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/randfloat.py Sun Jun 6 12:20:38 2010 @@ -204,6 +204,19 @@ '999999999999999999999999999999999990000000000000000' #... '000000000000000000000000000000000000000000000000000' #... '1', + + # tough cases for ln etc. + '1.000000000000000000000000000000000000000000000000' #... + '00000000000000000000000000000000000000000000000000' #... + '00100000000000000000000000000000000000000000000000' #... + '00000000000000000000000000000000000000000000000000' #... + '0001', + '0.999999999999999999999999999999999999999999999999' #... + '99999999999999999999999999999999999999999999999999' #... + '99899999999999999999999999999999999999999999999999' #... + '99999999999999999999999999999999999999999999999999' #... + '99999999999999999999999999999999999999999999999999' #... + '9999' ] From python-checkins at python.org Sun Jun 6 12:27:11 2010 From: python-checkins at python.org (stefan.krah) Date: Sun, 6 Jun 2010 12:27:11 +0200 (CEST) Subject: [Python-checkins] r81786 - python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py Message-ID: <20100606102711.97FBAEEA03@mail.python.org> Author: stefan.krah Date: Sun Jun 6 12:27:11 2010 New Revision: 81786 Log: Remove workaround for Python 2.5 from __hash__ and fix typos. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py Sun Jun 6 12:27:11 2010 @@ -313,15 +313,15 @@ return True def exp(self, result, operands): - if context.f.allcr: return False + if context.f._allcr: return False return self.un_resolve_ulp(result, "exp", operands) def log10(self, result, operands): - if context.f.allcr: return False + if context.f._allcr: return False return self.un_resolve_ulp(result, "log10", operands) def ln(self, result, operands): - if context.f.allcr: return False + if context.f._allcr: return False return self.un_resolve_ulp(result, "ln", operands) def __pow__(self, result, operands): @@ -615,19 +615,10 @@ return self.obj_binaryfunc(other, '__gt__') def __hash__(self): - global PY25_HASH_HAVE_WARNED if self.mpd.is_nan(): - return cdec(0) # for testing + return None # for testing raise TypeError('Cannot hash a NaN value.') - ret = None - try: # Python 2.5 can use exorbitant amounts of memory - ret = self.obj_unaryfunc('__hash__') - except MemoryError: - if not PY25_HASH_HAVE_WARNED: - sys.stderr.write("Out of memory while hashing %s: upgrade to Python 2.6\n" - % str(self.mpd)) - PY25_HASH_HAVE_WARNED = 1 - return ret + return self.obj_unaryfunc('__hash__') def __int__(self): # ValueError or OverflowError @@ -1301,15 +1292,15 @@ if '--medium' in sys.argv: base['expts'].append(('rand', 'rand')) base['samples'] = None - testspecs = [small, ieee, base] + testspecs = [small] + ieee + [base] if '--long' in sys.argv: base['expts'].append(('rand', 'rand')) base['samples'] = 5 - testspecs = [small, ieee, base] + testspecs = [small] + ieee + [base] elif '--all' in sys.argv: base['expts'].append(('rand', 'rand')) base['samples'] = 100 - testspecs = [small, ieee, base] + testspecs = [small] + ieee + [base] else: # --short rand_ieee = random.choice(ieee) base['iter'] = small['iter'] = rand_ieee['iter'] = 1 From python-checkins at python.org Sun Jun 6 13:45:18 2010 From: python-checkins at python.org (stefan.krah) Date: Sun, 6 Jun 2010 13:45:18 +0200 (CEST) Subject: [Python-checkins] r81787 - python/branches/py3k-cdecimal/setup.py Message-ID: <20100606114518.10220EE9B3@mail.python.org> Author: stefan.krah Date: Sun Jun 6 13:45:17 2010 New Revision: 81787 Log: New default: use thread local contexts. Modified: python/branches/py3k-cdecimal/setup.py Modified: python/branches/py3k-cdecimal/setup.py ============================================================================== --- python/branches/py3k-cdecimal/setup.py (original) +++ python/branches/py3k-cdecimal/setup.py Sun Jun 6 13:45:17 2010 @@ -1662,8 +1662,8 @@ define_macros.append(('ANSI', '1')) else: raise DistutilsError("cdecimal: unsupported architecture") - # Not recommended: TLS is very slow! - # define_macros.append(('USE_THREAD_LOCAL_STORAGE', 1)) + # Faster version without thread local contexts: + # define_macros.append(('WITHOUT_THREADS', 1)) if 'sunos' in platform and cc == 'cc': # suncc extra_compile_args.extend(['-erroff=E_ARGUEMENT_MISMATCH']) ext = Extension ( From python-checkins at python.org Sun Jun 6 22:05:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 6 Jun 2010 22:05:20 +0200 (CEST) Subject: [Python-checkins] r81788 - in python/trunk: Doc/distutils/builtdist.rst Misc/NEWS Message-ID: <20100606200520.54201EEDFF@mail.python.org> Author: tarek.ziade Date: Sun Jun 6 22:05:20 2010 New Revision: 81788 Log: Fixed #8909: now the doc details the size of the bitmap used in distutils' bdist_wininst Modified: python/trunk/Doc/distutils/builtdist.rst python/trunk/Misc/NEWS Modified: python/trunk/Doc/distutils/builtdist.rst ============================================================================== --- python/trunk/Doc/distutils/builtdist.rst (original) +++ python/trunk/Doc/distutils/builtdist.rst Sun Jun 6 22:05:20 2010 @@ -322,7 +322,7 @@ option. By default the installer will display the cool "Python Powered" logo when it is -run, but you can also supply your own bitmap which must be a Windows +run, but you can also supply your own 152x161 bitmap which must be a Windows :file:`.bmp` file with the :option:`--bitmap` option. The installer will also display a large title on the desktop background window Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Jun 6 22:05:20 2010 @@ -15,6 +15,12 @@ Library ------- +Documentation +------------- + +- Issues #8909: Added the size of the bitmap used in the installer created by + distutils' bdist_wininst. Patch by Anatoly Techtonik. + What's New in Python 2.7 Release Candidate 1? ============================================= From python-checkins at python.org Sun Jun 6 22:10:03 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 6 Jun 2010 22:10:03 +0200 (CEST) Subject: [Python-checkins] r81789 - in python/branches/release26-maint: Doc/distutils/builtdist.rst Misc/NEWS Message-ID: <20100606201003.9E184EEE02@mail.python.org> Author: tarek.ziade Date: Sun Jun 6 22:10:03 2010 New Revision: 81789 Log: Merged revisions 81788 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81788 | tarek.ziade | 2010-06-06 22:05:20 +0200 (Sun, 06 Jun 2010) | 1 line Fixed #8909: now the doc details the size of the bitmap used in distutils' bdist_wininst ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/distutils/builtdist.rst python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Doc/distutils/builtdist.rst ============================================================================== --- python/branches/release26-maint/Doc/distutils/builtdist.rst (original) +++ python/branches/release26-maint/Doc/distutils/builtdist.rst Sun Jun 6 22:10:03 2010 @@ -318,7 +318,7 @@ option. By default the installer will display the cool "Python Powered" logo when it is -run, but you can also supply your own bitmap which must be a Windows +run, but you can also supply your own 152x161 bitmap which must be a Windows :file:`.bmp` file with the :option:`--bitmap` option. The installer will also display a large title on the desktop background window Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Jun 6 22:10:03 2010 @@ -282,6 +282,12 @@ - Issue #8193: Fix test_zlib failure with zlib 1.2.4. +Documentation +------------- + +- Issue #8909: Added the size of the bitmap used in the installer created by + distutils' bdist_wininst. Patch by Anatoly Techtonik. + What's New in Python 2.6.5? =========================== From python-checkins at python.org Sun Jun 6 22:18:42 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 6 Jun 2010 22:18:42 +0200 (CEST) Subject: [Python-checkins] r81790 - in python/branches/py3k: Doc/distutils/builtdist.rst Misc/NEWS Message-ID: <20100606201842.6071BEEA5F@mail.python.org> Author: tarek.ziade Date: Sun Jun 6 22:18:42 2010 New Revision: 81790 Log: Merged revisions 81788 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81788 | tarek.ziade | 2010-06-06 22:05:20 +0200 (Sun, 06 Jun 2010) | 1 line Fixed #8909: now the doc details the size of the bitmap used in distutils' bdist_wininst ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/distutils/builtdist.rst python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/distutils/builtdist.rst ============================================================================== --- python/branches/py3k/Doc/distutils/builtdist.rst (original) +++ python/branches/py3k/Doc/distutils/builtdist.rst Sun Jun 6 22:18:42 2010 @@ -322,7 +322,7 @@ option. By default the installer will display the cool "Python Powered" logo when it is -run, but you can also supply your own bitmap which must be a Windows +run, but you can also supply your own 152x161 bitmap which must be a Windows :file:`.bmp` file with the :option:`--bitmap` option. The installer will also display a large title on the desktop background window Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Jun 6 22:18:42 2010 @@ -1421,6 +1421,9 @@ - Update python manual page (options -B, -O0, -s, environment variables PYTHONDONTWRITEBYTECODE, PYTHONNOUSERSITE). +- Issue #8909: Added the size of the bitmap used in the installer created by + distutils' bdist_wininst. Patch by Anatoly Techtonik. + Tests ----- From python-checkins at python.org Sun Jun 6 22:23:10 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 6 Jun 2010 22:23:10 +0200 (CEST) Subject: [Python-checkins] r81791 - in python/branches/release31-maint: Doc/distutils/builtdist.rst Misc/NEWS Message-ID: <20100606202310.C96FAEEB38@mail.python.org> Author: tarek.ziade Date: Sun Jun 6 22:23:10 2010 New Revision: 81791 Log: Merged revisions 81790 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81790 | tarek.ziade | 2010-06-06 22:18:42 +0200 (Sun, 06 Jun 2010) | 9 lines Merged revisions 81788 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81788 | tarek.ziade | 2010-06-06 22:05:20 +0200 (Sun, 06 Jun 2010) | 1 line Fixed #8909: now the doc details the size of the bitmap used in distutils' bdist_wininst ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/distutils/builtdist.rst python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Doc/distutils/builtdist.rst ============================================================================== --- python/branches/release31-maint/Doc/distutils/builtdist.rst (original) +++ python/branches/release31-maint/Doc/distutils/builtdist.rst Sun Jun 6 22:23:10 2010 @@ -321,7 +321,7 @@ option. By default the installer will display the cool "Python Powered" logo when it is -run, but you can also supply your own bitmap which must be a Windows +run, but you can also supply your own 152x161 bitmap which must be a Windows :file:`.bmp` file with the :option:`--bitmap` option. The installer will also display a large title on the desktop background window Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Jun 6 22:23:10 2010 @@ -774,6 +774,9 @@ - Update python manual page (options -B, -O0, -s, environment variables PYTHONDONTWRITEBYTECODE, PYTHONNOUSERSITE). +- Issue #8909: Added the size of the bitmap used in the installer created by + distutils' bdist_wininst. Patch by Anatoly Techtonik. + What's New in Python 3.1.1? =========================== From python-checkins at python.org Sun Jun 6 22:27:51 2010 From: python-checkins at python.org (victor.stinner) Date: Sun, 6 Jun 2010 22:27:51 +0200 (CEST) Subject: [Python-checkins] r81792 - python/branches/py3k/Python/getargs.c Message-ID: <20100606202751.D28F4EEB3C@mail.python.org> Author: victor.stinner Date: Sun Jun 6 22:27:51 2010 New Revision: 81792 Log: Simplify getbuffer(): convertbuffer() fails anyway if bf_getbuffer is NULL Modified: python/branches/py3k/Python/getargs.c Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Sun Jun 6 22:27:51 2010 @@ -1410,7 +1410,7 @@ static Py_ssize_t convertbuffer(PyObject *arg, void **p, char **errmsg) { - PyBufferProcs *pb = arg->ob_type->tp_as_buffer; + PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; Py_ssize_t count; Py_buffer view; @@ -1438,31 +1438,23 @@ static int getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) { - void *buf; - Py_ssize_t count; - PyBufferProcs *pb = arg->ob_type->tp_as_buffer; + PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; if (pb == NULL) { *errmsg = "bytes or buffer"; return -1; } - if (pb->bf_getbuffer) { - if (PyObject_GetBuffer(arg, view, 0) < 0) { - *errmsg = "convertible to a buffer"; - return -1; - } - if (!PyBuffer_IsContiguous(view, 'C')) { - *errmsg = "contiguous buffer"; - return -1; - } - return 0; + if (pb->bf_getbuffer == NULL) { + *errmsg = "convertible to a buffer"; + return -1; } - - count = convertbuffer(arg, &buf, errmsg); - if (count < 0) { + if (PyObject_GetBuffer(arg, view, 0) < 0) { *errmsg = "convertible to a buffer"; - return count; + return -1; + } + if (!PyBuffer_IsContiguous(view, 'C')) { + *errmsg = "contiguous buffer"; + return -1; } - PyBuffer_FillInfo(view, NULL, buf, count, 1, 0); return 0; } From python-checkins at python.org Sun Jun 6 22:33:05 2010 From: python-checkins at python.org (victor.stinner) Date: Sun, 6 Jun 2010 22:33:05 +0200 (CEST) Subject: [Python-checkins] r81793 - python/branches/release31-maint Message-ID: <20100606203305.80CFFEBB5@mail.python.org> Author: victor.stinner Date: Sun Jun 6 22:33:05 2010 New Revision: 81793 Log: Blocked revisions 81792 via svnmerge ........ r81792 | victor.stinner | 2010-06-06 22:27:51 +0200 (dim., 06 juin 2010) | 2 lines Simplify getbuffer(): convertbuffer() fails anyway if bf_getbuffer is NULL ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Jun 6 22:38:02 2010 From: python-checkins at python.org (victor.stinner) Date: Sun, 6 Jun 2010 22:38:02 +0200 (CEST) Subject: [Python-checkins] r81794 - python/branches/py3k/Python/getargs.c Message-ID: <20100606203802.93F58EEE35@mail.python.org> Author: victor.stinner Date: Sun Jun 6 22:38:02 2010 New Revision: 81794 Log: convertsimple(): call PyErr_NoMemory() on PyMem_NEW() failure Raise a more revelant error (MemoryError instead of TypeError) Modified: python/branches/py3k/Python/getargs.c Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Sun Jun 6 22:38:02 2010 @@ -1172,6 +1172,7 @@ *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); + PyErr_NoMemory(); return converterr( "(memory error)", arg, msgbuf, bufsize); @@ -1215,6 +1216,7 @@ *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); + PyErr_NoMemory(); return converterr("(memory error)", arg, msgbuf, bufsize); } From python-checkins at python.org Sun Jun 6 22:38:57 2010 From: python-checkins at python.org (victor.stinner) Date: Sun, 6 Jun 2010 22:38:57 +0200 (CEST) Subject: [Python-checkins] r81795 - python/branches/release31-maint Message-ID: <20100606203857.231B3EEB39@mail.python.org> Author: victor.stinner Date: Sun Jun 6 22:38:57 2010 New Revision: 81795 Log: Blocked revisions 81794 via svnmerge ........ r81794 | victor.stinner | 2010-06-06 22:38:02 +0200 (dim., 06 juin 2010) | 4 lines convertsimple(): call PyErr_NoMemory() on PyMem_NEW() failure Raise a more revelant error (MemoryError instead of TypeError) ........ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Mon Jun 7 01:23:42 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 7 Jun 2010 01:23:42 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81794): sum=0 Message-ID: <20100606232342.9F65B17758@ns6635.ovh.net> py3k results for svn r81794 (hg cset 805a4e38517f) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogIlGttn', '-x'] From python-checkins at python.org Mon Jun 7 12:46:04 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 7 Jun 2010 12:46:04 +0200 (CEST) Subject: [Python-checkins] r81796 - in python/branches/py3k-cdecimal: Doc/c-api/init.rst Doc/c-api/sys.rst Doc/distutils/builtdist.rst Doc/extending/newtypes.rst Doc/howto/descriptor.rst Doc/howto/index.rst Doc/library/argparse.rst Doc/library/datetime.rst Doc/library/decimal.rst Doc/library/dis.rst Doc/library/fcntl.rst Doc/library/ftplib.rst Doc/library/functions.rst Doc/library/getopt.rst Doc/library/hashlib.rst Doc/library/io.rst Doc/library/json.rst Doc/library/multiprocessing.rst Doc/library/optparse.rst Doc/library/os.rst Doc/library/socket.rst Doc/library/sqlite3.rst Doc/library/ssl.rst Doc/library/stdtypes.rst Doc/library/subprocess.rst Doc/library/symtable.rst Doc/library/sys.rst Doc/library/sysconfig.rst Doc/library/syslog.rst Doc/library/telnetlib.rst Doc/library/tempfile.rst Doc/library/time.rst Doc/library/unittest.rst Doc/library/urllib.parse.rst Doc/library/urllib.request.rst Doc/library/winreg.rst Doc/reference/datamodel.rst Doc/tools/sphinxext/pyspecific.py Doc/tutorial/datastructures.rst Doc/whatsnew/3.2.rst Include/longobject.h Include/pyport.h Include/sysmodule.h Lib/_abcoll.py Lib/argparse.py Lib/base64.py Lib/codecs.py Lib/decimal.py Lib/distutils/log.py Lib/distutils/tests/test_log.py Lib/distutils/unixccompiler.py Lib/email/charset.py Lib/email/encoders.py Lib/email/test/test_email.py Lib/encodings/utf_16.py Lib/encodings/utf_32.py Lib/fractions.py Lib/ftplib.py Lib/functools.py Lib/html/parser.py Lib/http/client.py Lib/lib2to3/refactor.py Lib/linecache.py Lib/pipes.py Lib/sqlite3/test/dbapi.py Lib/ssl.py Lib/subprocess.py Lib/sysconfig.py Lib/tabnanny.py Lib/tarfile.py Lib/test/regrtest.py Lib/test/test_argparse.py Lib/test/test_base64.py Lib/test/test_builtin.py Lib/test/test_codecs.py Lib/test/test_collections.py Lib/test/test_complex.py Lib/test/test_datetime.py Lib/test/test_decimal.py Lib/test/test_descr.py Lib/test/test_enumerate.py Lib/test/test_float.py Lib/test/test_ftplib.py Lib/test/test_gdb.py Lib/test/test_htmlparser.py Lib/test/test_httplib.py Lib/test/test_linecache.py Lib/test/test_long.py Lib/test/test_numeric_tower.py Lib/test/test_os.py Lib/test/test_pipes.py Lib/test/test_socketserver.py Lib/test/test_ssl.py Lib/test/test_subprocess.py Lib/test/test_sys.py Lib/test/test_sysconfig.py Lib/test/test_tarfile.py Lib/test/test_tcl.py Lib/test/test_urllib2.py Lib/test/test_warnings.py Lib/test/test_winreg.py Lib/test/test_winsound.py Lib/test/testtar.tar Lib/tkinter/_fix.py Lib/unittest/case.py Lib/unittest/loader.py Lib/unittest/suite.py Lib/unittest/test/test_case.py Lib/unittest/test/test_setups.py Lib/unittest/util.py Lib/urllib/request.py Lib/webbrowser.py Mac/Tools/pythonw.c Misc/ACKS Misc/NEWS Misc/developers.txt Modules/_multiprocessing/multiprocessing.h Modules/_sqlite/connection.c Modules/_ssl.c Modules/config.c.in Modules/datetimemodule.c Modules/main.c Modules/timemodule.c Objects/abstract.c Objects/complexobject.c Objects/longobject.c Objects/object.c Objects/typeobject.c PC/winreg.c Python/_warnings.c Python/ceval.c Python/getargs.c Python/pythonrun.c Python/sysmodule.c Tools/gdb/libpython.py Tools/i18n/msgfmt.py Tools/scripts/serve.py configure configure.in setup.py Message-ID: <20100607104604.16021EEE8F@mail.python.org> Author: stefan.krah Date: Mon Jun 7 12:46:02 2010 New Revision: 81796 Log: Merged revisions 81352,81356,81358-81361,81364-81368,81370,81372,81375,81378,81387,81392-81393,81397,81400,81403,81406,81410,81417-81418,81421,81424,81427,81435,81438,81442,81446,81452,81455,81457,81461,81470,81474,81476,81481,81485-81486,81491,81493,81495,81498,81504,81511,81513-81514,81519,81522,81526,81528,81532-81533,81535,81538,81541,81545,81547-81548,81550,81553,81556-81557,81560,81564-81565,81568,81572,81575,81581,81583,81585,81588,81590,81595,81600,81604,81607,81609,81611-81613,81623,81625,81628,81630,81632,81638,81642,81647,81650,81654,81656,81660,81665,81670,81673,81682,81685,81689,81694-81695,81698-81699,81703,81708,81711,81713,81725,81730-81731,81737,81742-81743,81746,81748,81751,81754-81755,81757,81762,81765-81766,81768,81771,81778-81782,81790,81792,81794 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81352 | stefan.krah | 2010-05-19 17:52:31 +0200 (Wed, 19 May 2010) | 9 lines Merged revisions 81350 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81350 | stefan.krah | 2010-05-19 17:46:39 +0200 (Wed, 19 May 2010) | 1 line Fix typos in docstrings. ........ ................ r81356 | stefan.krah | 2010-05-19 18:09:41 +0200 (Wed, 19 May 2010) | 9 lines Merged revisions 81354 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81354 | stefan.krah | 2010-05-19 17:59:40 +0200 (Wed, 19 May 2010) | 3 lines Fix typo. ........ ................ r81358 | victor.stinner | 2010-05-19 18:53:30 +0200 (Wed, 19 May 2010) | 4 lines Issue #8589: Decode PYTHONWARNINGS environment variable with the file system encoding and surrogateespace error handler instead of the locale encoding to be consistent with os.environ. Add PySys_AddWarnOptionUnicode() function. ................ r81359 | victor.stinner | 2010-05-19 19:00:07 +0200 (Wed, 19 May 2010) | 4 lines Issue #8663: distutils.log emulates backslashreplace error handler. Fix compilation in a non-ASCII directory if stdout encoding is ASCII (eg. if stdout is not a TTY). ................ r81360 | victor.stinner | 2010-05-19 19:11:19 +0200 (Wed, 19 May 2010) | 5 lines regrtest.py: call replace_stdout() before the first call to print() print("== ", os.getcwd()) fails if the current working directory is not ASCII whereas sys.stdout encoding is ASCII. ................ r81361 | victor.stinner | 2010-05-19 19:15:50 +0200 (Wed, 19 May 2010) | 2 lines Oops, add the new test_log.py for distutils test suite (missing part of r81359) ................ r81364 | victor.stinner | 2010-05-19 22:40:50 +0200 (Wed, 19 May 2010) | 3 lines Issue #8766: Initialize _warnings module before importing the first module. Fix a crash if an empty directory called "encodings" exists in sys.path. ................ r81365 | georg.brandl | 2010-05-19 22:57:08 +0200 (Wed, 19 May 2010) | 77 lines Merged revisions 80030,80067,80069,80080-80081,80084,80432-80433,80465-80470,81059,81065-81067 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r80030 | georg.brandl | 2010-04-13 08:43:54 +0200 (Di, 13 Apr 2010) | 1 line Get rid of multi-row cells. ........ r80067 | georg.brandl | 2010-04-14 10:53:38 +0200 (Mi, 14 Apr 2010) | 1 line #5341: typo. ........ r80069 | georg.brandl | 2010-04-14 15:50:31 +0200 (Mi, 14 Apr 2010) | 1 line Add an x-ref to where the O_ constants are documented and move the SEEK_ constants after lseek(). ........ r80080 | georg.brandl | 2010-04-14 21:16:38 +0200 (Mi, 14 Apr 2010) | 1 line #8399: add note about Windows and O_BINARY. ........ r80081 | georg.brandl | 2010-04-14 23:34:44 +0200 (Mi, 14 Apr 2010) | 1 line #5250: document __instancecheck__ and __subclasscheck__. I hope the part about the class/metaclass distinction is understandable. ........ r80084 | georg.brandl | 2010-04-14 23:46:45 +0200 (Mi, 14 Apr 2010) | 1 line Fix missing. ........ r80432 | georg.brandl | 2010-04-24 10:56:58 +0200 (Sa, 24 Apr 2010) | 1 line Markup fixes. ........ r80433 | georg.brandl | 2010-04-24 11:08:10 +0200 (Sa, 24 Apr 2010) | 1 line #7507: quote "!" in pipes.quote(); it is a special character for some shells. ........ r80465 | georg.brandl | 2010-04-25 12:29:17 +0200 (So, 25 Apr 2010) | 1 line Remove LaTeXy index entry syntax. ........ r80466 | georg.brandl | 2010-04-25 12:54:42 +0200 (So, 25 Apr 2010) | 1 line Patch from Tim Hatch: Better cross-referencing in socket and winreg docs. ........ r80467 | georg.brandl | 2010-04-25 12:55:16 +0200 (So, 25 Apr 2010) | 1 line Patch from Tim Hatch: Remove reference to winreg being the fabled high-level registry interface. ........ r80468 | georg.brandl | 2010-04-25 12:55:58 +0200 (So, 25 Apr 2010) | 1 line Patch from Tim Hatch: Minor spelling changes to _winreg docs. ........ r80469 | georg.brandl | 2010-04-25 12:56:41 +0200 (So, 25 Apr 2010) | 1 line Fix code example to have valid syntax so that it can be highlighted. ........ r80470 | georg.brandl | 2010-04-25 12:57:15 +0200 (So, 25 Apr 2010) | 1 line Patch from Tim Hatch: Make socket setblocking <-> settimeout examples symmetric. ........ r81059 | georg.brandl | 2010-05-10 23:02:51 +0200 (Mo, 10 Mai 2010) | 1 line #8642: fix wrong function name. ........ r81065 | georg.brandl | 2010-05-10 23:46:50 +0200 (Mo, 10 Mai 2010) | 1 line Fix reference direction. ........ r81066 | georg.brandl | 2010-05-10 23:50:57 +0200 (Mo, 10 Mai 2010) | 1 line Consolidate deprecation messages. ........ r81067 | georg.brandl | 2010-05-10 23:51:33 +0200 (Mo, 10 Mai 2010) | 1 line Fix typo. ........ ................ r81366 | georg.brandl | 2010-05-19 22:58:02 +0200 (Wed, 19 May 2010) | 61 lines Recorded merge of revisions 80030,80067,80069,80080-80081,80084,80432-80433,80465,80470,81059,81065-81067 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r80030 | georg.brandl | 2010-04-13 08:43:54 +0200 (Di, 13 Apr 2010) | 1 line Get rid of multi-row cells. ........ r80067 | georg.brandl | 2010-04-14 10:53:38 +0200 (Mi, 14 Apr 2010) | 1 line #5341: typo. ........ r80069 | georg.brandl | 2010-04-14 15:50:31 +0200 (Mi, 14 Apr 2010) | 1 line Add an x-ref to where the O_ constants are documented and move the SEEK_ constants after lseek(). ........ r80080 | georg.brandl | 2010-04-14 21:16:38 +0200 (Mi, 14 Apr 2010) | 1 line #8399: add note about Windows and O_BINARY. ........ r80081 | georg.brandl | 2010-04-14 23:34:44 +0200 (Mi, 14 Apr 2010) | 1 line #5250: document __instancecheck__ and __subclasscheck__. I hope the part about the class/metaclass distinction is understandable. ........ r80084 | georg.brandl | 2010-04-14 23:46:45 +0200 (Mi, 14 Apr 2010) | 1 line Fix missing. ........ r80432 | georg.brandl | 2010-04-24 10:56:58 +0200 (Sa, 24 Apr 2010) | 1 line Markup fixes. ........ r80433 | georg.brandl | 2010-04-24 11:08:10 +0200 (Sa, 24 Apr 2010) | 1 line #7507: quote "!" in pipes.quote(); it is a special character for some shells. ........ r80465 | georg.brandl | 2010-04-25 12:29:17 +0200 (So, 25 Apr 2010) | 1 line Remove LaTeXy index entry syntax. ........ r80470 | georg.brandl | 2010-04-25 12:57:15 +0200 (So, 25 Apr 2010) | 1 line Patch from Tim Hatch: Make socket setblocking <-> settimeout examples symmetric. ........ r81059 | georg.brandl | 2010-05-10 23:02:51 +0200 (Mo, 10 Mai 2010) | 1 line #8642: fix wrong function name. ........ r81065 | georg.brandl | 2010-05-10 23:46:50 +0200 (Mo, 10 Mai 2010) | 1 line Fix reference direction. ........ r81066 | georg.brandl | 2010-05-10 23:50:57 +0200 (Mo, 10 Mai 2010) | 1 line Consolidate deprecation messages. ........ r81067 | georg.brandl | 2010-05-10 23:51:33 +0200 (Mo, 10 Mai 2010) | 1 line Fix typo. ........ ................ r81367 | georg.brandl | 2010-05-19 23:03:51 +0200 (Wed, 19 May 2010) | 21 lines Recorded merge of revisions 80466-80469 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r80466 | georg.brandl | 2010-04-25 12:54:42 +0200 (So, 25 Apr 2010) | 1 line Patch from Tim Hatch: Better cross-referencing in socket and winreg docs. ........ r80467 | georg.brandl | 2010-04-25 12:55:16 +0200 (So, 25 Apr 2010) | 1 line Patch from Tim Hatch: Remove reference to winreg being the fabled high-level registry interface. ........ r80468 | georg.brandl | 2010-04-25 12:55:58 +0200 (So, 25 Apr 2010) | 1 line Patch from Tim Hatch: Minor spelling changes to _winreg docs. ........ r80469 | georg.brandl | 2010-04-25 12:56:41 +0200 (So, 25 Apr 2010) | 1 line Fix code example to have valid syntax so that it can be highlighted. ........ ................ r81368 | georg.brandl | 2010-05-19 23:06:36 +0200 (Wed, 19 May 2010) | 9 lines Merged revisions 80068 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r80068 | georg.brandl | 2010-04-14 10:56:01 +0200 (Mi, 14 Apr 2010) | 1 line #5341: fix typo and adapt docstring syntax. ........ ................ r81370 | georg.brandl | 2010-05-19 23:39:51 +0200 (Wed, 19 May 2010) | 1 line Add descriptor HOWTO to py3k docs. ................ r81372 | tarek.ziade | 2010-05-20 00:25:00 +0200 (Thu, 20 May 2010) | 9 lines Merged revisions 81371 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81371 | tarek.ziade | 2010-05-20 00:20:14 +0200 (Thu, 20 May 2010) | 1 line #8759: Fixed user paths in sysconfig for posix and os2 schemes ........ ................ r81375 | victor.stinner | 2010-05-20 01:04:56 +0200 (Thu, 20 May 2010) | 9 lines Issue #8559: improve unicode support of (gdb) libpython.py * Escape non printable characters (use locale.getpreferredencoding()) * Fix support of surrogate pairs * test_gdb.py: use ascii() instead of repr() in gdb program arguments to avoid encoding issues * Fix test_strings() of test_gdb.py for encoding different than UTF-8 (eg. ACSII) ................ r81378 | victor.stinner | 2010-05-20 13:30:37 +0200 (Thu, 20 May 2010) | 14 lines Blocked revisions 81377 via svnmerge ........ r81377 | victor.stinner | 2010-05-20 13:29:45 +0200 (jeu., 20 mai 2010) | 8 lines libpython.py: fix support of non-BMP unicode characters Forward port some code from Python3: * join surrogate pairs if sizeof(Py_UNICODE)==2 * Enable non-BMP test on narrow builds using u"\U0001D121" instead of unichr(0x1D121) ........ ................ r81387 | benjamin.peterson | 2010-05-21 00:29:43 +0200 (Fri, 21 May 2010) | 9 lines Merged revisions 81385 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81385 | benjamin.peterson | 2010-05-20 17:23:37 -0500 (Thu, 20 May 2010) | 1 line fix extra 't' #8778 ........ ................ r81392 | antoine.pitrou | 2010-05-21 11:56:06 +0200 (Fri, 21 May 2010) | 5 lines Issue #4870: Add an `options` attribute to SSL contexts, as well as several ``OP_*`` constants to the `ssl` module. This allows to selectively disable protocol versions, when used in combination with `PROTOCOL_SSLv23`. ................ r81393 | victor.stinner | 2010-05-21 12:52:08 +0200 (Fri, 21 May 2010) | 3 lines Issue #8774: tabnanny uses the encoding cookie (#coding:...) to use the correct encoding ................ r81397 | mark.dickinson | 2010-05-21 16:55:26 +0200 (Fri, 21 May 2010) | 10 lines Issue #8748: Fix two issues with comparisons between complex and integer objects. (1) The comparison could incorrectly return True in some cases (2**53+1 == complex(2**53) == 2**53), breaking transivity of equality. (2) The comparison raised an OverflowError for large integers, leading to unpredictable exceptions when combining integers and complex objects in sets or dicts. Patch by Meador Inge. ................ r81400 | antoine.pitrou | 2010-05-21 19:25:34 +0200 (Fri, 21 May 2010) | 12 lines Merged revisions 81398 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81398 | antoine.pitrou | 2010-05-21 19:12:38 +0200 (ven., 21 mai 2010) | 6 lines Issue #5753: A new C API function, :cfunc:`PySys_SetArgvEx`, allows embedders of the interpreter to set sys.argv without also modifying sys.path. This helps fix `CVE-2008-5983 `_. ........ ................ r81403 | victor.stinner | 2010-05-21 22:13:12 +0200 (Fri, 21 May 2010) | 5 lines Issue #8780: Fix a regression introduced by r78946 in subprocess on Windows Ensure that stdout / stderr is inherited from the parent if stdout=PIPE / stderr=PIPE is not used. ................ r81406 | georg.brandl | 2010-05-21 22:28:13 +0200 (Fri, 21 May 2010) | 9 lines Merged revisions 81404 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81404 | georg.brandl | 2010-05-21 22:24:45 +0200 (Fr, 21 Mai 2010) | 1 line #8783: replace link to now dead hash collision FAQ. ........ ................ r81410 | georg.brandl | 2010-05-21 22:45:12 +0200 (Fri, 21 May 2010) | 1 line Remove redundant example. ................ r81417 | benjamin.peterson | 2010-05-21 22:55:22 +0200 (Fri, 21 May 2010) | 9 lines Merged revisions 81414 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81414 | benjamin.peterson | 2010-05-21 15:51:45 -0500 (Fri, 21 May 2010) | 1 line return NotImplemented from Mapping when comparing to a non-mapping #8729 ........ ................ r81418 | georg.brandl | 2010-05-21 22:57:33 +0200 (Fri, 21 May 2010) | 9 lines Recorded merge of revisions 81415 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81415 | georg.brandl | 2010-05-21 22:52:46 +0200 (Fr, 21 Mai 2010) | 1 line typo ........ ................ r81421 | georg.brandl | 2010-05-21 23:01:32 +0200 (Fri, 21 May 2010) | 1 line Fix variable name in example. ................ r81424 | georg.brandl | 2010-05-21 23:03:02 +0200 (Fri, 21 May 2010) | 8 lines Blocked revisions 81419 via svnmerge ........ r81419 | georg.brandl | 2010-05-21 22:58:12 +0200 (Fr, 21 Mai 2010) | 1 line Add missing parameter in SimpleXMLRPCServer signature. ........ ................ r81427 | georg.brandl | 2010-05-21 23:12:07 +0200 (Fri, 21 May 2010) | 1 line Fix signatures for the various TemporaryFile class^Wfunctions. ................ r81435 | georg.brandl | 2010-05-21 23:33:23 +0200 (Fri, 21 May 2010) | 9 lines Merged revisions 81431 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81431 | georg.brandl | 2010-05-21 23:30:47 +0200 (Fr, 21 Mai 2010) | 1 line #8707: remove duplicate paragraph part. ........ ................ r81438 | benjamin.peterson | 2010-05-21 23:45:06 +0200 (Fri, 21 May 2010) | 25 lines Merged revisions 81428-81429,81432-81433,81437 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81428 | benjamin.peterson | 2010-05-21 16:16:12 -0500 (Fri, 21 May 2010) | 1 line use addCleanup ........ r81429 | benjamin.peterson | 2010-05-21 16:17:22 -0500 (Fri, 21 May 2010) | 1 line fix name ........ r81432 | benjamin.peterson | 2010-05-21 16:31:24 -0500 (Fri, 21 May 2010) | 1 line ensure the last line has a trailing newline #8782 ........ r81433 | benjamin.peterson | 2010-05-21 16:32:49 -0500 (Fri, 21 May 2010) | 1 line remove debugging rubish ........ r81437 | benjamin.peterson | 2010-05-21 16:35:44 -0500 (Fri, 21 May 2010) | 1 line simplify and modernize updatecache() ........ ................ r81442 | georg.brandl | 2010-05-21 23:48:27 +0200 (Fri, 21 May 2010) | 9 lines Merged revisions 81440 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81440 | georg.brandl | 2010-05-21 23:47:05 +0200 (Fr, 21 Mai 2010) | 1 line Correct info for Semaphore.acquire() semantics under OSX. ........ ................ r81446 | georg.brandl | 2010-05-21 23:49:47 +0200 (Fri, 21 May 2010) | 9 lines Merged revisions 81443 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81443 | georg.brandl | 2010-05-21 23:48:57 +0200 (Fr, 21 Mai 2010) | 1 line typo ........ ................ r81452 | georg.brandl | 2010-05-22 00:04:32 +0200 (Sat, 22 May 2010) | 9 lines Merged revisions 81450 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81450 | georg.brandl | 2010-05-22 00:03:29 +0200 (Sa, 22 Mai 2010) | 1 line #8709: mention Windows support for os.devnull. ........ ................ r81455 | victor.stinner | 2010-05-22 00:52:10 +0200 (Sat, 22 May 2010) | 9 lines Blocked revisions 81454 via svnmerge ........ r81454 | victor.stinner | 2010-05-22 00:50:28 +0200 (sam., 22 mai 2010) | 3 lines Issue #5640: Fix Shift-JIS incremental encoder for error handlers different than strict ........ ................ r81457 | victor.stinner | 2010-05-22 01:45:42 +0200 (Sat, 22 May 2010) | 3 lines Issue #3798: sys.exit(message) writes the message to sys.stderr file, instead of the C file stderr, to use stderr encoding and error handler ................ r81461 | victor.stinner | 2010-05-22 04:16:27 +0200 (Sat, 22 May 2010) | 10 lines Merged revisions 81459 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81459 | victor.stinner | 2010-05-22 04:11:07 +0200 (sam., 22 mai 2010) | 3 lines Issue #6268: Fix seek() method of codecs.open(), don't read the BOM twice after seek(0) ........ ................ r81470 | mark.dickinson | 2010-05-22 14:02:35 +0200 (Sat, 22 May 2010) | 1 line Issue #8749: remove unused code in Objects/object.c. Thanks Yaniv Aknin. ................ r81474 | victor.stinner | 2010-05-22 18:59:09 +0200 (Sat, 22 May 2010) | 20 lines Merged revisions 81471-81472 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81471 | victor.stinner | 2010-05-22 15:37:56 +0200 (sam., 22 mai 2010) | 7 lines Issue #6268: More bugfixes about BOM, UTF-16 and UTF-32 * Fix seek() method of codecs.open(), don't write the BOM twice after seek(0) * Fix reset() method of codecs, UTF-16, UTF-32 and StreamWriter classes * test_codecs: use "w+" mode instead of "wt+". "t" mode is not supported by Solaris or Windows, but does it really exist? I found it the in the issue. ........ r81472 | victor.stinner | 2010-05-22 15:44:25 +0200 (sam., 22 mai 2010) | 4 lines Fix my last commit (r81471) about codecs Rememder: don't touch the code just before a commit ........ ................ r81476 | mark.dickinson | 2010-05-22 20:35:36 +0200 (Sat, 22 May 2010) | 2 lines #Issue 8540: Make Context._clamp attribute public in decimal module. ................ r81481 | benjamin.peterson | 2010-05-22 20:59:24 +0200 (Sat, 22 May 2010) | 20 lines Merged revisions 81479 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r81479 | benjamin.peterson | 2010-05-22 13:52:21 -0500 (Sat, 22 May 2010) | 13 lines Merged revisions 80937,81478 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r80937 | benjamin.peterson | 2010-05-07 14:10:58 -0500 (Fri, 07 May 2010) | 1 line remove redundant unicode call ........ r81478 | benjamin.peterson | 2010-05-22 13:47:39 -0500 (Sat, 22 May 2010) | 1 line ensure doctests have some future_features ........ ................ ................ r81485 | mark.dickinson | 2010-05-23 15:26:48 +0200 (Sun, 23 May 2010) | 1 line Remove duplicate NEWS entry. ................ r81486 | mark.dickinson | 2010-05-23 15:33:13 +0200 (Sun, 23 May 2010) | 6 lines Issue #8188: Introduce a new scheme for computing hashes of numbers (instances of int, float, complex, decimal.Decimal and fractions.Fraction) that makes it easy to maintain the invariant that hash(x) == hash(y) whenever x and y have equal value. ................ r81491 | steven.bethard | 2010-05-24 05:21:08 +0200 (Mon, 24 May 2010) | 9 lines Merged revisions 81490 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81490 | steven.bethard | 2010-05-23 19:38:00 -0700 (Sun, 23 May 2010) | 1 line argparse documentation updates (including updates to optparse and getopt documentation that were promised in the PEP) ........ ................ r81493 | steven.bethard | 2010-05-24 05:47:38 +0200 (Mon, 24 May 2010) | 9 lines Merged revisions 81492 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81492 | steven.bethard | 2010-05-23 20:45:26 -0700 (Sun, 23 May 2010) | 1 line Fix default value for version help. Approved by Benjamin on python-dev: http://mail.python.org/pipermail/python-dev/2010-May/100231.html ........ ................ r81495 | antoine.pitrou | 2010-05-24 17:58:43 +0200 (Mon, 24 May 2010) | 3 lines Add a versionadded tag for SSL contexts. ................ r81498 | antoine.pitrou | 2010-05-24 23:20:20 +0200 (Mon, 24 May 2010) | 3 lines Document the context attribute of SSL sockets ................ r81504 | victor.stinner | 2010-05-24 23:46:25 +0200 (Mon, 24 May 2010) | 13 lines Recorded merge of revisions 81500-81501 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81500 | victor.stinner | 2010-05-24 23:33:24 +0200 (lun., 24 mai 2010) | 2 lines Issue #6662: Fix parsing of malformatted charref (&#bad;) ........ r81501 | victor.stinner | 2010-05-24 23:37:28 +0200 (lun., 24 mai 2010) | 2 lines Add the author of the last fix (Issue #6662) ........ ................ r81511 | benjamin.peterson | 2010-05-25 04:27:55 +0200 (Tue, 25 May 2010) | 8 lines Blocked revisions 81509 via svnmerge ........ r81509 | benjamin.peterson | 2010-05-24 21:23:32 -0500 (Mon, 24 May 2010) | 1 line correct default docs ........ ................ r81513 | tarek.ziade | 2010-05-25 11:44:36 +0200 (Tue, 25 May 2010) | 1 line Made sysconfig a script that displays useful information - #8770 ................ r81514 | tarek.ziade | 2010-05-25 11:47:06 +0200 (Tue, 25 May 2010) | 1 line added the list of public APIs in sysconfig ................ r81519 | r.david.murray | 2010-05-25 17:26:21 +0200 (Tue, 25 May 2010) | 13 lines Blocked revisions 81518 via svnmerge ........ r81518 | r.david.murray | 2010-05-25 11:20:46 -0400 (Tue, 25 May 2010) | 8 lines Issue 8143: sync unquote in urlparse with urllib; add comment about doing so. unquote is duplicated in the two files to avoid a circular reference. (This is fixed in Python3.) Updates keep getting made to the public unquote without fixing the urlparse one, however, so this fix syncs the two and adds a comment to both to make sure changes are applied to both. ........ ................ r81522 | r.david.murray | 2010-05-25 17:36:46 +0200 (Tue, 25 May 2010) | 9 lines Recorded merge of revisions 81521 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81521 | r.david.murray | 2010-05-25 11:32:06 -0400 (Tue, 25 May 2010) | 2 lines Issue 8818: urlparse/urlsplit keyword is 'scheme', not 'default_scheme'. ........ ................ r81526 | mark.dickinson | 2010-05-25 21:06:24 +0200 (Tue, 25 May 2010) | 10 lines Merged revisions 81525 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81525 | mark.dickinson | 2010-05-25 20:01:08 +0100 (Tue, 25 May 2010) | 3 lines Issue #8816: Extra tests for some built-in functions. These tests are ports of IronPython tests. Thanks Gregory Nofi. ........ ................ r81528 | mark.dickinson | 2010-05-25 21:46:20 +0200 (Tue, 25 May 2010) | 9 lines Merged revisions 81527 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81527 | mark.dickinson | 2010-05-25 20:44:49 +0100 (Tue, 25 May 2010) | 1 line Fix a NameError in test_enumerate. ........ ................ r81532 | martin.v.loewis | 2010-05-25 22:07:11 +0200 (Tue, 25 May 2010) | 9 lines Merged revisions 81531 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81531 | martin.v.loewis | 2010-05-25 22:06:02 +0200 (Di, 25 Mai 2010) | 2 lines Add Alexander Belopolsky. ........ ................ r81533 | victor.stinner | 2010-05-25 23:12:34 +0200 (Tue, 25 May 2010) | 3 lines Issue #4769: Fix main() function of the base64 module, use sys.stdin.buffer and sys.stdout.buffer (instead of sys.stdin and sys.stdout) to use the bytes API ................ r81535 | victor.stinner | 2010-05-26 00:17:22 +0200 (Wed, 26 May 2010) | 2 lines Fix the new TestMain.test_decode() of test_base64 for Windows ................ r81538 | victor.stinner | 2010-05-26 00:35:40 +0200 (Wed, 26 May 2010) | 11 lines Blocked revisions 81537 via svnmerge ........ r81537 | victor.stinner | 2010-05-26 00:30:32 +0200 (mer., 26 mai 2010) | 3 lines Issue #3798: Write sys.exit() message to sys.stderr to use stderr encoding and error handler, instead of writing to the C stderr file in utf-8 ........ py3k was already fixed by r81252. ................ r81541 | mark.dickinson | 2010-05-26 18:02:59 +0200 (Wed, 26 May 2010) | 4 lines Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near for use by the datetime module; also refactor long_round to use this function. ................ r81545 | victor.stinner | 2010-05-26 19:33:03 +0200 (Wed, 26 May 2010) | 9 lines Merged revisions 81543 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81543 | victor.stinner | 2010-05-26 19:25:28 +0200 (mer., 26 mai 2010) | 2 lines Issue #7449: Skip test_socketserver if threading support is disabled ........ ................ r81547 | brian.curtin | 2010-05-26 19:43:50 +0200 (Wed, 26 May 2010) | 6 lines Fix #2810 - handle the case where some registry calls return ERROR_MORE_DATA, requiring another call to get the remaining data. Patch by Daniel Stutzbach ................ r81548 | giampaolo.rodola | 2010-05-26 20:06:04 +0200 (Wed, 26 May 2010) | 1 line Fix issue #8806: add SSL contexts support to ftplib ................ r81550 | giampaolo.rodola | 2010-05-26 20:21:26 +0200 (Wed, 26 May 2010) | 1 line fix wrong assertIs context ................ r81553 | mark.dickinson | 2010-05-26 21:14:01 +0200 (Wed, 26 May 2010) | 9 lines Merged revisions 81551 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81551 | mark.dickinson | 2010-05-26 20:06:33 +0100 (Wed, 26 May 2010) | 1 line Issue #8825: additional testcases for int(string, 0) and long(string, 0). ........ ................ r81556 | alexander.belopolsky | 2010-05-26 22:00:12 +0200 (Wed, 26 May 2010) | 10 lines Merged revisions 81555 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81555 | alexander.belopolsky | 2010-05-26 15:43:16 -0400 (Wed, 26 May 2010) | 3 lines Issue #7879: Do not test negative timestamps on any Windows platform including Windows CE. ........ ................ r81557 | mark.dickinson | 2010-05-26 22:07:58 +0200 (Wed, 26 May 2010) | 4 lines Issue #2844: Make int('42', n) consistently raise ValueError for invalid integers n (including n = -909). ................ r81560 | alexander.belopolsky | 2010-05-26 22:48:30 +0200 (Wed, 26 May 2010) | 10 lines Merged revisions 81559 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81559 | alexander.belopolsky | 2010-05-26 16:45:37 -0400 (Wed, 26 May 2010) | 3 lines Issue #7879: Skip negative timestamps test on any Windows platform using unittest.skipIf decorator. ........ ................ r81564 | mark.dickinson | 2010-05-27 21:45:50 +0200 (Thu, 27 May 2010) | 9 lines Merged revisions 81512 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81512 | brett.cannon | 2010-05-25 03:53:04 +0100 (Tue, 25 May 2010) | 1 line Make the contributor list alphabetical again. ........ ................ r81565 | mark.dickinson | 2010-05-27 21:47:53 +0200 (Thu, 27 May 2010) | 1 line Stefan Krah was missing from Misc/ACKS in the py3k branch. ................ r81568 | alexander.belopolsky | 2010-05-27 23:42:58 +0200 (Thu, 27 May 2010) | 10 lines Merged revisions 81566 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81566 | alexander.belopolsky | 2010-05-27 16:55:27 -0400 (Thu, 27 May 2010) | 3 lines Issue #7150: Raise OverflowError if the result of adding or subtracting timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range. ........ ................ r81572 | benjamin.peterson | 2010-05-28 00:32:22 +0200 (Fri, 28 May 2010) | 1 line correct default value in signature ................ r81575 | ezio.melotti | 2010-05-28 00:38:16 +0200 (Fri, 28 May 2010) | 9 lines Merged revisions 81318 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81318 | ezio.melotti | 2010-05-19 03:32:52 +0300 (Wed, 19 May 2010) | 1 line Fix typo in argparse doc. ........ ................ r81581 | benjamin.peterson | 2010-05-28 05:23:57 +0200 (Fri, 28 May 2010) | 12 lines Blocked revisions 81578-81579 via svnmerge ........ r81578 | benjamin.peterson | 2010-05-27 21:12:36 -0500 (Thu, 27 May 2010) | 1 line remove non-ascii coding per PEP 8 ........ r81579 | benjamin.peterson | 2010-05-27 22:10:31 -0500 (Thu, 27 May 2010) | 1 line 2to3 doesn't fix test_support #6583 ........ ................ r81583 | martin.v.loewis | 2010-05-28 17:44:20 +0200 (Fri, 28 May 2010) | 9 lines Merged revisions 81582 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81582 | martin.v.loewis | 2010-05-28 17:28:47 +0200 (Fr, 28 Mai 2010) | 2 lines Issue #1759169: Drop _XOPEN_SOURCE on Solaris. ........ ................ r81585 | brian.curtin | 2010-05-28 18:08:40 +0200 (Fri, 28 May 2010) | 10 lines Merged revisions 81584 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81584 | brian.curtin | 2010-05-28 10:49:21 -0500 (Fri, 28 May 2010) | 3 lines Fix #8405 for slow buildbots. Remove the sleep on startup and move the pipe communication into a loop to retry in case a buildbot gets even slower. ........ ................ r81588 | victor.stinner | 2010-05-28 23:55:10 +0200 (Fri, 28 May 2010) | 3 lines Issue #8837: Remove "O?" format of PyArg_Parse*() functions. The format is no used anymore and it was never documented. ................ r81590 | victor.stinner | 2010-05-29 02:13:06 +0200 (Sat, 29 May 2010) | 2 lines Remove dead code ................ r81595 | antoine.pitrou | 2010-05-29 14:08:25 +0200 (Sat, 29 May 2010) | 9 lines Merged revisions 81594 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81594 | antoine.pitrou | 2010-05-29 14:06:13 +0200 (sam., 29 mai 2010) | 3 lines Issue #8840: Make documentation for truncate() clearer ........ ................ r81600 | stefan.krah | 2010-05-29 14:59:18 +0200 (Sat, 29 May 2010) | 9 lines Merged revisions 81598 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81598 | stefan.krah | 2010-05-29 14:54:35 +0200 (Sat, 29 May 2010) | 1 line Fix typo ........ ................ r81604 | mark.dickinson | 2010-05-29 23:05:27 +0200 (Sat, 29 May 2010) | 9 lines Merged revisions 81602 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81602 | mark.dickinson | 2010-05-29 22:00:52 +0100 (Sat, 29 May 2010) | 1 line Untabify Modules/config.c.in. ........ ................ r81607 | mark.dickinson | 2010-05-30 14:12:56 +0200 (Sun, 30 May 2010) | 10 lines Blocked revisions 81606 via svnmerge ........ r81606 | mark.dickinson | 2010-05-30 13:12:25 +0100 (Sun, 30 May 2010) | 4 lines Issue #5211: Complete removal of implicit coercions for the complex type. Coercion for arithmetic operations was already removed in r78280, but that commit didn't remove coercion for rich comparisons. ........ ................ r81609 | mark.dickinson | 2010-05-30 14:17:39 +0200 (Sun, 30 May 2010) | 8 lines Blocked revisions 81608 via svnmerge ........ r81608 | mark.dickinson | 2010-05-30 13:17:11 +0100 (Sun, 30 May 2010) | 1 line Remove declaration for unused variable. ........ ................ r81611 | mark.dickinson | 2010-05-30 15:18:47 +0200 (Sun, 30 May 2010) | 10 lines Recorded merge of revisions 81610 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81610 | mark.dickinson | 2010-05-30 14:18:10 +0100 (Sun, 30 May 2010) | 3 lines Issue #8748: Fix incorrect results from comparisons between an integer and a complex instance. Based on a patch by Meador Inge. ........ ................ r81612 | benjamin.peterson | 2010-05-30 16:49:32 +0200 (Sun, 30 May 2010) | 1 line use atomic structures in non-thread version ................ r81613 | ronald.oussoren | 2010-05-30 17:46:48 +0200 (Sun, 30 May 2010) | 4 lines Remove conditional import of 'ic', that module was removed in the transition from python 2.x to python 3.x. ................ r81623 | antoine.pitrou | 2010-05-31 19:04:40 +0200 (Mon, 31 May 2010) | 9 lines Merged revisions 81621 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81621 | antoine.pitrou | 2010-05-31 19:01:01 +0200 (lun., 31 mai 2010) | 4 lines Improve documentation for getaddrinfo() (part of #8857) ........ ................ r81625 | alexander.belopolsky | 2010-05-31 19:33:47 +0200 (Mon, 31 May 2010) | 3 lines Issue #1289118: datetime.timedelta objects can now be multiplied by float and divided by float and int objects. ................ r81628 | r.david.murray | 2010-06-01 01:23:50 +0200 (Tue, 01 Jun 2010) | 9 lines Merged revisions 81587 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81587 | r.david.murray | 2010-05-28 14:17:20 -0400 (Fri, 28 May 2010) | 2 lines Make the ctl-C shutdown of serve.py prettier. ........ ................ r81630 | r.david.murray | 2010-06-01 03:11:18 +0200 (Tue, 01 Jun 2010) | 9 lines Merged revisions 81586 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81586 | r.david.murray | 2010-05-28 14:08:11 -0400 (Fri, 28 May 2010) | 2 lines Make reference to Generic Attribute Management a hyperlink. ........ ................ r81632 | r.david.murray | 2010-06-01 03:32:12 +0200 (Tue, 01 Jun 2010) | 4 lines #8845: expose sqlite3 inTransaction as RO in_transaction Connection attribute. Patch by R. David Murray, unit tests by Shashwat Anand. ................ r81638 | senthil.kumaran | 2010-06-01 14:53:48 +0200 (Tue, 01 Jun 2010) | 9 lines Merged revisions 81636 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81636 | senthil.kumaran | 2010-06-01 18:10:07 +0530 (Tue, 01 Jun 2010) | 3 lines Fix Issue8797 - urllib2 basic authentication fix for wrong passwords. It fails after 5 retries. ........ ................ r81642 | brian.curtin | 2010-06-01 15:49:19 +0200 (Tue, 01 Jun 2010) | 10 lines Merged revisions 81640 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81640 | brian.curtin | 2010-06-01 08:29:13 -0500 (Tue, 01 Jun 2010) | 3 lines Fix #8618. Ask the Windows mixer API if there are any playback devices configured before attempting to test PlaySound. ........ ................ r81647 | senthil.kumaran | 2010-06-02 04:29:00 +0200 (Wed, 02 Jun 2010) | 9 lines Merged revisions 81645 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81645 | senthil.kumaran | 2010-06-02 07:49:15 +0530 (Wed, 02 Jun 2010) | 3 lines Fix issue8788 - description of doseq parameter in urllib.urlencode ........ ................ r81650 | ronald.oussoren | 2010-06-02 05:50:56 +0200 (Wed, 02 Jun 2010) | 11 lines Merged revisions 81649 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81649 | ronald.oussoren | 2010-06-02 05:47:14 +0200 (Wed, 02 Jun 2010) | 5 lines Fix for issue8868: without this patch 'MacOS.WMAvailable()' will return False on MacOSX 10.5 or earlier and scripts won't be able to access GUI functionality. ........ ................ r81654 | antoine.pitrou | 2010-06-02 19:10:49 +0200 (Wed, 02 Jun 2010) | 10 lines Merged revisions 81652 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81652 | antoine.pitrou | 2010-06-02 19:08:47 +0200 (mer., 02 juin 2010) | 4 lines Issue #8873: add a documentation note about possible performance issues with the default of unbuffered IO in subprocess.Popen. ........ ................ r81656 | benjamin.peterson | 2010-06-02 20:10:09 +0200 (Wed, 02 Jun 2010) | 1 line remove description of LOAD_LOCALS #8874 ................ r81660 | r.david.murray | 2010-06-03 03:58:28 +0200 (Thu, 03 Jun 2010) | 25 lines Fix Charset.body_encode to encode to output_charset before calling base64mime. This means that what gets encoded in base64 is the encoded version of the unicode payload. This bug was revealed by a forward port of the tests from Issue 1368247, but the fix was completely different. Note that the merge is only of the tests, the doc changes were inappropriate since email5 expects unicode, not bytes. I'm also not convinced that quopri works correctly in email5, but that's a different issue. Merged revisions 81658 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81658 | r.david.murray | 2010-06-02 18:03:15 -0400 (Wed, 02 Jun 2010) | 9 lines #1368247: make set_charset/MIMEText automatically encode unicode _payload. Fixes (mysterious, to the end user) UnicodeErrors when using utf-8 as the charset and unicode as the _text argument. Also makes the way in which unicode gets encoded to quoted printable for other charsets more sane (it only worked by accident previously). The _payload now is encoded to the charset.output_charset if it is unicode. ........ ................ r81665 | lars.gustaebel | 2010-06-03 12:11:52 +0200 (Thu, 03 Jun 2010) | 11 lines Merged revisions 81663 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81663 | lars.gustaebel | 2010-06-03 11:56:22 +0200 (Thu, 03 Jun 2010) | 4 lines Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. The associated testcase did not expose this bug because it was broken too. ........ ................ r81670 | lars.gustaebel | 2010-06-03 14:45:16 +0200 (Thu, 03 Jun 2010) | 14 lines Merged revisions 81667 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81667 | lars.gustaebel | 2010-06-03 14:34:14 +0200 (Thu, 03 Jun 2010) | 8 lines Issue #8741: Fixed the TarFile.makelink() method that is responsible for extracting symbolic and hard link entries as regular files as a work-around on platforms that do not support filesystem links. This stopped working reliably after a change in r74571. I also added a few tests for this functionality. ........ ................ r81673 | ronald.oussoren | 2010-06-03 16:42:25 +0200 (Thu, 03 Jun 2010) | 16 lines Merged revisions 81662 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81662 | ronald.oussoren | 2010-06-03 11:47:21 +0200 (Thu, 03 Jun 2010) | 9 lines Fix for issue #7724: ensure that distutils and python's own setup.py honor the MacOSX SDK when one is specified. This is needed to be able to build using the 10.4u SDK while running on OSX 10.6. This is a fixed version of the patch in r80963, I've tested this patch on OSX and Linux. ........ ................ r81682 | sean.reifschneider | 2010-06-04 03:51:38 +0200 (Fri, 04 Jun 2010) | 2 lines Issue8810: Clearing up docstring for tzinfo.utcoffset. ................ r81685 | r.david.murray | 2010-06-04 18:11:08 +0200 (Fri, 04 Jun 2010) | 4 lines #4768: store base64 encoded email body parts as text, not binary. Patch and tests by Forest Bond. ................ r81689 | senthil.kumaran | 2010-06-04 18:38:00 +0200 (Fri, 04 Jun 2010) | 9 lines Merged revisions 81687 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81687 | senthil.kumaran | 2010-06-04 22:02:14 +0530 (Fri, 04 Jun 2010) | 3 lines Fix issue6312 - close the resp object for HEAD response. ........ ................ r81694 | martin.v.loewis | 2010-06-04 19:20:56 +0200 (Fri, 04 Jun 2010) | 10 lines Merged revisions 81692 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81692 | martin.v.loewis | 2010-06-04 19:18:42 +0200 (Fr, 04 Jun 2010) | 3 lines Issue #8864: Define _XOPEN_SOURCE on Solaris for the multiprocessing module. ........ ................ r81695 | senthil.kumaran | 2010-06-04 19:27:11 +0200 (Fri, 04 Jun 2010) | 9 lines Merged revisions 81691 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81691 | senthil.kumaran | 2010-06-04 22:47:09 +0530 (Fri, 04 Jun 2010) | 3 lines test verifying the resp object is closed for HEAD response. ........ ................ r81698 | martin.v.loewis | 2010-06-04 20:14:42 +0200 (Fri, 04 Jun 2010) | 9 lines Merged revisions 81697 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81697 | martin.v.loewis | 2010-06-04 20:04:42 +0200 (Fr, 04 Jun 2010) | 2 lines Issue #5464: Implement plural forms in msgfmt.py. ........ ................ r81699 | martin.v.loewis | 2010-06-04 20:40:55 +0200 (Fri, 04 Jun 2010) | 2 lines Port to Python 3. ................ r81703 | martin.v.loewis | 2010-06-04 21:50:26 +0200 (Fri, 04 Jun 2010) | 10 lines Merged revisions 81701 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81701 | martin.v.loewis | 2010-06-04 21:39:07 +0200 (Fr, 04 Jun 2010) | 2 lines Issue #6470: Drop UNC prefix in FixTk.py Patch by Christop Gohlke and Amaury Forgeot d'Arc. ........ ................ r81708 | benjamin.peterson | 2010-06-05 02:45:37 +0200 (Sat, 05 Jun 2010) | 13 lines Merged revisions 81706-81707 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81706 | benjamin.peterson | 2010-06-04 19:32:50 -0500 (Fri, 04 Jun 2010) | 1 line properly lookup the __format__ special method ........ r81707 | benjamin.peterson | 2010-06-04 19:38:22 -0500 (Fri, 04 Jun 2010) | 1 line remove PyType_Ready call; float should be initialized in interpreter startup ........ ................ r81711 | benjamin.peterson | 2010-06-05 03:03:24 +0200 (Sat, 05 Jun 2010) | 13 lines Merged revisions 81709-81710 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81709 | benjamin.peterson | 2010-06-04 19:56:46 -0500 (Fri, 04 Jun 2010) | 1 line implement object.__format__ with PyObject_Format ........ r81710 | benjamin.peterson | 2010-06-04 20:00:10 -0500 (Fri, 04 Jun 2010) | 1 line fix ref counting ........ ................ r81713 | benjamin.peterson | 2010-06-05 04:11:45 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81712 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81712 | benjamin.peterson | 2010-06-04 21:07:01 -0500 (Fri, 04 Jun 2010) | 1 line _PyObject_LookupSpecial returns a new reference ........ ................ r81725 | michael.foord | 2010-06-05 12:45:41 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81724 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81724 | michael.foord | 2010-06-05 11:39:42 +0100 (Sat, 05 Jun 2010) | 1 line unittest TestLoader test discovery filename matching done in a method. This makes it easier to override the matching strategy in subclasses. No behaviour change in actual implementation. ........ ................ r81730 | michael.foord | 2010-06-05 13:27:52 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81728 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81728 | michael.foord | 2010-06-05 12:23:51 +0100 (Sat, 05 Jun 2010) | 1 line Issue 8351. Suppress large diffs in unittest.TestCase.assertSequenceEqual. ........ ................ r81731 | michael.foord | 2010-06-05 13:30:23 +0200 (Sat, 05 Jun 2010) | 1 line Test fix to use floor division. Correction from merge in previous commit. ................ r81737 | mark.dickinson | 2010-06-05 13:53:11 +0200 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81736 via svnmerge ........ r81736 | mark.dickinson | 2010-06-05 12:52:24 +0100 (Sat, 05 Jun 2010) | 1 line Issue #8627: remove out-of-date warning about overriding __cmp__ ........ ................ r81742 | michael.foord | 2010-06-05 14:17:02 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81739 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81739 | michael.foord | 2010-06-05 13:10:52 +0100 (Sat, 05 Jun 2010) | 1 line Removed the new max_diff argument to assertSequenceEqual. All unittest.TestCase assert methods that use difflib to produce failure messages now truncate overly long messages. New class attribute unittest.TestCase.maxDiff to configure this if necessary. Issue 8351. ........ ................ r81743 | mark.dickinson | 2010-06-05 14:38:00 +0200 (Sat, 05 Jun 2010) | 10 lines Blocked revisions 81740 via svnmerge ........ r81740 | mark.dickinson | 2010-06-05 13:14:43 +0100 (Sat, 05 Jun 2010) | 5 lines Issue #8627: Fix "XXX undetected error" from unchecked PyErr_WarnPy3k return. This is just a quick fix: if the warning is turned into an exception, the exception simply gets ignored. ........ ................ r81746 | mark.dickinson | 2010-06-05 14:52:23 +0200 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81744 via svnmerge ........ r81744 | mark.dickinson | 2010-06-05 13:51:21 +0100 (Sat, 05 Jun 2010) | 1 line Fix comment typo. ........ ................ r81748 | michael.foord | 2010-06-05 15:14:43 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81747 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81747 | michael.foord | 2010-06-05 13:58:39 +0100 (Sat, 05 Jun 2010) | 1 line unittest.TestCase.assertDictEqual and assertMultilineEqual provide better default failure messages in the event of long diffs. ........ ................ r81751 | mark.dickinson | 2010-06-05 15:27:17 +0200 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81749 via svnmerge ........ r81749 | mark.dickinson | 2010-06-05 14:18:33 +0100 (Sat, 05 Jun 2010) | 2 lines Fix test_py3kwarn not to test for __cmp__-related DeprecationWarning. ........ ................ r81754 | michael.foord | 2010-06-05 15:49:56 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81752 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81752 | michael.foord | 2010-06-05 14:38:16 +0100 (Sat, 05 Jun 2010) | 1 line unittest.TestCase assertion methods inform you when they have omitted an over long diff on failure. Issue 8351. ........ ................ r81755 | michael.foord | 2010-06-05 15:57:23 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81753 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81753 | michael.foord | 2010-06-05 14:48:27 +0100 (Sat, 05 Jun 2010) | 1 line Fix unittest tests after previous commit. ........ ................ r81757 | alexander.belopolsky | 2010-06-05 17:04:51 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81756 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81756 | alexander.belopolsky | 2010-06-05 10:54:26 -0400 (Sat, 05 Jun 2010) | 1 line Issue #8899: time.struct_time now has class and atribute docstrings. ........ ................ r81762 | michael.foord | 2010-06-05 21:58:25 +0200 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81761 via svnmerge ........ r81761 | michael.foord | 2010-06-05 20:51:38 +0100 (Sat, 05 Jun 2010) | 1 line Updated NEWS file. ........ ................ r81765 | michael.foord | 2010-06-05 23:01:08 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81763 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81763 | michael.foord | 2010-06-05 21:33:43 +0100 (Sat, 05 Jun 2010) | 1 line Tests for unittest.TestCase.maxDiff. ........ ................ r81766 | michael.foord | 2010-06-05 23:12:23 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81764 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81764 | michael.foord | 2010-06-05 21:59:00 +0100 (Sat, 05 Jun 2010) | 1 line Tests for issue 8302, skipped test in a setUpClass or a setUpModule are reported as skips rather than errors. ........ ................ r81768 | michael.foord | 2010-06-05 23:59:55 +0200 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81767 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81767 | michael.foord | 2010-06-05 22:57:03 +0100 (Sat, 05 Jun 2010) | 1 line Documentation updates for issues 8302 and 8351 (truncating excessive diffs in unittest failure messages and reporting SkipTest exceptions in setUpClass and setUpModule as skips rather than errors). ........ ................ r81771 | michael.foord | 2010-06-06 01:59:34 +0200 (Sun, 06 Jun 2010) | 9 lines Merged revisions 81770 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81770 | michael.foord | 2010-06-06 00:58:40 +0100 (Sun, 06 Jun 2010) | 1 line Code formatting change. ........ ................ r81778 | benjamin.peterson | 2010-06-06 04:14:27 +0200 (Sun, 06 Jun 2010) | 16 lines Blocked revisions 81772-81773,81777 via svnmerge ........ r81772 | benjamin.peterson | 2010-06-05 19:22:09 -0500 (Sat, 05 Jun 2010) | 1 line bump version to 2.7 rc1 ........ r81773 | benjamin.peterson | 2010-06-05 19:49:27 -0500 (Sat, 05 Jun 2010) | 1 line update pydoc-topics ........ r81777 | benjamin.peterson | 2010-06-05 21:09:33 -0500 (Sat, 05 Jun 2010) | 1 line careening towards 2.7rc2 we go ........ ................ r81779 | benjamin.peterson | 2010-06-06 04:32:09 +0200 (Sun, 06 Jun 2010) | 13 lines Merged revisions 81774-81775 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81774 | benjamin.peterson | 2010-06-05 19:50:58 -0500 (Sat, 05 Jun 2010) | 1 line remove extra space ........ r81775 | benjamin.peterson | 2010-06-05 19:54:29 -0500 (Sat, 05 Jun 2010) | 1 line fix sphinx warning with an extra space ........ ................ r81780 | benjamin.peterson | 2010-06-06 04:40:38 +0200 (Sun, 06 Jun 2010) | 1 line fix typo ................ r81781 | benjamin.peterson | 2010-06-06 04:41:24 +0200 (Sun, 06 Jun 2010) | 1 line reST indentation nit ................ r81782 | benjamin.peterson | 2010-06-06 04:44:41 +0200 (Sun, 06 Jun 2010) | 1 line bltn-file-objects don't exist in python3 ................ r81790 | tarek.ziade | 2010-06-06 22:18:42 +0200 (Sun, 06 Jun 2010) | 9 lines Merged revisions 81788 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81788 | tarek.ziade | 2010-06-06 22:05:20 +0200 (Sun, 06 Jun 2010) | 1 line Fixed #8909: now the doc details the size of the bitmap used in distutils' bdist_wininst ........ ................ r81792 | victor.stinner | 2010-06-06 22:27:51 +0200 (Sun, 06 Jun 2010) | 2 lines Simplify getbuffer(): convertbuffer() fails anyway if bf_getbuffer is NULL ................ r81794 | victor.stinner | 2010-06-06 22:38:02 +0200 (Sun, 06 Jun 2010) | 4 lines convertsimple(): call PyErr_NoMemory() on PyMem_NEW() failure Raise a more revelant error (MemoryError instead of TypeError) ................ Added: python/branches/py3k-cdecimal/Doc/howto/descriptor.rst - copied unchanged from r81794, /python/branches/py3k/Doc/howto/descriptor.rst python/branches/py3k-cdecimal/Lib/distutils/tests/test_log.py - copied unchanged from r81794, /python/branches/py3k/Lib/distutils/tests/test_log.py python/branches/py3k-cdecimal/Lib/test/test_numeric_tower.py - copied unchanged from r81794, /python/branches/py3k/Lib/test/test_numeric_tower.py Modified: python/branches/py3k-cdecimal/ (props changed) python/branches/py3k-cdecimal/Doc/c-api/init.rst python/branches/py3k-cdecimal/Doc/c-api/sys.rst python/branches/py3k-cdecimal/Doc/distutils/builtdist.rst python/branches/py3k-cdecimal/Doc/extending/newtypes.rst python/branches/py3k-cdecimal/Doc/howto/index.rst python/branches/py3k-cdecimal/Doc/library/argparse.rst python/branches/py3k-cdecimal/Doc/library/datetime.rst python/branches/py3k-cdecimal/Doc/library/decimal.rst python/branches/py3k-cdecimal/Doc/library/dis.rst python/branches/py3k-cdecimal/Doc/library/fcntl.rst python/branches/py3k-cdecimal/Doc/library/ftplib.rst python/branches/py3k-cdecimal/Doc/library/functions.rst python/branches/py3k-cdecimal/Doc/library/getopt.rst python/branches/py3k-cdecimal/Doc/library/hashlib.rst python/branches/py3k-cdecimal/Doc/library/io.rst python/branches/py3k-cdecimal/Doc/library/json.rst python/branches/py3k-cdecimal/Doc/library/multiprocessing.rst python/branches/py3k-cdecimal/Doc/library/optparse.rst python/branches/py3k-cdecimal/Doc/library/os.rst python/branches/py3k-cdecimal/Doc/library/socket.rst python/branches/py3k-cdecimal/Doc/library/sqlite3.rst python/branches/py3k-cdecimal/Doc/library/ssl.rst python/branches/py3k-cdecimal/Doc/library/stdtypes.rst python/branches/py3k-cdecimal/Doc/library/subprocess.rst python/branches/py3k-cdecimal/Doc/library/symtable.rst python/branches/py3k-cdecimal/Doc/library/sys.rst python/branches/py3k-cdecimal/Doc/library/sysconfig.rst python/branches/py3k-cdecimal/Doc/library/syslog.rst python/branches/py3k-cdecimal/Doc/library/telnetlib.rst python/branches/py3k-cdecimal/Doc/library/tempfile.rst python/branches/py3k-cdecimal/Doc/library/time.rst python/branches/py3k-cdecimal/Doc/library/unittest.rst python/branches/py3k-cdecimal/Doc/library/urllib.parse.rst python/branches/py3k-cdecimal/Doc/library/urllib.request.rst python/branches/py3k-cdecimal/Doc/library/winreg.rst python/branches/py3k-cdecimal/Doc/reference/datamodel.rst python/branches/py3k-cdecimal/Doc/tools/sphinxext/pyspecific.py python/branches/py3k-cdecimal/Doc/tutorial/datastructures.rst python/branches/py3k-cdecimal/Doc/whatsnew/3.2.rst python/branches/py3k-cdecimal/Include/longobject.h python/branches/py3k-cdecimal/Include/pyport.h python/branches/py3k-cdecimal/Include/sysmodule.h python/branches/py3k-cdecimal/Lib/_abcoll.py python/branches/py3k-cdecimal/Lib/argparse.py python/branches/py3k-cdecimal/Lib/base64.py python/branches/py3k-cdecimal/Lib/codecs.py python/branches/py3k-cdecimal/Lib/decimal.py python/branches/py3k-cdecimal/Lib/distutils/log.py python/branches/py3k-cdecimal/Lib/distutils/unixccompiler.py python/branches/py3k-cdecimal/Lib/email/charset.py python/branches/py3k-cdecimal/Lib/email/encoders.py python/branches/py3k-cdecimal/Lib/email/test/test_email.py python/branches/py3k-cdecimal/Lib/encodings/utf_16.py python/branches/py3k-cdecimal/Lib/encodings/utf_32.py python/branches/py3k-cdecimal/Lib/fractions.py python/branches/py3k-cdecimal/Lib/ftplib.py python/branches/py3k-cdecimal/Lib/functools.py python/branches/py3k-cdecimal/Lib/html/parser.py python/branches/py3k-cdecimal/Lib/http/client.py python/branches/py3k-cdecimal/Lib/lib2to3/refactor.py python/branches/py3k-cdecimal/Lib/linecache.py python/branches/py3k-cdecimal/Lib/pipes.py python/branches/py3k-cdecimal/Lib/sqlite3/test/dbapi.py python/branches/py3k-cdecimal/Lib/ssl.py python/branches/py3k-cdecimal/Lib/subprocess.py python/branches/py3k-cdecimal/Lib/sysconfig.py python/branches/py3k-cdecimal/Lib/tabnanny.py python/branches/py3k-cdecimal/Lib/tarfile.py python/branches/py3k-cdecimal/Lib/test/regrtest.py python/branches/py3k-cdecimal/Lib/test/test_argparse.py python/branches/py3k-cdecimal/Lib/test/test_base64.py python/branches/py3k-cdecimal/Lib/test/test_builtin.py python/branches/py3k-cdecimal/Lib/test/test_codecs.py python/branches/py3k-cdecimal/Lib/test/test_collections.py python/branches/py3k-cdecimal/Lib/test/test_complex.py python/branches/py3k-cdecimal/Lib/test/test_datetime.py python/branches/py3k-cdecimal/Lib/test/test_decimal.py python/branches/py3k-cdecimal/Lib/test/test_descr.py python/branches/py3k-cdecimal/Lib/test/test_enumerate.py python/branches/py3k-cdecimal/Lib/test/test_float.py python/branches/py3k-cdecimal/Lib/test/test_ftplib.py python/branches/py3k-cdecimal/Lib/test/test_gdb.py python/branches/py3k-cdecimal/Lib/test/test_htmlparser.py python/branches/py3k-cdecimal/Lib/test/test_httplib.py python/branches/py3k-cdecimal/Lib/test/test_linecache.py python/branches/py3k-cdecimal/Lib/test/test_long.py python/branches/py3k-cdecimal/Lib/test/test_os.py python/branches/py3k-cdecimal/Lib/test/test_pipes.py python/branches/py3k-cdecimal/Lib/test/test_socketserver.py python/branches/py3k-cdecimal/Lib/test/test_ssl.py python/branches/py3k-cdecimal/Lib/test/test_subprocess.py python/branches/py3k-cdecimal/Lib/test/test_sys.py python/branches/py3k-cdecimal/Lib/test/test_sysconfig.py python/branches/py3k-cdecimal/Lib/test/test_tarfile.py python/branches/py3k-cdecimal/Lib/test/test_tcl.py python/branches/py3k-cdecimal/Lib/test/test_urllib2.py python/branches/py3k-cdecimal/Lib/test/test_warnings.py python/branches/py3k-cdecimal/Lib/test/test_winreg.py python/branches/py3k-cdecimal/Lib/test/test_winsound.py python/branches/py3k-cdecimal/Lib/test/testtar.tar python/branches/py3k-cdecimal/Lib/tkinter/_fix.py python/branches/py3k-cdecimal/Lib/unittest/case.py python/branches/py3k-cdecimal/Lib/unittest/loader.py python/branches/py3k-cdecimal/Lib/unittest/suite.py python/branches/py3k-cdecimal/Lib/unittest/test/test_case.py python/branches/py3k-cdecimal/Lib/unittest/test/test_setups.py python/branches/py3k-cdecimal/Lib/unittest/util.py python/branches/py3k-cdecimal/Lib/urllib/request.py python/branches/py3k-cdecimal/Lib/webbrowser.py python/branches/py3k-cdecimal/Mac/Tools/pythonw.c python/branches/py3k-cdecimal/Misc/ACKS python/branches/py3k-cdecimal/Misc/NEWS python/branches/py3k-cdecimal/Misc/developers.txt python/branches/py3k-cdecimal/Modules/_multiprocessing/multiprocessing.h python/branches/py3k-cdecimal/Modules/_sqlite/connection.c python/branches/py3k-cdecimal/Modules/_ssl.c python/branches/py3k-cdecimal/Modules/config.c.in python/branches/py3k-cdecimal/Modules/datetimemodule.c python/branches/py3k-cdecimal/Modules/main.c python/branches/py3k-cdecimal/Modules/timemodule.c python/branches/py3k-cdecimal/Objects/abstract.c python/branches/py3k-cdecimal/Objects/complexobject.c python/branches/py3k-cdecimal/Objects/longobject.c python/branches/py3k-cdecimal/Objects/object.c python/branches/py3k-cdecimal/Objects/typeobject.c python/branches/py3k-cdecimal/PC/winreg.c python/branches/py3k-cdecimal/Python/_warnings.c python/branches/py3k-cdecimal/Python/ceval.c python/branches/py3k-cdecimal/Python/getargs.c python/branches/py3k-cdecimal/Python/pythonrun.c python/branches/py3k-cdecimal/Python/sysmodule.c python/branches/py3k-cdecimal/Tools/gdb/libpython.py python/branches/py3k-cdecimal/Tools/i18n/msgfmt.py python/branches/py3k-cdecimal/Tools/scripts/serve.py python/branches/py3k-cdecimal/configure python/branches/py3k-cdecimal/configure.in python/branches/py3k-cdecimal/setup.py Modified: python/branches/py3k-cdecimal/Doc/c-api/init.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/c-api/init.rst (original) +++ python/branches/py3k-cdecimal/Doc/c-api/init.rst Mon Jun 7 12:46:02 2010 @@ -22,6 +22,7 @@ module: sys triple: module; search; path single: PySys_SetArgv() + single: PySys_SetArgvEx() single: Py_Finalize() Initialize the Python interpreter. In an application embedding Python, this @@ -31,7 +32,7 @@ the table of loaded modules (``sys.modules``), and creates the fundamental modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. It also initializes the module search path (``sys.path``). It does not set ``sys.argv``; use - :cfunc:`PySys_SetArgv` for that. This is a no-op when called for a second time + :cfunc:`PySys_SetArgvEx` for that. This is a no-op when called for a second time (without calling :cfunc:`Py_Finalize` first). There is no return value; it is a fatal error if the initialization fails. @@ -337,7 +338,7 @@ ``sys.version``. -.. cfunction:: void PySys_SetArgv(int argc, wchar_t **argv) +.. cfunction:: void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) .. index:: single: main() @@ -352,14 +353,41 @@ string. If this function fails to initialize :data:`sys.argv`, a fatal condition is signalled using :cfunc:`Py_FatalError`. - This function also prepends the executed script's path to :data:`sys.path`. - If no script is executed (in the case of calling ``python -c`` or just the - interactive interpreter), the empty string is used instead. + If *updatepath* is zero, this is all the function does. If *updatepath* + is non-zero, the function also modifies :data:`sys.path` according to the + following algorithm: + + - If the name of an existing script is passed in ``argv[0]``, the absolute + path of the directory where the script is located is prepended to + :data:`sys.path`. + - Otherwise (that is, if *argc* is 0 or ``argv[0]`` doesn't point + to an existing file name), an empty string is prepended to + :data:`sys.path`, which is the same as prepending the current working + directory (``"."``). + + .. note:: + It is recommended that applications embedding the Python interpreter + for purposes other than executing a single script pass 0 as *updatepath*, + and update :data:`sys.path` themselves if desired. + See `CVE-2008-5983 `_. + + On versions before 3.1.3, you can achieve the same effect by manually + popping the first :data:`sys.path` element after having called + :cfunc:`PySys_SetArgv`, for example using:: + + PyRun_SimpleString("import sys; sys.path.pop(0)\n"); + + .. versionadded:: 3.1.3 .. XXX impl. doesn't seem consistent in allowing 0/NULL for the params; check w/ Guido. +.. cfunction:: void PySys_SetArgv(int argc, wchar_t **argv) + + This function works like :cfunc:`PySys_SetArgv` with *updatepath* set to 1. + + .. cfunction:: void Py_SetPythonHome(wchar_t *home) Set the default "home" directory, that is, the location of the standard Modified: python/branches/py3k-cdecimal/Doc/c-api/sys.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/c-api/sys.rst (original) +++ python/branches/py3k-cdecimal/Doc/c-api/sys.rst Mon Jun 7 12:46:02 2010 @@ -81,6 +81,10 @@ Append *s* to :data:`sys.warnoptions`. +.. cfunction:: void PySys_AddWarnOptionUnicode(PyObject *unicode) + + Append *unicode* to :data:`sys.warnoptions`. + .. cfunction:: void PySys_SetPath(wchar_t *path) Set :data:`sys.path` to a list object of paths found in *path* which should Modified: python/branches/py3k-cdecimal/Doc/distutils/builtdist.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/distutils/builtdist.rst (original) +++ python/branches/py3k-cdecimal/Doc/distutils/builtdist.rst Mon Jun 7 12:46:02 2010 @@ -322,7 +322,7 @@ option. By default the installer will display the cool "Python Powered" logo when it is -run, but you can also supply your own bitmap which must be a Windows +run, but you can also supply your own 152x161 bitmap which must be a Windows :file:`.bmp` file with the :option:`--bitmap` option. The installer will also display a large title on the desktop background window Modified: python/branches/py3k-cdecimal/Doc/extending/newtypes.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/extending/newtypes.rst (original) +++ python/branches/py3k-cdecimal/Doc/extending/newtypes.rst Mon Jun 7 12:46:02 2010 @@ -430,7 +430,7 @@ Noddy_members, /* tp_members */ Each member definition has a member name, type, offset, access flags and -documentation string. See the "Generic Attribute Management" section below for +documentation string. See the :ref:`Generic-Attribute-Management` section below for details. A disadvantage of this approach is that it doesn't provide a way to restrict the @@ -1078,6 +1078,8 @@ not been updated to use some of the new generic mechanism that is available. +.. _generic-attribute-management: + Generic Attribute Management ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Modified: python/branches/py3k-cdecimal/Doc/howto/index.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/howto/index.rst (original) +++ python/branches/py3k-cdecimal/Doc/howto/index.rst Mon Jun 7 12:46:02 2010 @@ -16,6 +16,7 @@ advocacy.rst cporting.rst curses.rst + descriptor.rst doanddont.rst functional.rst regex.rst Modified: python/branches/py3k-cdecimal/Doc/library/argparse.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/argparse.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/argparse.rst Mon Jun 7 12:46:02 2010 @@ -452,7 +452,7 @@ By default, :class:`ArgumentParser` objects uses ``sys.argv[0]`` to determine how to display the name of the program in help messages. This default is almost -always desirable because it will make the help messages match how the pgoram was +always desirable because it will make the help messages match how the program was invoked on the command line. For example, consider a file named ``myprogram.py`` with the following code:: @@ -672,8 +672,8 @@ >>> import argparse >>> parser = argparse.ArgumentParser(prog='PROG') - >>> parser.add_argument('-v', '--version', action='version', version='%(prog)s 2.0') - >>> parser.parse_args(['-v']) + >>> parser.add_argument('--version', action='version', version='%(prog)s 2.0') + >>> parser.parse_args(['--version']) PROG 2.0 You can also specify an arbitrary action by passing an object that implements @@ -1725,3 +1725,6 @@ * Replace strings with implicit arguments such as ``%default`` or ``%prog`` with the standard python syntax to use dictionaries to format strings, that is, ``%(default)s`` and ``%(prog)s``. + +* Replace the OptionParser constructor ``version`` argument with a call to + ``parser.add_argument('--version', action='version', version='')`` Modified: python/branches/py3k-cdecimal/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/datetime.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/datetime.rst Mon Jun 7 12:46:02 2010 @@ -220,12 +220,20 @@ | | In general, *t1* \* i == *t1* \* (i-1) + *t1* | | | is true. (1) | +--------------------------------+-----------------------------------------------+ +| ``t1 = t2 * f or t1 = f * t2`` | Delta multiplied by a float. The result is | +| | rounded to the nearest multiple of | +| | timedelta.resolution using round-half-to-even.| ++--------------------------------+-----------------------------------------------+ | ``f = t2 / t3`` | Division (3) of *t2* by *t3*. Returns a | | | :class:`float` object. | +--------------------------------+-----------------------------------------------+ +| ``t1 = t2 / f or t1 = t2 / i`` | Delta divided by a float or an int. The result| +| | is rounded to the nearest multiple of | +| | timedelta.resolution using round-half-to-even.| ++--------------------------------+-----------------------------------------------+ | ``t1 = t2 // i`` or | The floor is computed and the remainder (if | | ``t1 = t2 // t3`` | any) is thrown away. In the second case, an | -| | integer is returned (3) | +| | integer is returned. (3) | +--------------------------------+-----------------------------------------------+ | ``t1 = t2 % t3`` | The remainder is computed as a | | | :class:`timedelta` object. (3) | @@ -267,7 +275,9 @@ .. versionadded:: 3.2 Floor division and true division of a :class:`timedelta` object by another :class:`timedelta` object are now supported, as are - remainder operations and the :func:`divmod` function. + remainder operations and the :func:`divmod` function. True + division and multiplication of a :class:`timedelta` object by + a :class:`float` object are now supported. Comparisons of :class:`timedelta` objects are supported with the Modified: python/branches/py3k-cdecimal/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/decimal.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/decimal.rst Mon Jun 7 12:46:02 2010 @@ -122,7 +122,7 @@ >>> from decimal import * >>> getcontext() Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, - capitals=1, flags=[], traps=[Overflow, DivisionByZero, + capitals=1, clamp=0, flags=[], traps=[Overflow, DivisionByZero, InvalidOperation]) >>> getcontext().prec = 7 # Set a new precision @@ -244,7 +244,7 @@ >>> ExtendedContext Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, - capitals=1, flags=[], traps=[]) + capitals=1, clamp=0, flags=[], traps=[]) >>> setcontext(ExtendedContext) >>> Decimal(1) / Decimal(7) Decimal('0.142857143') @@ -269,7 +269,7 @@ Decimal('3.14159292') >>> getcontext() Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, - capitals=1, flags=[Inexact, Rounded], traps=[]) + capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[]) The *flags* entry shows that the rational approximation to :const:`Pi` was rounded (digits beyond the context precision were thrown away) and that the @@ -874,7 +874,7 @@ This context is used by the :class:`Context` constructor as a prototype for new contexts. Changing a field (such a precision) has the effect of changing the - default for new contexts creating by the :class:`Context` constructor. + default for new contexts created by the :class:`Context` constructor. This context is most useful in multi-threaded environments. Changing one of the fields before threads are started has the effect of setting system-wide @@ -891,7 +891,7 @@ :class:`Context` constructor. -.. class:: Context(prec=None, rounding=None, traps=None, flags=None, Emin=None, Emax=None, capitals=1) +.. class:: Context(prec=None, rounding=None, traps=None, flags=None, Emin=None, Emax=None, capitals=None, clamp=None) Creates a new context. If a field is not specified or is :const:`None`, the default values are copied from the :const:`DefaultContext`. If the *flags* @@ -922,6 +922,23 @@ :const:`1`, exponents are printed with a capital :const:`E`; otherwise, a lowercase :const:`e` is used: :const:`Decimal('6.02e+23')`. + The *clamp* field is either :const:`0` (the default) or :const:`1`. + If set to :const:`1`, the exponent ``e`` of a :class:`Decimal` + instance representable in this context is strictly limited to the + range ``Emin - prec + 1 <= e <= Emax - prec + 1``. If *clamp* is + :const:`0` then a weaker condition holds: the adjusted exponent of + the :class:`Decimal` instance is at most ``Emax``. When *clamp* is + :const:`1`, a large normal number will, where possible, have its + exponent reduced and a corresponding number of zeros added to its + coefficient, in order to fit the exponent constraints; this + preserves the value of the number but loses information about + significant trailing zeros. For example:: + + >>> Context(prec=6, Emax=999, clamp=1).create_decimal('1.23e999') + Decimal('1.23000E+999') + + A *clamp* value of :const:`1` allows compatibility with the + fixed-width decimal interchange formats specified in IEEE 754. The :class:`Context` class defines several general purpose methods as well as a large number of methods for doing arithmetic directly in a given context. Modified: python/branches/py3k-cdecimal/Doc/library/dis.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/dis.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/dis.rst Mon Jun 7 12:46:02 2010 @@ -383,13 +383,6 @@ the stack so that it is available for further iterations of the loop. -.. opcode:: LOAD_LOCALS () - - Pushes a reference to the locals of the current scope on the stack. This is used - in the code for a class definition: After the class body is evaluated, the - locals are passed to the class definition. - - .. opcode:: RETURN_VALUE () Returns with TOS to the caller of the function. Modified: python/branches/py3k-cdecimal/Doc/library/fcntl.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/fcntl.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/fcntl.rst Mon Jun 7 12:46:02 2010 @@ -8,8 +8,8 @@ .. index:: - pair: UNIX at Unix; file control - pair: UNIX at Unix; I/O control + pair: UNIX; file control + pair: UNIX; I/O control This module performs file control and I/O control on file descriptors. It is an interface to the :cfunc:`fcntl` and :cfunc:`ioctl` Unix routines. Modified: python/branches/py3k-cdecimal/Doc/library/ftplib.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/ftplib.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/ftplib.rst Mon Jun 7 12:46:02 2010 @@ -65,7 +65,7 @@ Support for the :keyword:`with` statement was added. -.. class:: FTP_TLS(host='', user='', passwd='', acct='', [keyfile[, certfile[, timeout]]]) +.. class:: FTP_TLS(host='', user='', passwd='', acct='', [keyfile[, certfile[, context[, timeout]]]]) A :class:`FTP` subclass which adds TLS support to FTP as described in :rfc:`4217`. @@ -74,6 +74,9 @@ explicitly ask for it by calling the :meth:`prot_p` method. *keyfile* and *certfile* are optional -- they can contain a PEM formatted private key and certificate chain file name for the SSL connection. + *context* parameter is a :class:`ssl.SSLContext` object which allows + bundling SSL configuration options, certificates and private keys into a + single (potentially long-lived) structure. .. versionadded:: 3.2 @@ -122,7 +125,7 @@ The set of all exceptions (as a tuple) that methods of :class:`FTP` instances may raise as a result of problems with the FTP connection (as opposed to programming errors made by the caller). This set includes the - four exceptions listed below as well as :exc:`socket.error` and + four exceptions listed above as well as :exc:`socket.error` and :exc:`IOError`. .. seealso:: Modified: python/branches/py3k-cdecimal/Doc/library/functions.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/functions.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/functions.rst Mon Jun 7 12:46:02 2010 @@ -1227,7 +1227,7 @@ True -.. function:: __import__(name, globals={}, locals={}, fromlist=[], level=-1) +.. function:: __import__(name, globals={}, locals={}, fromlist=[], level=0) .. index:: statement: import Modified: python/branches/py3k-cdecimal/Doc/library/getopt.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/getopt.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/getopt.rst Mon Jun 7 12:46:02 2010 @@ -5,6 +5,12 @@ :synopsis: Portable parser for command line options; support both short and long option names. +.. note:: + The :mod:`getopt` module is a parser for command line options whose API is + designed to be familiar to users of the C :cfunc:`getopt` function. Users who + are unfamiliar with the C :cfunc:`getopt` function or who would like to write + less code and get better help and error messages should consider using the + :mod:`argparse` module instead. This module helps scripts to parse the command line arguments in ``sys.argv``. It supports the same conventions as the Unix :cfunc:`getopt` function (including @@ -136,9 +142,21 @@ if __name__ == "__main__": main() +Note that an equivalent command line interface could be produced with less code +and more informative help and error messages by using the :mod:`argparse` module:: + + import argparse + + if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-o', '--output') + parser.add_argument('-v', dest='verbose', action='store_true') + args = parser.parse_args() + # ... do something with args.output ... + # ... do something with args.verbose .. .. seealso:: - Module :mod:`optparse` - More object-oriented command line option parsing. + Module :mod:`argparse` + Alternative command line option and argument parsing library. Modified: python/branches/py3k-cdecimal/Doc/library/hashlib.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/hashlib.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/hashlib.rst Mon Jun 7 12:46:02 2010 @@ -151,7 +151,7 @@ http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf The FIPS 180-2 publication on Secure Hash Algorithms. - http://www.cryptography.com/cnews/hash.html - Hash Collision FAQ with information on which algorithms have known issues and + http://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms + Wikipedia article with information on which algorithms have known issues and what that means regarding their use. Modified: python/branches/py3k-cdecimal/Doc/library/io.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/io.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/io.rst Mon Jun 7 12:46:02 2010 @@ -240,7 +240,7 @@ Flush and close this stream. This method has no effect if the file is already closed. Once the file is closed, any operation on the file - (e.g. reading or writing) will raise an :exc:`ValueError`. + (e.g. reading or writing) will raise a :exc:`ValueError`. As a convenience, it is allowed to call this method more than once; only the first call, however, will have an effect. @@ -314,10 +314,12 @@ .. method:: truncate(size=None) - Truncate the file to at most *size* bytes. *size* defaults to the current - file position, as returned by :meth:`tell`. Note that the current file - position isn't changed; if you want to change it to the new end of - file, you have to :meth:`seek()` explicitly. + Resize the stream to the given *size* in bytes (or the current position + if *size* is not specified). The current stream position isn't changed. + This resizing can extend or reduce the current file size. In case of + extension, the contents of the new file area depend on the platform + (on most systems, additional bytes are zero-filled, on Windows they're + undetermined). The new file size is returned. .. method:: writable() Modified: python/branches/py3k-cdecimal/Doc/library/json.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/json.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/json.rst Mon Jun 7 12:46:02 2010 @@ -209,7 +209,7 @@ specified. Encodings that are not ASCII based (such as UCS-2) are not allowed and should be decoded to :class:`str` first. - The other arguments have the same meaning as in :func:`dump`. + The other arguments have the same meaning as in :func:`load`. Encoders and decoders Modified: python/branches/py3k-cdecimal/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/multiprocessing.rst Mon Jun 7 12:46:02 2010 @@ -837,7 +837,7 @@ A bounded semaphore object: a clone of :class:`threading.BoundedSemaphore`. - (On Mac OS X this is indistinguishable from :class:`Semaphore` because + (On Mac OS X, this is indistinguishable from :class:`Semaphore` because ``sem_getvalue()`` is not implemented on that platform). .. class:: Condition([lock]) @@ -879,9 +879,8 @@ specifies a timeout in seconds. If *block* is ``False`` then *timeout* is ignored. -.. note:: - On OS/X ``sem_timedwait`` is unsupported, so timeout arguments for the - aforementioned :meth:`acquire` methods will be ignored on OS/X. + On Mac OS X, ``sem_timedwait`` is unsupported, so calling ``acquire()`` with + a timeout will emulate that function's behavior using a sleeping loop. .. note:: Modified: python/branches/py3k-cdecimal/Doc/library/optparse.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/optparse.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/optparse.rst Mon Jun 7 12:46:02 2010 @@ -3,6 +3,12 @@ .. module:: optparse :synopsis: Command-line option parsing library. + :deprecated: + +.. deprecated:: 2.7 + The :mod:`optparse` module is deprecated and will not be developed further; + development will continue with the :mod:`argparse` module. + .. moduleauthor:: Greg Ward .. sectionauthor:: Greg Ward Modified: python/branches/py3k-cdecimal/Doc/library/os.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/os.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/os.rst Mon Jun 7 12:46:02 2010 @@ -697,6 +697,14 @@ Availability: Unix, Windows. +.. data:: SEEK_SET + SEEK_CUR + SEEK_END + + Parameters to the :func:`lseek` function. Their values are 0, 1, and 2, + respectively. Availability: Windows, Unix. + + .. function:: open(file, flags[, mode]) Open the file *file* and set various flags according to *flags* and possibly @@ -706,7 +714,8 @@ For a description of the flag and mode values, see the C run-time documentation; flag constants (like :const:`O_RDONLY` and :const:`O_WRONLY`) are defined in - this module too (see below). + this module too (see :ref:`open-constants`). In particular, on Windows adding + :const:`O_BINARY` is needed to open files in binary mode. Availability: Unix, Windows. @@ -794,6 +803,12 @@ :func:`fdopen`, or :data:`sys.stdout` or :data:`sys.stderr`, use its :meth:`~file.write` method. + +.. _open-constants: + +``open()`` flag constants +~~~~~~~~~~~~~~~~~~~~~~~~~ + The following constants are options for the *flags* parameter to the :func:`~os.open` function. They can be combined using the bitwise OR operator ``|``. Some of them are not available on all platforms. For descriptions of @@ -845,14 +860,6 @@ the C library. -.. data:: SEEK_SET - SEEK_CUR - SEEK_END - - Parameters to the :func:`lseek` function. Their values are 0, 1, and 2, - respectively. Availability: Windows, Unix. - - .. _os-file-dir: Files and Directories @@ -2187,8 +2194,8 @@ .. data:: devnull - The file path of the null device. For example: ``'/dev/null'`` for POSIX. - Also available via :mod:`os.path`. + The file path of the null device. For example: ``'/dev/null'`` for + POSIX, ``'nul'`` for Windows. Also available via :mod:`os.path`. .. _os-miscfunc: Modified: python/branches/py3k-cdecimal/Doc/library/socket.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/socket.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/socket.rst Mon Jun 7 12:46:02 2010 @@ -89,8 +89,9 @@ and out-of-memory conditions can be raised; errors related to socket or address semantics raise the error :exc:`socket.error`. -Non-blocking mode is supported through :meth:`setblocking`. A generalization of -this based on timeouts is supported through :meth:`settimeout`. +Non-blocking mode is supported through :meth:`~socket.setblocking`. A +generalization of this based on timeouts is supported through +:meth:`~socket.settimeout`. The module :mod:`socket` exports the following constants and functions: @@ -210,27 +211,44 @@ *source_address* was added. -.. function:: getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]]) +.. function:: getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0) - Resolves the *host*/*port* argument, into a sequence of 5-tuples that contain - all the necessary arguments for creating the corresponding socket. *host* is a domain - name, a string representation of an IPv4/v6 address or ``None``. *port* is a string - service name such as ``'http'``, a numeric port number or ``None``. - The rest of the arguments are optional and must be numeric if specified. - By passing ``None`` as the value of *host* and *port*, , you can pass ``NULL`` to the C API. + Translate the *host*/*port* argument into a sequence of 5-tuples that contain + all the necessary arguments for creating a socket connected to that service. + *host* is a domain name, a string representation of an IPv4/v6 address + or ``None``. *port* is a string service name such as ``'http'``, a numeric + port number or ``None``. By passing ``None`` as the value of *host* + and *port*, you can pass ``NULL`` to the underlying C API. + + The *family*, *socktype* and *proto* arguments can be optionally specified + in order to narrow the list of addresses returned. Passing zero as a + value for each of these arguments selects the full range of results. + The *flags* argument can be one or several of the ``AI_*`` constants, + and will influence how results are computed and returned. + For example, :const:`AI_NUMERICHOST` will disable domain name resolution + and will raise an error if *host* is a domain name. - The :func:`getaddrinfo` function returns a list of 5-tuples with the following - structure: + The function returns a list of 5-tuples with the following structure: ``(family, socktype, proto, canonname, sockaddr)`` - *family*, *socktype*, *proto* are all integers and are meant to be passed to the - :func:`socket` function. *canonname* is a string representing the canonical name - of the *host*. It can be a numeric IPv4/v6 address when :const:`AI_CANONNAME` is - specified for a numeric *host*. *sockaddr* is a tuple describing a socket - address, as described above. See the source for :mod:`socket` and other - library modules for a typical usage of the function. - + In these tuples, *family*, *socktype*, *proto* are all integers and are + meant to be passed to the :func:`socket` function. *canonname* will be + a string representing the canonical name of the *host* if + :const:`AI_CANONNAME` is part of the *flags* argument; else *canonname* + will be empty. *sockaddr* is a tuple describing a socket address, whose + format depends on the returned *family* (a ``(address, port)`` 2-tuple for + :const:`AF_INET`, a ``(address, port, flow info, scope id)`` 4-tuple for + :const:`AF_INET6`), and is meant to be passed to the :meth:`socket.connect` + method. + + The following example fetches address information for a hypothetical TCP + connection to ``www.python.org`` on port 80 (results may differ on your + system if IPv6 isn't enabled):: + + >>> socket.getaddrinfo("www.python.org", 80, 0, 0, socket.SOL_TCP) + [(2, 1, 6, '', ('82.94.164.162', 80)), + (10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0))] .. function:: getfqdn([name]) @@ -559,7 +577,9 @@ :platform: Windows The :meth:`ioctl` method is a limited interface to the WSAIoctl system - interface. Please refer to the MSDN documentation for more information. + interface. Please refer to the `Win32 documentation + `_ for more + information. On other platforms, the generic :func:`fcntl.fcntl` and :func:`fcntl.ioctl` functions may be used; they accept a socket object as their first argument. @@ -662,7 +682,7 @@ blocking mode. In non-blocking mode, if a :meth:`recv` call doesn't find any data, or if a :meth:`send` call can't immediately dispose of the data, a :exc:`error` exception is raised; in blocking mode, the calls block until they - can proceed. ``s.setblocking(0)`` is equivalent to ``s.settimeout(0)``; + can proceed. ``s.setblocking(0)`` is equivalent to ``s.settimeout(0.0)``; ``s.setblocking(1)`` is equivalent to ``s.settimeout(None)``. @@ -691,21 +711,21 @@ non-blocking mode, operations fail (with an error that is unfortunately system-dependent) if they cannot be completed immediately. In timeout mode, operations fail if they cannot be completed within the timeout specified for the -socket or if the system returns an error. The :meth:`setblocking` method is simply -a shorthand for certain :meth:`settimeout` calls. +socket or if the system returns an error. The :meth:`~socket.setblocking` +method is simply a shorthand for certain :meth:`~socket.settimeout` calls. Timeout mode internally sets the socket in non-blocking mode. The blocking and timeout modes are shared between file descriptors and socket objects that refer to the same network endpoint. A consequence of this is that file objects -returned by the :meth:`makefile` method must only be used when the socket is in -blocking mode; in timeout or non-blocking mode file operations that cannot be -completed immediately will fail. - -Note that the :meth:`connect` operation is subject to the timeout setting, and -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. +returned by the :meth:`~socket.makefile` method must only be used when the +socket is in blocking mode; in timeout or non-blocking mode file operations +that cannot be completed immediately will fail. + +Note that the :meth:`~socket.connect` operation is subject to the timeout +setting, and in general it is recommended to call :meth:`~socket.settimeout` +before calling :meth:`~socket.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. .. method:: socket.setsockopt(level, optname, value) @@ -727,8 +747,8 @@ are disallowed. If *how* is :const:`SHUT_RDWR`, further sends and receives are disallowed. -Note that there are no methods :meth:`read` or :meth:`write`; use :meth:`recv` -and :meth:`send` without *flags* argument instead. +Note that there are no methods :meth:`read` or :meth:`write`; use +:meth:`~socket.recv` and :meth:`~socket.send` without *flags* argument instead. Socket objects also have these (read-only) attributes that correspond to the values given to the :class:`socket` constructor. @@ -757,11 +777,12 @@ Here are four minimal example programs using the TCP/IP protocol: a server that echoes all data that it receives back (servicing only one client), and a client using it. Note that a server must perform the sequence :func:`socket`, -:meth:`bind`, :meth:`listen`, :meth:`accept` (possibly repeating the -:meth:`accept` to service more than one client), while a client only needs the -sequence :func:`socket`, :meth:`connect`. Also note that the server does not -:meth:`send`/:meth:`recv` on the socket it is listening on but on the new -socket returned by :meth:`accept`. +:meth:`~socket.bind`, :meth:`~socket.listen`, :meth:`~socket.accept` (possibly +repeating the :meth:`~socket.accept` to service more than one client), while a +client only needs the sequence :func:`socket`, :meth:`~socket.connect`. Also +note that the server does not :meth:`~socket.send`/:meth:`~socket.recv` on the +socket it is listening on but on the new socket returned by +:meth:`~socket.accept`. The first two examples support IPv4 only. :: Modified: python/branches/py3k-cdecimal/Doc/library/sqlite3.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/sqlite3.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/sqlite3.rst Mon Jun 7 12:46:02 2010 @@ -227,6 +227,13 @@ one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". See section :ref:`sqlite3-controlling-transactions` for a more detailed explanation. +.. attribute:: Connection.in_transaction + + .. versionadded:: 3.2 + + :const:`True` if a transaction is active (there are uncommitted changes), + :const:`False` otherwise. Read-only attribute. + .. method:: Connection.cursor([cursorClass]) @@ -806,7 +813,8 @@ before executing that command. There are two reasons for doing that. The first is that some of these commands don't work within transactions. The other reason is that sqlite3 needs to keep track of the transaction state (if a transaction -is active or not). +is active or not). The current transaction state is exposed through the +:attr:`Connection.in_transaction` attribute of the connection object. You can control which kind of ``BEGIN`` statements sqlite3 implicitly executes (or none at all) via the *isolation_level* parameter to the :func:`connect` Modified: python/branches/py3k-cdecimal/Doc/library/ssl.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/ssl.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/ssl.rst Mon Jun 7 12:46:02 2010 @@ -257,6 +257,37 @@ modern version, and probably the best choice for maximum protection, if both sides can speak it. +.. data:: OP_ALL + + Enables workarounds for various bugs present in other SSL implementations. + This option is set by default. + + .. versionadded:: 3.2 + +.. data:: OP_NO_SSLv2 + + Prevents an SSLv2 connection. This option is only applicable in + conjunction with :const:`PROTOCOL_SSLv23`. It prevents the peers from + choosing SSLv2 as the protocol version. + + .. versionadded:: 3.2 + +.. data:: OP_NO_SSLv3 + + Prevents an SSLv3 connection. This option is only applicable in + conjunction with :const:`PROTOCOL_SSLv23`. It prevents the peers from + choosing SSLv3 as the protocol version. + + .. versionadded:: 3.2 + +.. data:: OP_NO_TLSv1 + + Prevents a TLSv1 connection. This option is only applicable in + conjunction with :const:`PROTOCOL_SSLv23`. It prevents the peers from + choosing TLSv1 as the protocol version. + + .. versionadded:: 3.2 + .. data:: OPENSSL_VERSION The version string of the OpenSSL library loaded by the interpreter:: @@ -376,9 +407,21 @@ other side of the connection, rather than the original socket. +.. attribute:: SSLSocket.context + + The :class:`SSLContext` object this SSL socket is tied to. If the SSL + socket was created using the top-level :func:`wrap_socket` function + (rather than :meth:`SSLContext.wrap_socket`), this is a custom context + object created for this SSL socket. + + .. versionadded:: 3.2 + + SSL Contexts ------------ +.. versionadded:: 3.2 + .. class:: SSLContext(protocol) An object holding various data longer-lived than single SSL connections, @@ -440,6 +483,17 @@ and *suppress_ragged_eofs* have the same meaning as in the top-level :func:`wrap_socket` function. +.. attribute:: SSLContext.options + + An integer representing the set of SSL options enabled on this context. + The default value is :data:`OP_ALL`, but you can specify other options + such as :data:`OP_NO_SSLv2` by ORing them together. + + .. note:: + With versions of OpenSSL older than 0.9.8m, it is only possible + to set options, not to clear them. Attempting to clear an option + (by resetting the corresponding bits) will raise a ``ValueError``. + .. attribute:: SSLContext.protocol The protocol version chosen when constructing the context. This attribute @@ -794,6 +848,20 @@ equivalent unless anonymous ciphers are enabled (they are disabled by default). +Protocol versions +^^^^^^^^^^^^^^^^^ + +SSL version 2 is considered insecure and is therefore dangerous to use. If +you want maximum compatibility between clients and servers, it is recommended +to use :const:`PROTOCOL_SSLv23` as the protocol version and then disable +SSLv2 explicitly using the :data:`SSLContext.options` attribute:: + + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.options |= ssl.OP_NO_SSLv2 + +The SSL context created above will allow SSLv3 and TLSv1 connections, but +not SSLv2. + .. seealso:: Modified: python/branches/py3k-cdecimal/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/stdtypes.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/stdtypes.rst Mon Jun 7 12:46:02 2010 @@ -595,6 +595,109 @@ '0x1.d380000000000p+11' +.. _numeric-hash: + +Hashing of numeric types +------------------------ + +For numbers ``x`` and ``y``, possibly of different types, it's a requirement +that ``hash(x) == hash(y)`` whenever ``x == y`` (see the :meth:`__hash__` +method documentation for more details). For ease of implementation and +efficiency across a variety of numeric types (including :class:`int`, +:class:`float`, :class:`decimal.Decimal` and :class:`fractions.Fraction`) +Python's hash for numeric types is based on a single mathematical function +that's defined for any rational number, and hence applies to all instances of +:class:`int` and :class:`fraction.Fraction`, and all finite instances of +:class:`float` and :class:`decimal.Decimal`. Essentially, this function is +given by reduction modulo ``P`` for a fixed prime ``P``. The value of ``P`` is +made available to Python as the :attr:`modulus` attribute of +:data:`sys.hash_info`. + +.. impl-detail:: + + Currently, the prime used is ``P = 2**31 - 1`` on machines with 32-bit C + longs and ``P = 2**61 - 1`` on machines with 64-bit C longs. + +Here are the rules in detail: + + - If ``x = m / n`` is a nonnegative rational number and ``n`` is not divisible + by ``P``, define ``hash(x)`` as ``m * invmod(n, P) % P``, where ``invmod(n, + P)`` gives the inverse of ``n`` modulo ``P``. + + - If ``x = m / n`` is a nonnegative rational number and ``n`` is + divisible by ``P`` (but ``m`` is not) then ``n`` has no inverse + modulo ``P`` and the rule above doesn't apply; in this case define + ``hash(x)`` to be the constant value ``sys.hash_info.inf``. + + - If ``x = m / n`` is a negative rational number define ``hash(x)`` + as ``-hash(-x)``. If the resulting hash is ``-1``, replace it with + ``-2``. + + - The particular values ``sys.hash_info.inf``, ``-sys.hash_info.inf`` + and ``sys.hash_info.nan`` are used as hash values for positive + infinity, negative infinity, or nans (respectively). (All hashable + nans have the same hash value.) + + - For a :class:`complex` number ``z``, the hash values of the real + and imaginary parts are combined by computing ``hash(z.real) + + sys.hash_info.imag * hash(z.imag)``, reduced modulo + ``2**sys.hash_info.width`` so that it lies in + ``range(-2**(sys.hash_info.width - 1), 2**(sys.hash_info.width - + 1))``. Again, if the result is ``-1``, it's replaced with ``-2``. + + +To clarify the above rules, here's some example Python code, +equivalent to the builtin hash, for computing the hash of a rational +number, :class:`float`, or :class:`complex`:: + + + import sys, math + + def hash_fraction(m, n): + """Compute the hash of a rational number m / n. + + Assumes m and n are integers, with n positive. + Equivalent to hash(fractions.Fraction(m, n)). + + """ + P = sys.hash_info.modulus + # Remove common factors of P. (Unnecessary if m and n already coprime.) + while m % P == n % P == 0: + m, n = m // P, n // P + + if n % P == 0: + hash_ = sys.hash_info.inf + else: + # Fermat's Little Theorem: pow(n, P-1, P) is 1, so + # pow(n, P-2, P) gives the inverse of n modulo P. + hash_ = (abs(m) % P) * pow(n, P - 2, P) % P + if m < 0: + hash_ = -hash_ + if hash_ == -1: + hash_ = -2 + return hash_ + + def hash_float(x): + """Compute the hash of a float x.""" + + if math.isnan(x): + return sys.hash_info.nan + elif math.isinf(x): + return sys.hash_info.inf if x > 0 else -sys.hash_info.inf + else: + return hash_fraction(*x.as_integer_ratio()) + + def hash_complex(z): + """Compute the hash of a complex number z.""" + + hash_ = hash_float(z.real) + sys.hash_info.imag * hash_float(z.imag) + # do a signed reduction modulo 2**sys.hash_info.width + M = 2**(sys.hash_info.width - 1) + hash_ = (hash_ & (M - 1)) - (hash & M) + if hash_ == -1: + hash_ == -2 + return hash_ + .. _typeiter: Iterator Types Modified: python/branches/py3k-cdecimal/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/subprocess.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/subprocess.rst Mon Jun 7 12:46:02 2010 @@ -89,6 +89,12 @@ size. A negative *bufsize* means to use the system default, which usually means fully buffered. The default value for *bufsize* is :const:`0` (unbuffered). + .. note:: + + If you experience performance issues, it is recommended that you try to + enable buffering by setting *bufsize* to either -1 or a large enough + positive value (such as 4096). + The *executable* argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the *args* argument. If ``shell=True``, the *executable* argument specifies which shell to use. On Unix, Modified: python/branches/py3k-cdecimal/Doc/library/symtable.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/symtable.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/symtable.rst Mon Jun 7 12:46:02 2010 @@ -67,7 +67,7 @@ Return ``True`` if the block uses ``exec``. - .. method:: has_import_start() + .. method:: has_import_star() Return ``True`` if the block uses a starred from-import. Modified: python/branches/py3k-cdecimal/Doc/library/sys.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/sys.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/sys.rst Mon Jun 7 12:46:02 2010 @@ -446,6 +446,30 @@ Changed to a named tuple and added *service_pack_minor*, *service_pack_major*, *suite_mask*, and *product_type*. + +.. data:: hash_info + + A structseq giving parameters of the numeric hash implementation. For + more details about hashing of numeric types, see :ref:`numeric-hash`. + + +---------------------+--------------------------------------------------+ + | attribute | explanation | + +=====================+==================================================+ + | :const:`width` | width in bits used for hash values | + +---------------------+--------------------------------------------------+ + | :const:`modulus` | prime modulus P used for numeric hash scheme | + +---------------------+--------------------------------------------------+ + | :const:`inf` | hash value returned for a positive infinity | + +---------------------+--------------------------------------------------+ + | :const:`nan` | hash value returned for a nan | + +---------------------+--------------------------------------------------+ + | :const:`imag` | multiplier used for the imaginary part of a | + | | complex number | + +---------------------+--------------------------------------------------+ + + .. versionadded:: 3.2 + + .. data:: hexversion The version number encoded as a single integer. This is guaranteed to increase Modified: python/branches/py3k-cdecimal/Doc/library/sysconfig.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/sysconfig.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/sysconfig.rst Mon Jun 7 12:46:02 2010 @@ -216,3 +216,35 @@ .. function:: get_config_h_filename() Return the path of :file:`pyconfig.h`. + +Using :mod:`sysconfig` as a script +---------------------------------- + +You can use :mod:`sysconfig` as a script with Python's *-m* option:: + + $ python -m sysconfig + Platform: "macosx-10.4-i386" + Python version: "3.2" + Current installation scheme: "posix_prefix" + + Paths: + data = "/usr/local" + include = "/Users/tarek/Dev/svn.python.org/py3k/Include" + platinclude = "." + platlib = "/usr/local/lib/python3.2/site-packages" + platstdlib = "/usr/local/lib/python3.2" + purelib = "/usr/local/lib/python3.2/site-packages" + scripts = "/usr/local/bin" + stdlib = "/usr/local/lib/python3.2" + + Variables: + AC_APPLE_UNIVERSAL_BUILD = "0" + AIX_GENUINE_CPLUSPLUS = "0" + AR = "ar" + ARFLAGS = "rc" + ASDLGEN = "./Parser/asdl_c.py" + ... + +This call will print in the standard output the information returned by +:func:`get_platform`, :func:`get_python_version`, :func:`get_path` and +:func:`get_config_vars`. Modified: python/branches/py3k-cdecimal/Doc/library/syslog.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/syslog.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/syslog.rst Mon Jun 7 12:46:02 2010 @@ -10,66 +10,63 @@ Refer to the Unix manual pages for a detailed description of the ``syslog`` facility. -This module wraps the system ``syslog`` module. A pure Python -library that can speak to a syslog server is available in -the :mod:`logging.handlers` module as :class:`SysLogHandler`. +This module wraps the system ``syslog`` family of routines. A pure Python +library that can speak to a syslog server is available in the +:mod:`logging.handlers` module as :class:`SysLogHandler`. The module defines the following functions: .. function:: syslog([priority,] message) - Send the string *message* to the system logger. A trailing newline is - added if necessary. Each message is tagged with a priority composed - of a *facility* and a *level*. The optional *priority* argument, which - defaults to :const:`LOG_INFO`, determines the message priority. If the - facility is not encoded in *priority* using logical-or (``LOG_INFO | - LOG_USER``), the value given in the :func:`openlog` call is used. + Send the string *message* to the system logger. A trailing newline is added + if necessary. Each message is tagged with a priority composed of a + *facility* and a *level*. The optional *priority* argument, which defaults + to :const:`LOG_INFO`, determines the message priority. If the facility is + not encoded in *priority* using logical-or (``LOG_INFO | LOG_USER``), the + value given in the :func:`openlog` call is used. - If :func:`openlog` has not been called prior to the call to - :func:'syslog', ``openlog()`` will be called with no arguments. + If :func:`openlog` has not been called prior to the call to :func:`syslog`, + ``openlog()`` will be called with no arguments. .. function:: openlog([ident[, logopt[, facility]]]) - Logging options of subsequent :func:`syslog` calls can be set by - calling :func:`openlog`. :func:`syslog` will call :func:`openlog` - with no arguments if the log is not currently open. - - The optional *ident* keyword argument is a string which is prepended - to every message, and defaults to ''sys.argv[0]'' with leading - path components stripped. The optional *logopt* keyword argument - (default=0) is a bit field - see below for possible values to combine. - The optional *facility* keyword argument (default=:const:`LOG_USER`) - sets the default facility for messages which do not have a facility - explicitly encoded. - - .. versionchanged::3.2 - In previous versions, keyword arguments were not allowed, and *ident* - was required. The default for *ident* was dependent on the system - libraries, and often was ''python'' instead of the name of the - python program file. + Logging options of subsequent :func:`syslog` calls can be set by calling + :func:`openlog`. :func:`syslog` will call :func:`openlog` with no arguments + if the log is not currently open. + + The optional *ident* keyword argument is a string which is prepended to every + message, and defaults to ``sys.argv[0]`` with leading path components + stripped. The optional *logopt* keyword argument (default is 0) is a bit + field -- see below for possible values to combine. The optional *facility* + keyword argument (default is :const:`LOG_USER`) sets the default facility for + messages which do not have a facility explicitly encoded. + + .. versionchanged:: 3.2 + In previous versions, keyword arguments were not allowed, and *ident* was + required. The default for *ident* was dependent on the system libraries, + and often was ``python`` instead of the name of the python program file. .. function:: closelog() - Reset the syslog module values and call the system library - ''closelog()''. + Reset the syslog module values and call the system library ``closelog()``. - This causes the module to behave as it does when initially imported. - For example, :func:'openlog' will be called on the first :func:'syslog' - call (if :func:'openlog' hasn't already been called), and *ident* - and other :func:'openlog' parameters are reset to defaults. + This causes the module to behave as it does when initially imported. For + example, :func:`openlog` will be called on the first :func:`syslog` call (if + :func:`openlog` hasn't already been called), and *ident* and other + :func:`openlog` parameters are reset to defaults. .. function:: setlogmask(maskpri) - Set the priority mask to *maskpri* and return the previous mask value. - Calls to :func:`syslog` with a priority level not set in *maskpri* - are ignored. The default is to log all priorities. The function - ``LOG_MASK(pri)`` calculates the mask for the individual priority - *pri*. The function ``LOG_UPTO(pri)`` calculates the mask for all - priorities up to and including *pri*. + Set the priority mask to *maskpri* and return the previous mask value. Calls + to :func:`syslog` with a priority level not set in *maskpri* are ignored. + The default is to log all priorities. The function ``LOG_MASK(pri)`` + calculates the mask for the individual priority *pri*. The function + ``LOG_UPTO(pri)`` calculates the mask for all priorities up to and including + *pri*. The module defines the following constants: @@ -100,11 +97,11 @@ syslog.syslog('Processing started') if error: - syslog.syslog(syslog.LOG_ERR, 'Processing started') + syslog.syslog(syslog.LOG_ERR, 'Processing started') -An example of setting some log options, these would include the process ID -in logged messages, and write the messages to the destination facility -used for mail logging:: +An example of setting some log options, these would include the process ID in +logged messages, and write the messages to the destination facility used for +mail logging:: syslog.openlog(logopt=syslog.LOG_PID, facility=syslog.LOG_MAIL) syslog.syslog('E-mail processing initiated...') Modified: python/branches/py3k-cdecimal/Doc/library/telnetlib.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/telnetlib.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/telnetlib.rst Mon Jun 7 12:46:02 2010 @@ -27,16 +27,11 @@ :class:`Telnet` represents a connection to a Telnet server. The instance is initially not connected by default; the :meth:`open` method must be used to establish a connection. Alternatively, the host name and optional port - and timeout can be passed to the constructor, in which case the connection to - the server will be established before the constructor returns. The optional - *timeout* parameter specifies a timeout in seconds for the connection attempt (if - not specified, the global default timeout setting will be used). - number can be passed to the constructor, to, in which case the connection to - the server will be established before the constructor returns. The optional + the server will be established before the constructor returns. The optional *timeout* parameter specifies a timeout in seconds for blocking operations - like the connection attempt (if not specified, or passed as None, the global - default timeout setting will be used). + like the connection attempt (if not specified, the global default timeout + setting will be used). Do not reopen an already connected instance. Modified: python/branches/py3k-cdecimal/Doc/library/tempfile.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/tempfile.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/tempfile.rst Mon Jun 7 12:46:02 2010 @@ -27,8 +27,7 @@ The module defines the following user-callable functions: - -.. function:: TemporaryFile(mode='w+b', bufsize=-1, suffix='', prefix='tmp', dir=None) +.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None) Return a file-like object that can be used as a temporary storage area. The file is created using :func:`mkstemp`. It will be destroyed as soon @@ -41,8 +40,8 @@ The *mode* parameter defaults to ``'w+b'`` so that the file created can be read and written without being closed. Binary mode is used so that it behaves consistently on all platforms without regard for the data that is - stored. *bufsize* defaults to ``-1``, meaning that the operating system - default is used. + stored. *buffering*, *encoding* and *newline* are interpreted as for + :func:`open`. The *dir*, *prefix* and *suffix* parameters are passed to :func:`mkstemp`. @@ -52,7 +51,7 @@ :keyword:`with` statement, just like a normal file. -.. function:: NamedTemporaryFile(mode='w+b', bufsize=-1, suffix='', prefix='tmp', dir=None, delete=True) +.. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None, delete=True) This function operates exactly as :func:`TemporaryFile` does, except that the file is guaranteed to have a visible name in the file system (on @@ -67,7 +66,7 @@ be used in a :keyword:`with` statement, just like a normal file. -.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', bufsize=-1, suffix='', prefix='tmp', dir=None) +.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None) This function operates exactly as :func:`TemporaryFile` does, except that data is spooled in memory until the file size exceeds *max_size*, or Modified: python/branches/py3k-cdecimal/Doc/library/time.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/time.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/time.rst Mon Jun 7 12:46:02 2010 @@ -81,30 +81,31 @@ :func:`gmtime`, :func:`localtime`, and :func:`strptime` also offer attribute names for individual fields. - +-------+------------------+------------------------------+ - | Index | Attribute | Values | - +=======+==================+==============================+ - | 0 | :attr:`tm_year` | (for example, 1993) | - +-------+------------------+------------------------------+ - | 1 | :attr:`tm_mon` | range [1,12] | - +-------+------------------+------------------------------+ - | 2 | :attr:`tm_mday` | range [1,31] | - +-------+------------------+------------------------------+ - | 3 | :attr:`tm_hour` | range [0,23] | - +-------+------------------+------------------------------+ - | 4 | :attr:`tm_min` | range [0,59] | - +-------+------------------+------------------------------+ - | 5 | :attr:`tm_sec` | range [0,61]; see **(1)** in | - | | | :func:`strftime` description | - +-------+------------------+------------------------------+ - | 6 | :attr:`tm_wday` | range [0,6], Monday is 0 | - +-------+------------------+------------------------------+ - | 7 | :attr:`tm_yday` | range [1,366] | - +-------+------------------+------------------------------+ - | 8 | :attr:`tm_isdst` | 0, 1 or -1; see below | - +-------+------------------+------------------------------+ + +-------+-------------------+---------------------------------+ + | Index | Attribute | Values | + +=======+===================+=================================+ + | 0 | :attr:`tm_year` | (for example, 1993) | + +-------+-------------------+---------------------------------+ + | 1 | :attr:`tm_mon` | range [1, 12] | + +-------+-------------------+---------------------------------+ + | 2 | :attr:`tm_mday` | range [1, 31] | + +-------+-------------------+---------------------------------+ + | 3 | :attr:`tm_hour` | range [0, 23] | + +-------+-------------------+---------------------------------+ + | 4 | :attr:`tm_min` | range [0, 59] | + +-------+-------------------+---------------------------------+ + | 5 | :attr:`tm_sec` | range [0, 61]; see **(1)** in | + | | | :func:`strftime` description | + +-------+-------------------+---------------------------------+ + | 6 | :attr:`tm_wday` | range [0, 6], Monday is 0 | + +-------+-------------------+---------------------------------+ + | 7 | :attr:`tm_yday` | range [1, 366] | + +-------+-------------------+---------------------------------+ + | 8 | :attr:`tm_isdst` | 0, 1 or -1; see below | + +-------+-------------------+---------------------------------+ - Note that unlike the C structure, the month value is a range of 1-12, not 0-11. + Note that unlike the C structure, the month value is a range of [1, 12], + not [0, 11]. A year value will be handled as described under "Year 2000 (Y2K) issues" above. A ``-1`` argument as the daylight savings flag, passed to :func:`mktime` will usually result in the correct daylight savings state to be filled in. Modified: python/branches/py3k-cdecimal/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/unittest.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/unittest.rst Mon Jun 7 12:46:02 2010 @@ -749,7 +749,7 @@ .. method:: skipTest(reason) - Calling this during the a test method or :meth:`setUp` skips the current + Calling this during a test method or :meth:`setUp` skips the current test. See :ref:`unittest-skipping` for more information. .. versionadded:: 3.1 @@ -773,8 +773,7 @@ will be *msg* if given, otherwise it will be :const:`None`. .. deprecated:: 3.1 - :meth:`failUnless`; use one of the ``assert`` variants. - :meth:`assert_`; use :meth:`assertTrue`. + :meth:`failUnless` and :meth:`assert_`; use :meth:`assertTrue`. .. method:: assertEqual(first, second, msg=None) @@ -1169,6 +1168,21 @@ .. versionadded:: 3.1 + .. attribute:: maxDiff + + This attribute controls the maximum length of diffs output by assert + methods that report diffs on failure. It defaults to 80*8 characters. + Assert methods affected by this attribute are + :meth:`assertSequenceEqual` (including all the sequence comparison + methods that delegate to it), :meth:`assertDictEqual` and + :meth:`assertMultiLineEqual`. + + Setting ``maxDiff`` to None means that there is no maximum length of + diffs. + + .. versionadded:: 3.2 + + Testing frameworks can use the following methods to collect information on the test: @@ -1863,7 +1877,9 @@ If an exception is raised during a ``setUpClass`` then the tests in the class are not run and the ``tearDownClass`` is not run. Skipped classes will not -have ``setUpClass`` or ``tearDownClass`` run. +have ``setUpClass`` or ``tearDownClass`` run. If the exception is a +``SkipTest`` exception then the class will be reported as having been skipped +instead of as an error. setUpModule and tearDownModule @@ -1878,7 +1894,9 @@ closeConnection() If an exception is raised in a ``setUpModule`` then none of the tests in the -module will be run and the ``tearDownModule`` will not be run. +module will be run and the ``tearDownModule`` will not be run. If the exception is a +``SkipTest`` exception then the module will be reported as having been skipped +instead of as an error. Signal Handling Modified: python/branches/py3k-cdecimal/Doc/library/urllib.parse.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/urllib.parse.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/urllib.parse.rst Mon Jun 7 12:46:02 2010 @@ -26,7 +26,7 @@ The :mod:`urllib.parse` module defines the following functions: -.. function:: urlparse(urlstring, default_scheme='', allow_fragments=True) +.. function:: urlparse(urlstring, scheme='', allow_fragments=True) Parse a URL into six components, returning a 6-tuple. This corresponds to the general structure of a URL: ``scheme://netloc/path;parameters?query#fragment``. @@ -48,7 +48,7 @@ >>> o.geturl() 'http://www.cwi.nl:80/%7Eguido/Python.html' - If the *default_scheme* argument is specified, it gives the default addressing + If the *scheme* argument is specified, it gives the default addressing scheme, to be used only if the URL does not specify one. The default value for this argument is the empty string. @@ -142,7 +142,7 @@ states that these are equivalent). -.. function:: urlsplit(urlstring, default_scheme='', allow_fragments=True) +.. function:: urlsplit(urlstring, scheme='', allow_fragments=True) This is similar to :func:`urlparse`, but does not split the params from the URL. This should generally be used instead of :func:`urlparse` if the more recent URL @@ -312,19 +312,21 @@ .. function:: urlencode(query, doseq=False) - Convert a mapping object or a sequence of two-element tuples to a "url-encoded" - string, suitable to pass to :func:`urlopen` above as the optional *data* - argument. This is useful to pass a dictionary of form fields to a ``POST`` - request. The resulting string is a series of ``key=value`` pairs separated by - ``'&'`` characters, where both *key* and *value* are quoted using - :func:`quote_plus` above. If the optional parameter *doseq* is present and - evaluates to true, individual ``key=value`` pairs are generated for each element - of the sequence. When a sequence of two-element tuples is used as the *query* - argument, the first element of each tuple is a key and the second is a value. - The order of parameters in the encoded string will match the order of parameter - tuples in the sequence. This module provides the functions - :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings - into Python data structures. + Convert a mapping object or a sequence of two-element tuples to a + "url-encoded" string, suitable to pass to :func:`urlopen` above as the + optional *data* argument. This is useful to pass a dictionary of form + fields to a ``POST`` request. The resulting string is a series of + ``key=value`` pairs separated by ``'&'`` characters, where both *key* and + *value* are quoted using :func:`quote_plus` above. When a sequence of + two-element tuples is used as the *query* argument, the first element of + each tuple is a key and the second is a value. The value element in itself + can be a sequence and in that case, if the optional parameter *doseq* is + evaluates to *True*, individual ``key=value`` pairs separated by ``'&'`` are + generated for each element of the value sequence for the key. The order of + parameters in the encoded string will match the order of parameter tuples in + the sequence. This module provides the functions :func:`parse_qs` and + :func:`parse_qsl` which are used to parse query strings into Python data + structures. .. seealso:: Modified: python/branches/py3k-cdecimal/Doc/library/urllib.request.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/urllib.request.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/urllib.request.rst Mon Jun 7 12:46:02 2010 @@ -604,7 +604,7 @@ method on the currently installed global :class:`OpenerDirector`). The optional *timeout* parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default - timeout setting will be usedi). The timeout feature actually works only for + timeout setting will be used). The timeout feature actually works only for HTTP, HTTPS, FTP and FTPS connections). @@ -1079,7 +1079,7 @@ >>> import urllib.request >>> f = urllib.request.urlopen('http://www.python.org/') - >>> print(fp.read(100).decode('utf-8')) + >>> print(f.read(100).decode('utf-8')) ` is used +to ensure that the handles are closed correctly, even if the programmer neglects +to explicitly close them. This module offers the following functions: .. function:: CloseKey(hkey) - Closes a previously opened registry key. The hkey argument specifies a + Closes a previously opened registry key. The *hkey* argument specifies a previously opened key. .. note:: - If *hkey* is not closed using this method (or via :meth:`hkey.Close() `), - it is closed when the *hkey* object is destroyed by Python. + + If *hkey* is not closed using this method (or via :meth:`hkey.Close() + `), it is closed when the *hkey* object is destroyed by + Python. .. function:: ConnectRegistry(computer_name, key) @@ -109,7 +111,7 @@ The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx Windows API function, which is specific to 64-bit versions of Windows. See the `RegDeleteKeyEx documentation - `__. + `__. *key* is an already open key, or one of the predefined :ref:`HKEY_* constants `. @@ -120,7 +122,7 @@ *res* is a reserved integer, and must be zero. The default is zero. - *sam* is an integer that specifies an access mask that describes the + *sam* is an integer that specifies an access mask that describes the desired security access for the key. Default is :const:`KEY_ALL_ACCESS`. See :ref:`Access Rights ` for other allowed values. @@ -183,13 +185,15 @@ | | registry type | +-------+--------------------------------------------+ | ``2`` | An integer that identifies the type of the | - | | value data | + | | value data (see table in docs for | + | | :meth:`SetValueEx`) | +-------+--------------------------------------------+ .. function:: ExpandEnvironmentStrings(str) - Expands environment strings %NAME% in unicode string like :const:`REG_EXPAND_SZ`:: + Expands environment variable placeholders ``%NAME%`` in strings like + :const:`REG_EXPAND_SZ`:: >>> ExpandEnvironmentStrings('%windir%') 'C:\\Windows' @@ -223,23 +227,20 @@ *key* is a handle returned by :func:`ConnectRegistry` or one of the constants :const:`HKEY_USERS` or :const:`HKEY_LOCAL_MACHINE`. - *sub_key* is a string that identifies the sub_key to load. + *sub_key* is a string that identifies the subkey to load. *file_name* is the name of the file to load registry data from. This file must have been created with the :func:`SaveKey` function. Under the file allocation table (FAT) file system, the filename may not have an extension. - A call to LoadKey() fails if the calling process does not have the - :const:`SE_RESTORE_PRIVILEGE` privilege. Note that privileges are different than + A call to :func:`LoadKey` fails if the calling process does not have the + :const:`SE_RESTORE_PRIVILEGE` privilege. Note that privileges are different from permissions -- see the `RegLoadKey documentation `__ for more details. If *key* is a handle returned by :func:`ConnectRegistry`, then the path - specified in *fileName* is relative to the remote computer. - - The Win32 documentation implies *key* must be in the :const:`HKEY_USER` or - :const:`HKEY_LOCAL_MACHINE` tree. This may or may not be true. + specified in *file_name* is relative to the remote computer. .. function:: OpenKey(key, sub_key[, res[, sam]]) @@ -254,8 +255,8 @@ *res* is a reserved integer, and must be zero. The default is zero. *sam* is an integer that specifies an access mask that describes the desired - security access for the key. Default is :const:`KEY_READ`. See - :ref:`Access Rights ` for other allowed values. + security access for the key. Default is :const:`KEY_READ`. See :ref:`Access + Rights ` for other allowed values. The result is a new handle to the specified key. @@ -327,7 +328,8 @@ | ``0`` | The value of the registry item. | +-------+-----------------------------------------+ | ``1`` | An integer giving the registry type for | - | | this value. | + | | this value (see table in docs for | + | | :meth:`SetValueEx`) | +-------+-----------------------------------------+ @@ -338,10 +340,10 @@ *key* is an already open key, or one of the predefined :ref:`HKEY_* constants `. - *file_name* is the name of the file to save registry data to. This file cannot - already exist. If this filename includes an extension, it cannot be used on file - allocation table (FAT) file systems by the :meth:`LoadKey`, :meth:`ReplaceKey` - or :meth:`RestoreKey` methods. + *file_name* is the name of the file to save registry data to. This file + cannot already exist. If this filename includes an extension, it cannot be + used on file allocation table (FAT) file systems by the :meth:`LoadKey` + method. If *key* represents a key on a remote computer, the path described by *file_name* is relative to the remote computer. The caller of this method must @@ -411,16 +413,16 @@ .. function:: DisableReflectionKey(key) Disables registry reflection for 32-bit processes running on a 64-bit - Operating System. + operating system. - *key* is an already open key, or one of the predefined - :ref:`HKEY_* constants `. + *key* is an already open key, or one of the predefined :ref:`HKEY_* constants + `. - Will generally raise :exc:`NotImplemented` if executed on a 32-bit - Operating System. + Will generally raise :exc:`NotImplemented` if executed on a 32-bit operating + system. If the key is not on the reflection list, the function succeeds but has no - effect. Disabling reflection for a key does not affect reflection of any + effect. Disabling reflection for a key does not affect reflection of any subkeys. @@ -428,11 +430,11 @@ Restores registry reflection for the specified disabled key. - *key* is an already open key, or one of the predefined - :ref:`HKEY_* constants `. + *key* is an already open key, or one of the predefined :ref:`HKEY_* constants + `. - Will generally raise :exc:`NotImplemented` if executed on a 32-bit - Operating System. + Will generally raise :exc:`NotImplemented` if executed on a 32-bit operating + system. Restoring reflection for a key does not affect reflection of any subkeys. @@ -447,7 +449,7 @@ Returns ``True`` if reflection is disabled. Will generally raise :exc:`NotImplemented` if executed on a 32-bit - Operating System. + operating system. .. _constants: @@ -646,7 +648,7 @@ This object wraps a Windows HKEY object, automatically closing it when the object is destroyed. To guarantee cleanup, you can call either the -:meth:`Close` method on the object, or the :func:`CloseKey` function. +:meth:`~PyHKEY.Close` method on the object, or the :func:`CloseKey` function. All registry functions in this module return one of these objects. @@ -666,8 +668,8 @@ Handle objects can be converted to an integer (e.g., using the built-in :func:`int` function), in which case the underlying Windows handle value is -returned. You can also use the :meth:`Detach` method to return the integer -handle, and also disconnect the Windows handle from the handle object. +returned. You can also use the :meth:`~PyHKEY.Detach` method to return the +integer handle, and also disconnect the Windows handle from the handle object. .. method:: PyHKEY.Close() @@ -692,11 +694,12 @@ .. method:: PyHKEY.__enter__() PyHKEY.__exit__(\*exc_info) - The HKEY object implements :meth:`__enter__` and :meth:`__exit__` and thus - supports the context protocol for the :keyword:`with` statement:: + The HKEY object implements :meth:`~object.__enter__` and + :meth:`~object.__exit__` and thus supports the context protocol for the + :keyword:`with` statement:: with OpenKey(HKEY_LOCAL_MACHINE, "foo") as key: - # ... work with key ... + ... # work with key will automatically close *key* when control leaves the :keyword:`with` block. Modified: python/branches/py3k-cdecimal/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/reference/datamodel.rst (original) +++ python/branches/py3k-cdecimal/Doc/reference/datamodel.rst Mon Jun 7 12:46:02 2010 @@ -1587,6 +1587,46 @@ called *members*. +Customizing instance and subclass checks +---------------------------------------- + +The following methods are used to override the default behavior of the +:func:`isinstance` and :func:`issubclass` built-in functions. + +In particular, the metaclass :class:`abc.ABCMeta` implements these methods in +order to allow the addition of Abstract Base Classes (ABCs) as "virtual base +classes" to any class or type (including built-in types), and including to other +ABCs. + +.. method:: class.__instancecheck__(self, instance) + + Return true if *instance* should be considered a (direct or indirect) + instance of *class*. If defined, called to implement ``isinstance(instance, + class)``. + + +.. method:: class.__subclasscheck__(self, subclass) + + Return true if *subclass* should be considered a (direct or indirect) + subclass of *class*. If defined, called to implement ``issubclass(subclass, + class)``. + + +Note that these methods are looked up on the type (metaclass) of a class. They +cannot be defined as class methods in the actual class. This is consistent with +the lookup of special methods that are called on instances, only that in this +case the instance is itself a class. + +.. seealso:: + + :pep:`3119` - Introducing Abstract Base Classes + Includes the specification for customizing :func:`isinstance` and + :func:`issubclass` behavior through :meth:`__instancecheck__` and + :meth:`__subclasscheck__`, with motivation for this functionality in the + context of adding Abstract Base Classes (see the :mod:`abc` module) to the + language. + + .. _callable-types: Emulating callable objects Modified: python/branches/py3k-cdecimal/Doc/tools/sphinxext/pyspecific.py ============================================================================== --- python/branches/py3k-cdecimal/Doc/tools/sphinxext/pyspecific.py (original) +++ python/branches/py3k-cdecimal/Doc/tools/sphinxext/pyspecific.py Mon Jun 7 12:46:02 2010 @@ -78,7 +78,7 @@ 'assert', 'assignment', 'atom-identifiers', 'atom-literals', 'attribute-access', 'attribute-references', 'augassign', 'binary', 'bitwise', 'bltin-code-objects', 'bltin-ellipsis-object', - 'bltin-file-objects', 'bltin-null-object', 'bltin-type-objects', 'booleans', + 'bltin-null-object', 'bltin-type-objects', 'booleans', 'break', 'callable-types', 'calls', 'class', 'comparisons', 'compound', 'context-managers', 'continue', 'conversions', 'customization', 'debugger', 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'execmodel', Modified: python/branches/py3k-cdecimal/Doc/tutorial/datastructures.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/tutorial/datastructures.rst (original) +++ python/branches/py3k-cdecimal/Doc/tutorial/datastructures.rst Mon Jun 7 12:46:02 2010 @@ -377,10 +377,7 @@ Here is a brief demonstration:: - >>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} - >>> print(basket) - {'orange', 'banana', 'pear', 'apple'} - >>> fruit = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] + >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> fruit = set(basket) # create a set without duplicates >>> fruit {'orange', 'pear', 'apple', 'banana'} Modified: python/branches/py3k-cdecimal/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k-cdecimal/Doc/whatsnew/3.2.rst Mon Jun 7 12:46:02 2010 @@ -100,6 +100,18 @@ (Contributed by Tarek Ziade.) +* The *sqlite3* module has some new features: + + * XXX *enable_load_extension* + + * XXX *load_extension* + + * New :class:`~sqlite3.Connection` attribute + :attr:`~sqlite3.Connection.in_transaction` is :const:`True` when there + are uncommitted changes, and :const:`False` otherwise. (Contributed + by R. David Murray and Shashwat Anand, :issue:`8845`.) + + Multi-threading =============== Modified: python/branches/py3k-cdecimal/Include/longobject.h ============================================================================== --- python/branches/py3k-cdecimal/Include/longobject.h (original) +++ python/branches/py3k-cdecimal/Include/longobject.h Mon Jun 7 12:46:02 2010 @@ -101,6 +101,14 @@ */ PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); +/* _PyLong_Divmod_Near. Given integers a and b, compute the nearest + integer q to the exact quotient a / b, rounding to the nearest even integer + in the case of a tie. Return (q, r), where r = a - q*b. The remainder r + will satisfy abs(r) <= abs(b)/2, with equality possible only if q is + even. +*/ +PyAPI_FUNC(PyObject *) _PyLong_Divmod_Near(PyObject *, PyObject *); + /* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in base 256, and return a Python long with the same numeric value. If n is 0, the integer is 0. Else: Modified: python/branches/py3k-cdecimal/Include/pyport.h ============================================================================== --- python/branches/py3k-cdecimal/Include/pyport.h (original) +++ python/branches/py3k-cdecimal/Include/pyport.h Mon Jun 7 12:46:02 2010 @@ -126,6 +126,20 @@ #endif #endif +/* Parameters used for the numeric hash implementation. See notes for + _PyHash_Double in Objects/object.c. Numeric hashes are based on + reduction modulo the prime 2**_PyHASH_BITS - 1. */ + +#if SIZEOF_LONG >= 8 +#define _PyHASH_BITS 61 +#else +#define _PyHASH_BITS 31 +#endif +#define _PyHASH_MODULUS ((1UL << _PyHASH_BITS) - 1) +#define _PyHASH_INF 314159 +#define _PyHASH_NAN 0 +#define _PyHASH_IMAG 1000003UL + /* uintptr_t is the C9X name for an unsigned integral type such that a * legitimate void* can be cast to uintptr_t and then back to void* again * without loss of information. Similarly for intptr_t, wrt a signed Modified: python/branches/py3k-cdecimal/Include/sysmodule.h ============================================================================== --- python/branches/py3k-cdecimal/Include/sysmodule.h (original) +++ python/branches/py3k-cdecimal/Include/sysmodule.h Mon Jun 7 12:46:02 2010 @@ -10,6 +10,7 @@ PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **); +PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int); PyAPI_FUNC(void) PySys_SetPath(const wchar_t *); PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) @@ -21,6 +22,7 @@ PyAPI_FUNC(void) PySys_ResetWarnOptions(void); PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *); +PyAPI_FUNC(void) PySys_AddWarnOptionUnicode(PyObject *); PyAPI_FUNC(int) PySys_HasWarnOptions(void); #ifdef __cplusplus Modified: python/branches/py3k-cdecimal/Lib/_abcoll.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/_abcoll.py (original) +++ python/branches/py3k-cdecimal/Lib/_abcoll.py Mon Jun 7 12:46:02 2010 @@ -376,8 +376,9 @@ return ValuesView(self) def __eq__(self, other): - return isinstance(other, Mapping) and \ - dict(self.items()) == dict(other.items()) + if not isinstance(other, Mapping): + return NotImplemented + return dict(self.items()) == dict(other.items()) def __ne__(self, other): return not (self == other) Modified: python/branches/py3k-cdecimal/Lib/argparse.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/argparse.py (original) +++ python/branches/py3k-cdecimal/Lib/argparse.py Mon Jun 7 12:46:02 2010 @@ -987,7 +987,7 @@ version=None, dest=SUPPRESS, default=SUPPRESS, - help=None): + help="show program's version number and exit"): super(_VersionAction, self).__init__( option_strings=option_strings, dest=dest, Modified: python/branches/py3k-cdecimal/Lib/base64.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/base64.py (original) +++ python/branches/py3k-cdecimal/Lib/base64.py Mon Jun 7 12:46:02 2010 @@ -383,9 +383,9 @@ if o == '-u': func = decode if o == '-t': test(); return if args and args[0] != '-': - func(open(args[0], 'rb'), sys.stdout) + func(open(args[0], 'rb'), sys.stdout.buffer) else: - func(sys.stdin, sys.stdout) + func(sys.stdin.buffer, sys.stdout.buffer) def test(): Modified: python/branches/py3k-cdecimal/Lib/codecs.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/codecs.py (original) +++ python/branches/py3k-cdecimal/Lib/codecs.py Mon Jun 7 12:46:02 2010 @@ -374,6 +374,11 @@ """ pass + def seek(self, offset, whence=0): + self.stream.seek(offset, whence) + if whence == 0 and offset == 0: + self.reset() + def __getattr__(self, name, getattr=getattr): @@ -606,8 +611,8 @@ Resets the codec buffers used for keeping state. """ - self.reset() self.stream.seek(offset, whence) + self.reset() def __next__(self): @@ -699,6 +704,12 @@ self.reader.reset() self.writer.reset() + def seek(self, offset, whence=0): + self.stream.seek(offset, whence) + self.reader.reset() + if whence == 0 and offset == 0: + self.writer.reset() + def __getattr__(self, name, getattr=getattr): Modified: python/branches/py3k-cdecimal/Lib/decimal.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/decimal.py (original) +++ python/branches/py3k-cdecimal/Lib/decimal.py Mon Jun 7 12:46:02 2010 @@ -164,7 +164,7 @@ anything, though. handle -- Called when context._raise_error is called and the - trap_enabler is set. First argument is self, second is the + trap_enabler is not set. First argument is self, second is the context. More arguments can be given, those being after the explanation in _raise_error (For example, context._raise_error(NewError, '(-x)!', self._sign) would @@ -862,7 +862,7 @@ # that specified by IEEE 754. def __eq__(self, other, context=None): - other = _convert_other(other, allow_float=True) + other = _convert_other(other, allow_float = True) if other is NotImplemented: return other if self._check_nans(other, context): @@ -870,7 +870,7 @@ return self._cmp(other) == 0 def __ne__(self, other, context=None): - other = _convert_other(other, allow_float=True) + other = _convert_other(other, allow_float = True) if other is NotImplemented: return other if self._check_nans(other, context): @@ -879,7 +879,7 @@ def __lt__(self, other, context=None): - other = _convert_other(other, allow_float=True) + other = _convert_other(other, allow_float = True) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -888,7 +888,7 @@ return self._cmp(other) < 0 def __le__(self, other, context=None): - other = _convert_other(other, allow_float=True) + other = _convert_other(other, allow_float = True) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -897,7 +897,7 @@ return self._cmp(other) <= 0 def __gt__(self, other, context=None): - other = _convert_other(other, allow_float=True) + other = _convert_other(other, allow_float = True) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -906,7 +906,7 @@ return self._cmp(other) > 0 def __ge__(self, other, context=None): - other = _convert_other(other, allow_float=True) + other = _convert_other(other, allow_float = True) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -935,55 +935,28 @@ def __hash__(self): """x.__hash__() <==> hash(x)""" - # Decimal integers must hash the same as the ints - # - # The hash of a nonspecial noninteger Decimal must depend only - # on the value of that Decimal, and not on its representation. - # For example: hash(Decimal('100E-1')) == hash(Decimal('10')). - - # Equality comparisons involving signaling nans can raise an - # exception; since equality checks are implicitly and - # unpredictably used when checking set and dict membership, we - # prevent signaling nans from being used as set elements or - # dict keys by making __hash__ raise an exception. + + # In order to make sure that the hash of a Decimal instance + # agrees with the hash of a numerically equal integer, float + # or Fraction, we follow the rules for numeric hashes outlined + # in the documentation. (See library docs, 'Built-in Types'). if self._is_special: if self.is_snan(): raise TypeError('Cannot hash a signaling NaN value.') elif self.is_nan(): - # 0 to match hash(float('nan')) - return 0 + return _PyHASH_NAN else: - # values chosen to match hash(float('inf')) and - # hash(float('-inf')). if self._sign: - return -271828 + return -_PyHASH_INF else: - return 314159 + return _PyHASH_INF - # In Python 2.7, we're allowing comparisons (but not - # arithmetic operations) between floats and Decimals; so if - # a Decimal instance is exactly representable as a float then - # its hash should match that of the float. - self_as_float = float(self) - if Decimal.from_float(self_as_float) == self: - return hash(self_as_float) - - if self._isinteger(): - op = _WorkRep(self.to_integral_value()) - # to make computation feasible for Decimals with large - # exponent, we use the fact that hash(n) == hash(m) for - # any two nonzero integers n and m such that (i) n and m - # have the same sign, and (ii) n is congruent to m modulo - # 2**64-1. So we can replace hash((-1)**s*c*10**e) with - # hash((-1)**s*c*pow(10, e, 2**64-1). - return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1)) - # The value of a nonzero nonspecial Decimal instance is - # faithfully represented by the triple consisting of its sign, - # its adjusted exponent, and its coefficient with trailing - # zeros removed. - return hash((self._sign, - self._exp+len(self._int), - self._int.rstrip('0'))) + if self._exp >= 0: + exp_hash = pow(10, self._exp, _PyHASH_MODULUS) + else: + exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS) + hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS + return hash_ if self >= 0 else -hash_ def as_tuple(self): """Represents the number as a triple tuple. @@ -1611,9 +1584,9 @@ """Decapitate the payload of a NaN to fit the context""" payload = self._int - # maximum length of payload is precision if _clamp=0, - # precision-1 if _clamp=1. - max_payload_len = context.prec - context._clamp + # maximum length of payload is precision if clamp=0, + # precision-1 if clamp=1. + max_payload_len = context.prec - context.clamp if len(payload) > max_payload_len: payload = payload[len(payload)-max_payload_len:].lstrip('0') return _dec_from_triple(self._sign, payload, self._exp, True) @@ -1638,11 +1611,11 @@ return Decimal(self) # if self is zero then exponent should be between Etiny and - # Emax if _clamp==0, and between Etiny and Etop if _clamp==1. + # Emax if clamp==0, and between Etiny and Etop if clamp==1. Etiny = context.Etiny() Etop = context.Etop() if not self: - exp_max = [context.Emax, Etop][context._clamp] + exp_max = [context.Emax, Etop][context.clamp] new_exp = min(max(self._exp, Etiny), exp_max) if new_exp != self._exp: context._raise_error(Clamped) @@ -1702,8 +1675,8 @@ if self_is_subnormal: context._raise_error(Subnormal) - # fold down if _clamp == 1 and self has too few digits - if context._clamp == 1 and self._exp > Etop: + # fold down if clamp == 1 and self has too few digits + if context.clamp == 1 and self._exp > Etop: context._raise_error(Clamped) self_padded = self._int + '0'*(self._exp - Etop) return _dec_from_triple(self._sign, self_padded, Etop) @@ -2451,7 +2424,7 @@ if not dup: return _dec_from_triple(dup._sign, '0', 0) - exp_max = [context.Emax, context.Etop()][context._clamp] + exp_max = [context.Emax, context.Etop()][context.clamp] end = len(dup._int) exp = dup._exp while dup._int[end-1] == '0' and exp < exp_max: @@ -3828,13 +3801,13 @@ Emax - Maximum exponent capitals - If 1, 1*10^1 is printed as 1E+1. If 0, printed as 1e1 - _clamp - If 1, change exponents if too high (Default 0) + clamp - If 1, change exponents if too high (Default 0) """ def __init__(self, prec=None, rounding=None, traps=None, flags=None, Emin=None, Emax=None, - capitals=None, _clamp=0, + capitals=None, clamp=None, _ignored_flags=None): if flags is None: flags = [] @@ -3855,7 +3828,8 @@ """Show the current context.""" s = [] s.append('Context(prec=%(prec)d, rounding=%(rounding)s, ' - 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' + 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d, ' + 'clamp=%(clamp)d' % vars(self)) names = [f.__name__ for f, v in self.flags.items() if v] s.append('flags=[' + ', '.join(names) + ']') @@ -3872,23 +3846,45 @@ """Returns a shallow copy from self.""" nc = Context(self.prec, self.rounding, self.traps, self.flags, self.Emin, self.Emax, - self.capitals, self._clamp, self._ignored_flags) + self.capitals, self.clamp, self._ignored_flags) return nc def copy(self): """Returns a deep copy from self.""" nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(), self.Emin, self.Emax, - self.capitals, self._clamp, self._ignored_flags) + self.capitals, self.clamp, self._ignored_flags) return nc __copy__ = copy + # _clamp is provided for backwards compatibility with third-party + # code. May be removed in Python >= 3.3. + def _get_clamp(self): + "_clamp mirrors the clamp attribute. Its use is deprecated." + import warnings + warnings.warn('Use of the _clamp attribute is deprecated. ' + 'Please use clamp instead.', + DeprecationWarning) + return self.clamp + + def _set_clamp(self, clamp): + "_clamp mirrors the clamp attribute. Its use is deprecated." + import warnings + warnings.warn('Use of the _clamp attribute is deprecated. ' + 'Please use clamp instead.', + DeprecationWarning) + self.clamp = clamp + + # don't bother with _del_clamp; no sane 3rd party code should + # be deleting the _clamp attribute + _clamp = property(_get_clamp, _set_clamp) + def _raise_error(self, condition, explanation = None, *args): """Handles an error If the flag is in _ignored_flags, returns the default response. Otherwise, it sets the flag, then, if the corresponding - trap_enabler is set, it reaises the exception. Otherwise, it returns + trap_enabler is set, it reraises the exception. Otherwise, it returns the default value after setting the flag. """ error = _condition_map.get(condition, condition) @@ -3965,7 +3961,7 @@ "permitted.") d = Decimal(num, context=self) - if d._isnan() and len(d._int) > self.prec - self._clamp: + if d._isnan() and len(d._int) > self.prec - self.clamp: return self._raise_error(ConversionSyntax, "diagnostic info too long in NaN") return d._fix(self) @@ -5875,7 +5871,8 @@ flags=[], Emax=999999999, Emin=-999999999, - capitals=1 + capitals=1, + clamp=0 ) # Pre-made alternate contexts offered by the specification @@ -6194,6 +6191,17 @@ # _SignedInfinity[sign] is infinity w/ that sign _SignedInfinity = (_Infinity, _NegativeInfinity) +# Constants related to the hash implementation; hash(x) is based +# on the reduction of x modulo _PyHASH_MODULUS +import sys +_PyHASH_MODULUS = sys.hash_info.modulus +# hash values to use for positive and negative infinities, and nans +_PyHASH_INF = sys.hash_info.inf +_PyHASH_NAN = sys.hash_info.nan +del sys + +# _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS +_PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS) if __name__ == '__main__': Modified: python/branches/py3k-cdecimal/Lib/distutils/log.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/distutils/log.py (original) +++ python/branches/py3k-cdecimal/Lib/distutils/log.py Mon Jun 7 12:46:02 2010 @@ -27,6 +27,10 @@ stream = sys.stderr else: stream = sys.stdout + if stream.errors == 'strict': + # emulate backslashreplace error handler + encoding = stream.encoding + msg = msg.encode(encoding, "backslashreplace").decode(encoding) stream.write('%s\n' % msg) stream.flush() Modified: python/branches/py3k-cdecimal/Lib/distutils/unixccompiler.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/distutils/unixccompiler.py (original) +++ python/branches/py3k-cdecimal/Lib/distutils/unixccompiler.py Mon Jun 7 12:46:02 2010 @@ -15,7 +15,7 @@ __revision__ = "$Id$" -import os, sys +import os, sys, re from distutils.dep_util import newer from distutils.ccompiler import \ @@ -320,10 +320,31 @@ dylib_f = self.library_filename(lib, lib_type='dylib') static_f = self.library_filename(lib, lib_type='static') + if sys.platform == 'darwin': + # On OSX users can specify an alternate SDK using + # '-isysroot', calculate the SDK root if it is specified + # (and use it further on) + _sysconfig = __import__('sysconfig') + cflags = _sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + + + for dir in dirs: shared = os.path.join(dir, shared_f) dylib = os.path.join(dir, dylib_f) static = os.path.join(dir, static_f) + + if sys.platform == 'darwin' and ( + dir.startswith('/System/') or dir.startswith('/usr/')): + shared = os.path.join(sysroot, dir[1:], shared_f) + dylib = os.path.join(sysroot, dir[1:], dylib_f) + static = os.path.join(sysroot, dir[1:], static_f) + # We're second-guessing the linker here, with not much hard # data to go on: GCC seems to prefer the shared library, so I'm # assuming that *all* Unix C compilers do. And of course I'm Modified: python/branches/py3k-cdecimal/Lib/email/charset.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/email/charset.py (original) +++ python/branches/py3k-cdecimal/Lib/email/charset.py Mon Jun 7 12:46:02 2010 @@ -377,6 +377,8 @@ """ # 7bit/8bit encodings return the string unchanged (module conversions) if self.body_encoding is BASE64: + if isinstance(string, str): + string = string.encode(self.output_charset) return email.base64mime.body_encode(string) elif self.body_encoding is QP: return email.quoprimime.body_encode(string) Modified: python/branches/py3k-cdecimal/Lib/email/encoders.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/email/encoders.py (original) +++ python/branches/py3k-cdecimal/Lib/email/encoders.py Mon Jun 7 12:46:02 2010 @@ -29,7 +29,7 @@ Also, add an appropriate Content-Transfer-Encoding header. """ orig = msg.get_payload() - encdata = _bencode(orig) + encdata = str(_bencode(orig), 'ascii') msg.set_payload(encdata) msg['Content-Transfer-Encoding'] = 'base64' Modified: python/branches/py3k-cdecimal/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/email/test/test_email.py (original) +++ python/branches/py3k-cdecimal/Lib/email/test/test_email.py Mon Jun 7 12:46:02 2010 @@ -535,7 +535,7 @@ # whose output character set is 7bit gets a transfer-encoding # of 7bit. eq = self.assertEqual - msg = MIMEText('\xca\xb8', _charset='euc-jp') + msg = MIMEText('?', _charset='euc-jp') eq(msg['content-transfer-encoding'], '7bit') @@ -970,7 +970,8 @@ def test_encoding(self): payload = self._au.get_payload() - self.assertEqual(base64.decodebytes(payload), self._audiodata) + self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), + self._audiodata) def test_checkSetMinor(self): au = MIMEAudio(self._audiodata, 'fish') @@ -1010,7 +1011,8 @@ def test_encoding(self): payload = self._im.get_payload() - self.assertEqual(base64.decodebytes(payload), self._imgdata) + self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), + self._imgdata) def test_checkSetMinor(self): im = MIMEImage(self._imgdata, 'fish') @@ -1050,7 +1052,7 @@ eq = self.assertEqual bytes = b'\xfa\xfb\xfc\xfd\xfe\xff' msg = MIMEApplication(bytes) - eq(msg.get_payload(), b'+vv8/f7/') + eq(msg.get_payload(), '+vv8/f7/') eq(msg.get_payload(decode=True), bytes) @@ -1080,6 +1082,33 @@ eq(msg.get_charset().input_charset, 'us-ascii') eq(msg['content-type'], 'text/plain; charset="us-ascii"') + def test_7bit_input(self): + eq = self.assertEqual + msg = MIMEText('hello there', _charset='us-ascii') + eq(msg.get_charset().input_charset, 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + + def test_7bit_input_no_charset(self): + eq = self.assertEqual + msg = MIMEText('hello there') + eq(msg.get_charset(), 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + self.assertTrue('hello there' in msg.as_string()) + + def test_utf8_input(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + eq = self.assertEqual + msg = MIMEText(teststr, _charset='utf-8') + eq(msg.get_charset().output_charset, 'utf-8') + eq(msg['content-type'], 'text/plain; charset="utf-8"') + eq(msg.get_payload(decode=True), teststr.encode('utf-8')) + + @unittest.skip("can't fix because of backward compat in email5, " + "will fix in email6") + def test_utf8_input_no_charset(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + self.assertRaises(UnicodeEncodeError, MIMEText, teststr) + # Test complicated multipart/* messages Modified: python/branches/py3k-cdecimal/Lib/encodings/utf_16.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/encodings/utf_16.py (original) +++ python/branches/py3k-cdecimal/Lib/encodings/utf_16.py Mon Jun 7 12:46:02 2010 @@ -103,17 +103,23 @@ class StreamWriter(codecs.StreamWriter): def __init__(self, stream, errors='strict'): - self.bom_written = False codecs.StreamWriter.__init__(self, stream, errors) + self.encoder = None + + def reset(self): + codecs.StreamWriter.reset(self) + self.encoder = None def encode(self, input, errors='strict'): - self.bom_written = True - result = codecs.utf_16_encode(input, errors) - if sys.byteorder == 'little': - self.encode = codecs.utf_16_le_encode + if self.encoder is None: + result = codecs.utf_16_encode(input, errors) + if sys.byteorder == 'little': + self.encoder = codecs.utf_16_le_encode + else: + self.encoder = codecs.utf_16_be_encode + return result else: - self.encode = codecs.utf_16_be_encode - return result + return self.encoder(input, errors) class StreamReader(codecs.StreamReader): Modified: python/branches/py3k-cdecimal/Lib/encodings/utf_32.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/encodings/utf_32.py (original) +++ python/branches/py3k-cdecimal/Lib/encodings/utf_32.py Mon Jun 7 12:46:02 2010 @@ -98,17 +98,23 @@ class StreamWriter(codecs.StreamWriter): def __init__(self, stream, errors='strict'): - self.bom_written = False + self.encoder = None codecs.StreamWriter.__init__(self, stream, errors) + def reset(self): + codecs.StreamWriter.reset(self) + self.encoder = None + def encode(self, input, errors='strict'): - self.bom_written = True - result = codecs.utf_32_encode(input, errors) - if sys.byteorder == 'little': - self.encode = codecs.utf_32_le_encode + if self.encoder is None: + result = codecs.utf_32_encode(input, errors) + if sys.byteorder == 'little': + self.encoder = codecs.utf_32_le_encode + else: + self.encoder = codecs.utf_32_be_encode + return result else: - self.encode = codecs.utf_32_be_encode - return result + return self.encoder(input, errors) class StreamReader(codecs.StreamReader): Modified: python/branches/py3k-cdecimal/Lib/fractions.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/fractions.py (original) +++ python/branches/py3k-cdecimal/Lib/fractions.py Mon Jun 7 12:46:02 2010 @@ -8,6 +8,7 @@ import numbers import operator import re +import sys __all__ = ['Fraction', 'gcd'] @@ -23,6 +24,12 @@ a, b = b, a%b return a +# Constants related to the hash implementation; hash(x) is based +# on the reduction of x modulo the prime _PyHASH_MODULUS. +_PyHASH_MODULUS = sys.hash_info.modulus +# Value to be used for rationals that reduce to infinity modulo +# _PyHASH_MODULUS. +_PyHASH_INF = sys.hash_info.inf _RATIONAL_FORMAT = re.compile(r""" \A\s* # optional whitespace at the start, then @@ -528,16 +535,22 @@ """ # XXX since this method is expensive, consider caching the result - if self._denominator == 1: - # Get integers right. - return hash(self._numerator) - # Expensive check, but definitely correct. - if self == float(self): - return hash(float(self)) + + # In order to make sure that the hash of a Fraction agrees + # with the hash of a numerically equal integer, float or + # Decimal instance, we follow the rules for numeric hashes + # outlined in the documentation. (See library docs, 'Built-in + # Types'). + + # dinv is the inverse of self._denominator modulo the prime + # _PyHASH_MODULUS, or 0 if self._denominator is divisible by + # _PyHASH_MODULUS. + dinv = pow(self._denominator, _PyHASH_MODULUS - 2, _PyHASH_MODULUS) + if not dinv: + hash_ = _PyHASH_INF else: - # Use tuple's hash to avoid a high collision rate on - # simple fractions. - return hash((self._numerator, self._denominator)) + hash_ = abs(self._numerator) * dinv % _PyHASH_MODULUS + return hash_ if self >= 0 else -hash_ def __eq__(a, b): """a == b""" Modified: python/branches/py3k-cdecimal/Lib/ftplib.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/ftplib.py (original) +++ python/branches/py3k-cdecimal/Lib/ftplib.py Mon Jun 7 12:46:02 2010 @@ -638,9 +638,17 @@ ssl_version = ssl.PROTOCOL_TLSv1 def __init__(self, host='', user='', passwd='', acct='', keyfile=None, - certfile=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): + certfile=None, context=None, + timeout=_GLOBAL_DEFAULT_TIMEOUT): + if context is not None and keyfile is not None: + raise ValueError("context and keyfile arguments are mutually " + "exclusive") + if context is not None and certfile is not None: + raise ValueError("context and certfile arguments are mutually " + "exclusive") self.keyfile = keyfile self.certfile = certfile + self.context = context self._prot_p = False FTP.__init__(self, host, user, passwd, acct, timeout) @@ -657,8 +665,12 @@ resp = self.voidcmd('AUTH TLS') else: resp = self.voidcmd('AUTH SSL') - self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, - ssl_version=self.ssl_version) + if self.context is not None: + self.sock = self.context.wrap_socket(self.sock) + else: + self.sock = ssl.wrap_socket(self.sock, self.keyfile, + self.certfile, + ssl_version=self.ssl_version) self.file = self.sock.makefile(mode='r', encoding=self.encoding) return resp @@ -689,8 +701,11 @@ def ntransfercmd(self, cmd, rest=None): conn, size = FTP.ntransfercmd(self, cmd, rest) if self._prot_p: - conn = ssl.wrap_socket(conn, self.keyfile, self.certfile, - ssl_version=self.ssl_version) + if self.context is not None: + conn = self.context.wrap_socket(conn) + else: + conn = ssl.wrap_socket(conn, self.keyfile, self.certfile, + ssl_version=self.ssl_version) return conn, size def retrbinary(self, cmd, callback, blocksize=8192, rest=None): Modified: python/branches/py3k-cdecimal/Lib/functools.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/functools.py (original) +++ python/branches/py3k-cdecimal/Lib/functools.py Mon Jun 7 12:46:02 2010 @@ -51,7 +51,7 @@ assigned=assigned, updated=updated) def total_ordering(cls): - 'Class decorator that fills-in missing ordering methods' + """Class decorator that fills in missing ordering methods""" convert = { '__lt__': [('__gt__', lambda self, other: other < self), ('__le__', lambda self, other: not other < self), @@ -78,7 +78,7 @@ return cls def cmp_to_key(mycmp): - 'Convert a cmp= function into a key= function' + """Convert a cmp= function into a key= function""" class K(object): def __init__(self, obj, *args): self.obj = obj Modified: python/branches/py3k-cdecimal/Lib/html/parser.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/html/parser.py (original) +++ python/branches/py3k-cdecimal/Lib/html/parser.py Mon Jun 7 12:46:02 2010 @@ -175,6 +175,9 @@ i = self.updatepos(i, k) continue else: + if ";" in rawdata[i:]: #bail by consuming &# + self.handle_data(rawdata[0:2]) + i = self.updatepos(i, 2) break elif startswith('&', i): match = entityref.match(rawdata, i) Modified: python/branches/py3k-cdecimal/Lib/http/client.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/http/client.py (original) +++ python/branches/py3k-cdecimal/Lib/http/client.py Mon Jun 7 12:46:02 2010 @@ -488,6 +488,7 @@ return b"" if self._method == "HEAD": + self.close() return b"" if self.chunked: Modified: python/branches/py3k-cdecimal/Lib/lib2to3/refactor.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/lib2to3/refactor.py (original) +++ python/branches/py3k-cdecimal/Lib/lib2to3/refactor.py Mon Jun 7 12:46:02 2010 @@ -564,7 +564,9 @@ This is necessary to get correct line number / offset information in the parser diagnostics and embedded into the parse tree. """ - return self.driver.parse_tokens(self.wrap_toks(block, lineno, indent)) + tree = self.driver.parse_tokens(self.wrap_toks(block, lineno, indent)) + tree.future_features = frozenset() + return tree def wrap_toks(self, block, lineno, indent): """Wraps a tokenize stream to systematically modify start/end.""" Modified: python/branches/py3k-cdecimal/Lib/linecache.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/linecache.py (original) +++ python/branches/py3k-cdecimal/Lib/linecache.py Mon Jun 7 12:46:02 2010 @@ -73,13 +73,13 @@ if filename in cache: del cache[filename] - if not filename or filename[0] + filename[-1] == '<>': + if not filename or (filename.startswith('<') and filename.endswith('>')): return [] fullname = filename try: stat = os.stat(fullname) - except os.error as msg: + except OSError: basename = filename # Try for a __loader__, if available @@ -114,20 +114,23 @@ fullname = os.path.join(dirname, basename) except (TypeError, AttributeError): # Not sufficiently string-like to do anything useful with. + continue + try: + stat = os.stat(fullname) + break + except os.error: pass - else: - try: - stat = os.stat(fullname) - break - except os.error: - pass else: - # No luck return [] - with open(fullname, 'rb') as fp: - coding, line = tokenize.detect_encoding(fp.readline) - with open(fullname, 'r', encoding=coding) as fp: - lines = fp.readlines() + try: + with open(fullname, 'rb') as fp: + coding, line = tokenize.detect_encoding(fp.readline) + with open(fullname, 'r', encoding=coding) as fp: + lines = fp.readlines() + except IOError: + pass + if lines and not lines[-1].endswith('\n'): + lines[-1] += '\n' size, mtime = stat.st_size, stat.st_mtime cache[filename] = size, mtime, lines, fullname return lines Modified: python/branches/py3k-cdecimal/Lib/pipes.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/pipes.py (original) +++ python/branches/py3k-cdecimal/Lib/pipes.py Mon Jun 7 12:46:02 2010 @@ -249,11 +249,11 @@ # Reliably quote a string as a single argument for /bin/sh -_safechars = string.ascii_letters + string.digits + '!@%_-+=:,./' # Safe unquoted -_funnychars = '"`$\\' # Unsafe inside "double quotes" +# Safe unquoted +_safechars = frozenset(string.ascii_letters + string.digits + '@%_-+=:,./') def quote(file): - ''' return a shell-escaped version of the file string ''' + """Return a shell-escaped version of the file string.""" for c in file: if c not in _safechars: break @@ -261,11 +261,6 @@ if not file: return "''" return file - if '\'' not in file: - return '\'' + file + '\'' - res = '' - for c in file: - if c in _funnychars: - c = '\\' + c - res = res + c - return '"' + res + '"' + # use single quotes, and put single quotes into double quotes + # the string $'b is then quoted as '$'"'"'b' + return "'" + file.replace("'", "'\"'\"'") + "'" Modified: python/branches/py3k-cdecimal/Lib/sqlite3/test/dbapi.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/sqlite3/test/dbapi.py (original) +++ python/branches/py3k-cdecimal/Lib/sqlite3/test/dbapi.py Mon Jun 7 12:46:02 2010 @@ -84,6 +84,7 @@ "NotSupportedError is not a subclass of DatabaseError") class ConnectionTests(unittest.TestCase): + def setUp(self): self.cx = sqlite.connect(":memory:") cu = self.cx.cursor() @@ -140,6 +141,28 @@ self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError) self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError) + def CheckInTransaction(self): + # Can't use db from setUp because we want to test initial state. + cx = sqlite.connect(":memory:") + cu = cx.cursor() + self.assertEqual(cx.in_transaction, False) + cu.execute("create table transactiontest(id integer primary key, name text)") + self.assertEqual(cx.in_transaction, False) + cu.execute("insert into transactiontest(name) values (?)", ("foo",)) + self.assertEqual(cx.in_transaction, True) + cu.execute("select name from transactiontest where name=?", ["foo"]) + row = cu.fetchone() + self.assertEqual(cx.in_transaction, True) + cx.commit() + self.assertEqual(cx.in_transaction, False) + cu.execute("select name from transactiontest where name=?", ["foo"]) + row = cu.fetchone() + self.assertEqual(cx.in_transaction, False) + + def CheckInTransactionRO(self): + with self.assertRaises(AttributeError): + self.cx.in_transaction = True + class CursorTests(unittest.TestCase): def setUp(self): self.cx = sqlite.connect(":memory:") Modified: python/branches/py3k-cdecimal/Lib/ssl.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/ssl.py (original) +++ python/branches/py3k-cdecimal/Lib/ssl.py Mon Jun 7 12:46:02 2010 @@ -63,6 +63,7 @@ from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED from _ssl import (PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1) +from _ssl import OP_ALL, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1 from _ssl import RAND_status, RAND_egd, RAND_add from _ssl import ( SSL_ERROR_ZERO_RETURN, Modified: python/branches/py3k-cdecimal/Lib/subprocess.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/subprocess.py (original) +++ python/branches/py3k-cdecimal/Lib/subprocess.py Mon Jun 7 12:46:02 2010 @@ -843,7 +843,7 @@ # Process startup details if startupinfo is None: startupinfo = STARTUPINFO() - if None not in (p2cread, c2pwrite, errwrite): + if -1 not in (p2cread, c2pwrite, errwrite): startupinfo.dwFlags |= _subprocess.STARTF_USESTDHANDLES startupinfo.hStdInput = p2cread startupinfo.hStdOutput = c2pwrite Modified: python/branches/py3k-cdecimal/Lib/sysconfig.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/sysconfig.py (original) +++ python/branches/py3k-cdecimal/Lib/sysconfig.py Mon Jun 7 12:46:02 2010 @@ -5,6 +5,10 @@ import os from os.path import pardir, realpath +__all__ = ['parse_config_h', 'get_config_h_filename', 'get_scheme_names', + 'get_path_names', 'get_paths', 'get_path', 'get_config_vars', + 'get_config_var', 'get_platform', 'get_python_version'] + _INSTALL_SCHEMES = { 'posix_prefix': { 'stdlib': '{base}/lib/python{py_version_short}', @@ -47,10 +51,10 @@ 'data' : '{base}', }, 'os2_home': { - 'stdlib': '{userbase}/lib/python/{py_version_short}', - 'platstdlib': '{userbase}/lib/python/{py_version_short}', - 'purelib': '{userbase}/lib/python/{py_version_short}/site-packages', - 'platlib': '{userbase}/lib/python/{py_version_short}/site-packages', + 'stdlib': '{userbase}/lib/python{py_version_short}', + 'platstdlib': '{userbase}/lib/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', + 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', 'include': '{userbase}/include/python{py_version_short}', 'scripts': '{userbase}/bin', 'data' : '{userbase}', @@ -65,10 +69,10 @@ 'data' : '{userbase}', }, 'posix_user': { - 'stdlib': '{userbase}/lib/python/{py_version_short}', - 'platstdlib': '{userbase}/lib/python/{py_version_short}', - 'purelib': '{userbase}/lib/python/{py_version_short}/site-packages', - 'platlib': '{userbase}/lib/python/{py_version_short}/site-packages', + 'stdlib': '{userbase}/lib/python{py_version_short}', + 'platstdlib': '{userbase}/lib/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', + 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', 'include': '{userbase}/include/python{py_version_short}', 'scripts': '{userbase}/bin', 'data' : '{userbase}', @@ -686,3 +690,22 @@ def get_python_version(): return _PY_VERSION_SHORT + +def _print_dict(title, data): + for index, (key, value) in enumerate(sorted(data.items())): + if index == 0: + print('{0}: '.format(title)) + print('\t{0} = "{1}"'.format(key, value)) + +def _main(): + """Displays all information sysconfig detains.""" + print('Platform: "{0}"'.format(get_platform())) + print('Python version: "{0}"'.format(get_python_version())) + print('Current installation scheme: "{0}"'.format(_get_default_scheme())) + print('') + _print_dict('Paths', get_paths()) + print('') + _print_dict('Variables', get_config_vars()) + +if __name__ == '__main__': + _main() Modified: python/branches/py3k-cdecimal/Lib/tabnanny.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/tabnanny.py (original) +++ python/branches/py3k-cdecimal/Lib/tabnanny.py Mon Jun 7 12:46:02 2010 @@ -93,8 +93,11 @@ check(fullname) return + with open(file, 'rb') as f: + encoding, lines = tokenize.detect_encoding(f.readline) + try: - f = open(file) + f = open(file, encoding=encoding) except IOError as msg: errprint("%r: I/O Error: %s" % (file, msg)) return Modified: python/branches/py3k-cdecimal/Lib/tarfile.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/tarfile.py (original) +++ python/branches/py3k-cdecimal/Lib/tarfile.py Mon Jun 7 12:46:02 2010 @@ -1920,7 +1920,7 @@ tarinfo.mode = stmd tarinfo.uid = statres.st_uid tarinfo.gid = statres.st_gid - if stat.S_ISREG(stmd): + if type == REGTYPE: tarinfo.size = statres.st_size else: tarinfo.size = 0 @@ -2163,8 +2163,7 @@ raise StreamError("cannot extract (sym)link as file object") else: # A (sym)link's file object is its target's file object. - return self.extractfile(self._getmember(tarinfo.linkname, - tarinfo)) + return self.extractfile(self._find_link_target(tarinfo)) else: # If there's no data associated with the member (directory, chrdev, # blkdev, etc.), return None instead of a file object. @@ -2273,27 +2272,21 @@ (platform limitation), we try to make a copy of the referenced file instead of a link. """ - try: + if hasattr(os, "symlink") and hasattr(os, "link"): + # For systems that support symbolic and hard links. if tarinfo.issym(): os.symlink(tarinfo.linkname, targetpath) else: # See extract(). - os.link(tarinfo._link_target, targetpath) - except AttributeError: - if tarinfo.issym(): - linkpath = os.path.dirname(tarinfo.name) + "/" + \ - tarinfo.linkname - else: - linkpath = tarinfo.linkname - + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), targetpath) + else: try: - self._extract_member(self.getmember(linkpath), targetpath) - except (EnvironmentError, KeyError) as e: - linkpath = linkpath.replace("/", os.sep) - try: - shutil.copy2(linkpath, targetpath) - except EnvironmentError as e: - raise IOError("link could not be created") + self._extract_member(self._find_link_target(tarinfo), targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") def chown(self, tarinfo, targetpath): """Set owner of targetpath according to tarinfo. @@ -2392,21 +2385,28 @@ #-------------------------------------------------------------------------- # Little helper methods: - def _getmember(self, name, tarinfo=None): + def _getmember(self, name, tarinfo=None, normalize=False): """Find an archive member by name from bottom to top. If tarinfo is given, it is used as the starting point. """ # Ensure that all members have been loaded. members = self.getmembers() - if tarinfo is None: - end = len(members) - else: - end = members.index(tarinfo) + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] - for i in range(end - 1, -1, -1): - if name == members[i].name: - return members[i] + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member def _load(self): """Read through the entire archive file and look for readable @@ -2427,6 +2427,25 @@ if mode is not None and self.mode not in mode: raise IOError("bad operation for mode %r" % self.mode) + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + def __iter__(self): """Provide an iterator object. """ Modified: python/branches/py3k-cdecimal/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/regrtest.py (original) +++ python/branches/py3k-cdecimal/Lib/test/regrtest.py Mon Jun 7 12:46:02 2010 @@ -258,6 +258,8 @@ on the command line. """ + replace_stdout() + support.record_original_stdout(sys.stdout) try: opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:nj:', @@ -376,7 +378,6 @@ elif o in ('-j', '--multiprocess'): use_mp = int(a) elif o == '--slaveargs': - replace_stdout() args, kwargs = json.loads(a) try: result = runtest(*args, **kwargs) @@ -515,8 +516,6 @@ else: tests = iter(selected) - replace_stdout() - if use_mp: try: from threading import Thread Modified: python/branches/py3k-cdecimal/Lib/test/test_argparse.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_argparse.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_argparse.py Mon Jun 7 12:46:02 2010 @@ -3688,6 +3688,25 @@ ''' version = '' +class TestHelpVersionAction(HelpTestCase): + """Test the default help for the version action""" + + parser_signature = Sig(prog='PROG', description='description') + argument_signatures = [Sig('-V', '--version', action='version', version='3.6')] + argument_group_signatures = [] + usage = '''\ + usage: PROG [-h] [-V] + ''' + help = usage + '''\ + + description + + optional arguments: + -h, --help show this help message and exit + -V, --version show program's version number and exit + ''' + version = '' + # ===================================== # Optional/Positional constructor tests # ===================================== Modified: python/branches/py3k-cdecimal/Lib/test/test_base64.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_base64.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_base64.py Mon Jun 7 12:46:02 2010 @@ -2,6 +2,8 @@ from test import support import base64 import binascii +import sys +import subprocess @@ -208,6 +210,38 @@ +class TestMain(unittest.TestCase): + def get_output(self, *args, **options): + args = (sys.executable, '-m', 'base64') + args + return subprocess.check_output(args, **options) + + def test_encode_decode(self): + output = self.get_output('-t') + self.assertSequenceEqual(output.splitlines(), ( + b"b'Aladdin:open sesame'", + br"b'QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n'", + b"b'Aladdin:open sesame'", + )) + + def test_encode_file(self): + with open(support.TESTFN, 'wb') as fp: + fp.write(b'a\xffb\n') + + output = self.get_output('-e', support.TESTFN) + self.assertEquals(output.rstrip(), b'Yf9iCg==') + + with open(support.TESTFN, 'rb') as fp: + output = self.get_output('-e', stdin=fp) + self.assertEquals(output.rstrip(), b'Yf9iCg==') + + def test_decode(self): + with open(support.TESTFN, 'wb') as fp: + fp.write(b'Yf9iCg==') + output = self.get_output('-d', support.TESTFN) + self.assertEquals(output.rstrip(), b'a\xffb') + + + def test_main(): support.run_unittest(__name__) Modified: python/branches/py3k-cdecimal/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_builtin.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_builtin.py Mon Jun 7 12:46:02 2010 @@ -124,6 +124,16 @@ self.assertEqual(abs(-3.14), 3.14) # str self.assertRaises(TypeError, abs, 'a') + # bool + self.assertEqual(abs(True), 1) + self.assertEqual(abs(False), 0) + # other + self.assertRaises(TypeError, abs) + self.assertRaises(TypeError, abs, None) + class AbsClass(object): + def __abs__(self): + return -5 + self.assertEqual(abs(AbsClass()), -5) def test_all(self): self.assertEqual(all([2, 4, 6]), True) @@ -600,6 +610,8 @@ def __len__(self): return sys.maxsize + 1 self.assertRaises(OverflowError, len, HugeLen()) + class NoLenMethod(object): pass + self.assertRaises(TypeError, len, NoLenMethod()) def test_map(self): self.assertEqual( @@ -1187,6 +1199,11 @@ b = 2 return vars() + class C_get_vars(object): + def getDict(self): + return {'a':2} + __dict__ = property(fget=getDict) + def test_vars(self): self.assertEqual(set(vars()), set(dir())) import sys @@ -1195,6 +1212,7 @@ self.assertEqual(self.get_vars_f2(), {'a': 1, 'b': 2}) self.assertRaises(TypeError, vars, 42, 42) self.assertRaises(TypeError, vars, 42) + self.assertEqual(vars(self.C_get_vars()), {'a':2}) def test_zip(self): a = (1, 2, 3) Modified: python/branches/py3k-cdecimal/Lib/test/test_codecs.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_codecs.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_codecs.py Mon Jun 7 12:46:02 2010 @@ -1594,6 +1594,62 @@ b"\xe4\xeb\xef\xf6\xfc") +class BomTest(unittest.TestCase): + def test_seek0(self): + data = "1234567890" + tests = ("utf-16", + "utf-16-le", + "utf-16-be", + "utf-32", + "utf-32-le", + "utf-32-be") + for encoding in tests: + # Check if the BOM is written only once + with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + f.write(data) + f.write(data) + f.seek(0) + self.assertEquals(f.read(), data * 2) + f.seek(0) + self.assertEquals(f.read(), data * 2) + + # Check that the BOM is written after a seek(0) + with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + f.write(data[0]) + self.assertNotEquals(f.tell(), 0) + f.seek(0) + f.write(data) + f.seek(0) + self.assertEquals(f.read(), data) + + # (StreamWriter) Check that the BOM is written after a seek(0) + with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + f.writer.write(data[0]) + self.assertNotEquals(f.writer.tell(), 0) + f.writer.seek(0) + f.writer.write(data) + f.seek(0) + self.assertEquals(f.read(), data) + + # Check that the BOM is not written after a seek() at a position + # different than the start + with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + f.write(data) + f.seek(f.tell()) + f.write(data) + f.seek(0) + self.assertEquals(f.read(), data * 2) + + # (StreamWriter) Check that the BOM is not written after a seek() + # at a position different than the start + with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: + f.writer.write(data) + f.writer.seek(f.writer.tell()) + f.writer.write(data) + f.seek(0) + self.assertEquals(f.read(), data * 2) + + def test_main(): support.run_unittest( UTF32Test, @@ -1621,6 +1677,7 @@ WithStmtTest, TypesTest, SurrogateEscapeTest, + BomTest, ) Modified: python/branches/py3k-cdecimal/Lib/test/test_collections.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_collections.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_collections.py Mon Jun 7 12:46:02 2010 @@ -1,6 +1,6 @@ """Unit tests for collections.py.""" -import unittest, doctest +import unittest, doctest, operator import inspect from test import support from collections import namedtuple, Counter, OrderedDict @@ -246,6 +246,37 @@ self.assertNotIsInstance(C(), abc) self.assertFalse(issubclass(C, abc)) + def validate_comparison(self, instance): + ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] + operators = {} + for op in ops: + name = '__' + op + '__' + operators[name] = getattr(operator, name) + + class Other: + def __init__(self): + self.right_side = False + def __eq__(self, other): + self.right_side = True + return True + __lt__ = __eq__ + __gt__ = __eq__ + __le__ = __eq__ + __ge__ = __eq__ + __ne__ = __eq__ + __ror__ = __eq__ + __rand__ = __eq__ + __rxor__ = __eq__ + __rsub__ = __eq__ + + for name, op in operators.items(): + if not hasattr(instance, name): + continue + other = Other() + op(instance, other) + self.assertTrue(other.right_side,'Right side not called for %s.%s' + % (type(instance), name)) + class TestOneTrickPonyABCs(ABCTestCase): def test_Hashable(self): @@ -420,6 +451,14 @@ self.assertIsInstance(sample(), Set) self.assertTrue(issubclass(sample, Set)) self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') + class MySet(Set): + def __contains__(self, x): + return False + def __len__(self): + return 0 + def __iter__(self): + return iter([]) + self.validate_comparison(MySet()) def test_hash_Set(self): class OneTwoThreeSet(Set): @@ -483,6 +522,14 @@ self.assertTrue(issubclass(sample, Mapping)) self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', '__getitem__') + class MyMapping(collections.Mapping): + def __len__(self): + return 0 + def __getitem__(self, i): + raise IndexError + def __iter__(self): + return iter(()) + self.validate_comparison(MyMapping()) def test_MutableMapping(self): for sample in [dict]: Modified: python/branches/py3k-cdecimal/Lib/test/test_complex.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_complex.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_complex.py Mon Jun 7 12:46:02 2010 @@ -110,12 +110,18 @@ self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 0+0j) def test_richcompare(self): - self.assertRaises(OverflowError, complex.__eq__, 1+1j, 1<<10000) + self.assertIs(complex.__eq__(1+1j, 1<<10000), False) self.assertIs(complex.__lt__(1+1j, None), NotImplemented) self.assertIs(complex.__eq__(1+1j, 1+1j), True) self.assertIs(complex.__eq__(1+1j, 2+2j), False) self.assertIs(complex.__ne__(1+1j, 1+1j), False) self.assertIs(complex.__ne__(1+1j, 2+2j), True) + for i in range(1, 100): + f = i / 100.0 + self.assertIs(complex.__eq__(f+0j, f), True) + self.assertIs(complex.__ne__(f+0j, f), False) + self.assertIs(complex.__eq__(complex(f, f), f), False) + self.assertIs(complex.__ne__(complex(f, f), f), True) self.assertIs(complex.__lt__(1+1j, 2+2j), NotImplemented) self.assertIs(complex.__le__(1+1j, 2+2j), NotImplemented) self.assertIs(complex.__gt__(1+1j, 2+2j), NotImplemented) @@ -129,6 +135,23 @@ self.assertIs(operator.ne(1+1j, 1+1j), False) self.assertIs(operator.ne(1+1j, 2+2j), True) + def test_richcompare_boundaries(self): + def check(n, deltas, is_equal, imag = 0.0): + for delta in deltas: + i = n + delta + z = complex(i, imag) + self.assertIs(complex.__eq__(z, i), is_equal(delta)) + self.assertIs(complex.__ne__(z, i), not is_equal(delta)) + # For IEEE-754 doubles the following should hold: + # x in [2 ** (52 + i), 2 ** (53 + i + 1)] -> x mod 2 ** i == 0 + # where the interval is representable, of course. + for i in range(1, 10): + pow = 52 + i + mult = 2 ** i + check(2 ** pow, range(1, 101), lambda delta: delta % mult == 0) + check(2 ** pow, range(1, 101), lambda delta: False, float(i)) + check(2 ** 53, range(-100, 0), lambda delta: True) + def test_mod(self): # % is no longer supported on complex numbers self.assertRaises(TypeError, (1+1j).__mod__, 0+0j) Modified: python/branches/py3k-cdecimal/Lib/test/test_datetime.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_datetime.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_datetime.py Mon Jun 7 12:46:02 2010 @@ -3,7 +3,7 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ -import os +import sys import pickle import unittest @@ -25,6 +25,16 @@ OTHERSTUFF = (10, 34.5, "abc", {}, [], ()) +# XXX Copied from test_float. +INF = float("inf") +NAN = float("nan") + +# decorator for skipping tests on non-IEEE 754 platforms +requires_IEEE_754 = unittest.skipUnless( + float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + + ############################################################################# # module tests @@ -225,6 +235,36 @@ eq(c//1000, td(0, 0, 1)) eq(a//10, td(0, 7*24*360)) eq(a//3600000, td(0, 0, 7*24*1000)) + eq(a/0.5, td(14)) + eq(b/0.5, td(0, 120)) + eq(a/7, td(1)) + eq(b/10, td(0, 6)) + eq(c/1000, td(0, 0, 1)) + eq(a/10, td(0, 7*24*360)) + eq(a/3600000, td(0, 0, 7*24*1000)) + + # Multiplication by float + us = td(microseconds=1) + eq((3*us) * 0.5, 2*us) + eq((5*us) * 0.5, 2*us) + eq(0.5 * (3*us), 2*us) + eq(0.5 * (5*us), 2*us) + eq((-3*us) * 0.5, -2*us) + eq((-5*us) * 0.5, -2*us) + + # Division by int and float + eq((3*us) / 2, 2*us) + eq((5*us) / 2, 2*us) + eq((-3*us) / 2.0, -2*us) + eq((-5*us) / 2.0, -2*us) + eq((3*us) / -2, -2*us) + eq((5*us) / -2, -2*us) + eq((3*us) / -2.0, -2*us) + eq((5*us) / -2.0, -2*us) + for i in range(-10, 10): + eq((i*us/3)//us, round(i/3)) + for i in range(-10, 10): + eq((i*us/-3)//us, round(i/-3)) def test_disallowed_computations(self): a = timedelta(42) @@ -236,20 +276,19 @@ self.assertRaises(TypeError, lambda: i+a) self.assertRaises(TypeError, lambda: i-a) - # Mul/div by float isn't supported. - x = 2.3 - self.assertRaises(TypeError, lambda: a*x) - self.assertRaises(TypeError, lambda: x*a) - self.assertRaises(TypeError, lambda: a/x) - self.assertRaises(TypeError, lambda: x/a) - self.assertRaises(TypeError, lambda: a // x) - self.assertRaises(TypeError, lambda: x // a) - # Division of int by timedelta doesn't make sense. # Division by zero doesn't make sense. zero = 0 self.assertRaises(TypeError, lambda: zero // a) self.assertRaises(ZeroDivisionError, lambda: a // zero) + self.assertRaises(ZeroDivisionError, lambda: a / zero) + self.assertRaises(ZeroDivisionError, lambda: a / 0.0) + + @requires_IEEE_754 + def test_disallowed_special(self): + a = timedelta(42) + self.assertRaises(ValueError, a.__mul__, NAN) + self.assertRaises(ValueError, a.__truediv__, NAN) def test_basic_attributes(self): days, seconds, us = 1, 7, 31 @@ -410,6 +449,19 @@ self.assertRaises(OverflowError, lambda: -timedelta.max) + day = timedelta(1) + self.assertRaises(OverflowError, day.__mul__, 10**9) + self.assertRaises(OverflowError, day.__mul__, 1e9) + self.assertRaises(OverflowError, day.__truediv__, 1e-20) + self.assertRaises(OverflowError, day.__truediv__, 1e-10) + self.assertRaises(OverflowError, day.__truediv__, 9e-10) + + @requires_IEEE_754 + def _test_overflow_special(self): + day = timedelta(1) + self.assertRaises(OverflowError, day.__mul__, INF) + self.assertRaises(OverflowError, day.__mul__, -INF) + def test_microsecond_rounding(self): td = timedelta eq = self.assertEqual @@ -489,7 +541,7 @@ self.assertRaises(ZeroDivisionError, truediv, t, zerotd) self.assertRaises(ZeroDivisionError, floordiv, t, zerotd) - self.assertRaises(TypeError, truediv, t, 2) + # self.assertRaises(TypeError, truediv, t, 2) # note: floor division of a timedelta by an integer *is* # currently permitted. @@ -761,15 +813,16 @@ def test_overflow(self): tiny = self.theclass.resolution - dt = self.theclass.min + tiny - dt -= tiny # no problem - self.assertRaises(OverflowError, dt.__sub__, tiny) - self.assertRaises(OverflowError, dt.__add__, -tiny) - - dt = self.theclass.max - tiny - dt += tiny # no problem - self.assertRaises(OverflowError, dt.__add__, tiny) - self.assertRaises(OverflowError, dt.__sub__, -tiny) + for delta in [tiny, timedelta(1), timedelta(2)]: + dt = self.theclass.min + delta + dt -= delta # no problem + self.assertRaises(OverflowError, dt.__sub__, delta) + self.assertRaises(OverflowError, dt.__add__, -delta) + + dt = self.theclass.max - delta + dt += delta # no problem + self.assertRaises(OverflowError, dt.__add__, delta) + self.assertRaises(OverflowError, dt.__sub__, -delta) def test_fromtimestamp(self): import time @@ -1554,19 +1607,14 @@ for insane in -1e200, 1e200: self.assertRaises(ValueError, self.theclass.utcfromtimestamp, insane) - + @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_fromtimestamp(self): - # Windows doesn't accept negative timestamps - if os.name == "nt": - return # The result is tz-dependent; at least test that this doesn't # fail (like it did before bug 1646728 was fixed). self.theclass.fromtimestamp(-1.05) + @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_utcfromtimestamp(self): - # Windows doesn't accept negative timestamps - if os.name == "nt": - return d = self.theclass.utcfromtimestamp(-1.05) self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) Modified: python/branches/py3k-cdecimal/Lib/test/test_decimal.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_decimal.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_decimal.py Mon Jun 7 12:46:02 2010 @@ -27,11 +27,13 @@ import math import os, sys import operator +import warnings import pickle, copy import unittest from decimal import * import numbers from test.support import run_unittest, run_doctest, is_resource_enabled +from test.support import check_warnings import random try: import threading @@ -412,7 +414,7 @@ def change_max_exponent(self, exp): self.context.Emax = exp def change_clamp(self, clamp): - self.context._clamp = clamp + self.context.clamp = clamp @@ -1815,6 +1817,26 @@ self.assertNotEqual(id(c.flags), id(d.flags)) self.assertNotEqual(id(c.traps), id(d.traps)) + def test__clamp(self): + # In Python 3.2, the private attribute `_clamp` was made + # public (issue 8540), with the old `_clamp` becoming a + # property wrapping `clamp`. For the duration of Python 3.2 + # only, the attribute should be gettable/settable via both + # `clamp` and `_clamp`; in Python 3.3, `_clamp` should be + # removed. + c = Context(clamp = 0) + self.assertEqual(c.clamp, 0) + + with check_warnings(("", DeprecationWarning)): + c._clamp = 1 + self.assertEqual(c.clamp, 1) + with check_warnings(("", DeprecationWarning)): + self.assertEqual(c._clamp, 1) + c.clamp = 0 + self.assertEqual(c.clamp, 0) + with check_warnings(("", DeprecationWarning)): + self.assertEqual(c._clamp, 0) + def test_abs(self): c = Context() d = c.abs(Decimal(-1)) Modified: python/branches/py3k-cdecimal/Lib/test/test_descr.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_descr.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_descr.py Mon Jun 7 12:46:02 2010 @@ -1557,6 +1557,8 @@ self.assertEqual(key, "hi") return 4 def swallow(*args): pass + def format_impl(self, spec): + return "hello" # It would be nice to have every special method tested here, but I'm # only listing the ones I can remember outside of typeobject.c, since it @@ -1575,6 +1577,7 @@ ("__enter__", run_context, iden, set(), {"__exit__" : swallow}), ("__exit__", run_context, swallow, set(), {"__enter__" : iden}), ("__complex__", complex, complex_num, set(), {}), + ("__format__", format, format_impl, set(), {}), ] class Checker(object): Modified: python/branches/py3k-cdecimal/Lib/test/test_enumerate.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_enumerate.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_enumerate.py Mon Jun 7 12:46:02 2010 @@ -198,6 +198,18 @@ self.fail("non-callable __reversed__ didn't raise!") self.assertEqual(rc, sys.getrefcount(r)) + def test_objmethods(self): + # Objects must have __len__() and __getitem__() implemented. + class NoLen(object): + def __getitem__(self): return 1 + nl = NoLen() + self.assertRaises(TypeError, reversed, nl) + + class NoGetItem(object): + def __len__(self): return 2 + ngi = NoGetItem() + self.assertRaises(TypeError, reversed, ngi) + class EnumerateStartTestCase(EnumerateTestCase): @@ -227,7 +239,7 @@ if verbose and hasattr(sys, "gettotalrefcount"): counts = [None] * 5 for i in range(len(counts)): - support.run_unittest(*testclasses) + support.run_unittest(__name__) counts[i] = sys.gettotalrefcount() print(counts) Modified: python/branches/py3k-cdecimal/Lib/test/test_float.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_float.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_float.py Mon Jun 7 12:46:02 2010 @@ -914,15 +914,6 @@ self.assertFalse(NAN.is_inf()) self.assertFalse((0.).is_inf()) - def test_hash_inf(self): - # the actual values here should be regarded as an - # implementation detail, but they need to be - # identical to those used in the Decimal module. - self.assertEqual(hash(float('inf')), 314159) - self.assertEqual(hash(float('-inf')), -271828) - self.assertEqual(hash(float('nan')), 0) - - fromHex = float.fromhex toHex = float.hex class HexFloatTestCase(unittest.TestCase): Modified: python/branches/py3k-cdecimal/Lib/test/test_ftplib.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_ftplib.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_ftplib.py Mon Jun 7 12:46:02 2010 @@ -719,6 +719,29 @@ finally: self.client.ssl_version = ssl.PROTOCOL_TLSv1 + def test_context(self): + self.client.quit() + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + self.assertRaises(ValueError, ftplib.FTP_TLS, keyfile=CERTFILE, + context=ctx) + self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE, + context=ctx) + self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE, + keyfile=CERTFILE, context=ctx) + + self.client = ftplib.FTP_TLS(context=ctx, timeout=2) + self.client.connect(self.server.host, self.server.port) + self.assertNotIsInstance(self.client.sock, ssl.SSLSocket) + self.client.auth() + self.assertIs(self.client.sock.context, ctx) + self.assertIsInstance(self.client.sock, ssl.SSLSocket) + + self.client.prot_p() + sock = self.client.transfercmd('list') + self.assertIs(sock.context, ctx) + self.assertIsInstance(sock, ssl.SSLSocket) + sock.close() + class TestTimeouts(TestCase): Modified: python/branches/py3k-cdecimal/Lib/test/test_gdb.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_gdb.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_gdb.py Mon Jun 7 12:46:02 2010 @@ -8,6 +8,7 @@ import subprocess import sys import unittest +import locale from test.support import run_unittest, findfile @@ -177,7 +178,7 @@ def assertGdbRepr(self, val, exp_repr=None, cmds_after_breakpoint=None): # Ensure that gdb's rendering of the value in a debugged process # matches repr(value) in this process: - gdb_repr, gdb_output = self.get_gdb_repr('id(' + repr(val) + ')', + gdb_repr, gdb_output = self.get_gdb_repr('id(' + ascii(val) + ')', cmds_after_breakpoint) if not exp_repr: exp_repr = repr(val) @@ -226,31 +227,35 @@ def test_strings(self): 'Verify the pretty-printing of unicode strings' + encoding = locale.getpreferredencoding() + def check_repr(text): + try: + text.encode(encoding) + printable = True + except UnicodeEncodeError: + self.assertGdbRepr(text, ascii(text)) + else: + self.assertGdbRepr(text) + self.assertGdbRepr('') self.assertGdbRepr('And now for something hopefully the same') self.assertGdbRepr('string with embedded NUL here \0 and then some more text') # Test printing a single character: # U+2620 SKULL AND CROSSBONES - self.assertGdbRepr('\u2620') + check_repr('\u2620') # Test printing a Japanese unicode string # (I believe this reads "mojibake", using 3 characters from the CJK # Unified Ideographs area, followed by U+3051 HIRAGANA LETTER KE) - self.assertGdbRepr('\u6587\u5b57\u5316\u3051') + check_repr('\u6587\u5b57\u5316\u3051') # Test a character outside the BMP: # U+1D121 MUSICAL SYMBOL C CLEF # This is: # UTF-8: 0xF0 0x9D 0x84 0xA1 # UTF-16: 0xD834 0xDD21 - if sys.maxunicode == 0x10FFFF: - # wide unicode: - self.assertGdbRepr(chr(0x1D121)) - else: - # narrow unicode: - self.assertGdbRepr(chr(0x1D121), - "'\\U0000d834\\U0000dd21'") + check_repr(chr(0x1D121)) def test_tuples(self): 'Verify the pretty-printing of tuples' Modified: python/branches/py3k-cdecimal/Lib/test/test_htmlparser.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_htmlparser.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_htmlparser.py Mon Jun 7 12:46:02 2010 @@ -136,6 +136,13 @@ ("data", "\n"), ]) + def test_malformatted_charref(self): + self._run_check("

&#bad;

", [ + ("starttag", "p", []), + ("data", "&#bad;"), + ("endtag", "p"), + ]) + def test_unclosed_entityref(self): self._run_check("&entityref foo", [ ("entityref", "entityref"), Modified: python/branches/py3k-cdecimal/Lib/test/test_httplib.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_httplib.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_httplib.py Mon Jun 7 12:46:02 2010 @@ -239,7 +239,7 @@ self.assertEquals(resp.read(), b'') self.assertEquals(resp.status, 200) self.assertEquals(resp.reason, 'OK') - resp.close() + self.assertTrue(resp.isclosed()) def test_negative_content_length(self): sock = FakeSocket( Modified: python/branches/py3k-cdecimal/Lib/test/test_linecache.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_linecache.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_linecache.py Mon Jun 7 12:46:02 2010 @@ -31,6 +31,11 @@ ''' +SOURCE_3 = ''' +def f(): + return 3''' # No ending newline + + class LineCacheTests(unittest.TestCase): def test_getline(self): @@ -63,6 +68,13 @@ empty = linecache.getlines('a/b/c/__init__.py') self.assertEquals(empty, []) + def test_no_ending_newline(self): + self.addCleanup(support.unlink, support.TESTFN) + with open(support.TESTFN, "w") as fp: + fp.write(SOURCE_3) + lines = linecache.getlines(support.TESTFN) + self.assertEqual(lines, ["\n", "def f():\n", " return 3\n"]) + def test_clearcache(self): cached = [] for entry in TESTS: @@ -81,39 +93,36 @@ def test_checkcache(self): getline = linecache.getline - try: - # Create a source file and cache its contents - source_name = support.TESTFN + '.py' - with open(source_name, 'w') as source: - source.write(SOURCE_1) - getline(source_name, 1) - - # Keep a copy of the old contents - source_list = [] - with open(source_name) as source: - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) + # Create a source file and cache its contents + source_name = support.TESTFN + '.py' + self.addCleanup(support.unlink, source_name) + with open(source_name, 'w') as source: + source.write(SOURCE_1) + getline(source_name, 1) + + # Keep a copy of the old contents + source_list = [] + with open(source_name) as source: + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) - with open(source_name, 'w') as source: - source.write(SOURCE_2) + with open(source_name, 'w') as source: + source.write(SOURCE_2) - # Try to update a bogus cache entry - linecache.checkcache('dummy') + # 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): + # 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) + with open(source_name) as source: + for index, line in enumerate(source): self.assertEquals(line, getline(source_name, index + 1)) - - # Update the cache and check whether it matches the new source file - linecache.checkcache(source_name) - with open(source_name) as source: - for index, line in enumerate(source): - self.assertEquals(line, getline(source_name, index + 1)) - source_list.append(line) - - finally: - support.unlink(source_name) + source_list.append(line) def test_main(): support.run_unittest(LineCacheTests) Modified: python/branches/py3k-cdecimal/Lib/test/test_long.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_long.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_long.py Mon Jun 7 12:46:02 2010 @@ -330,6 +330,31 @@ # ... but it's just a normal digit if base >= 22 self.assertEqual(int('1L', 22), 43) + # tests with base 0 + self.assertEqual(int('000', 0), 0) + self.assertEqual(int('0o123', 0), 83) + self.assertEqual(int('0x123', 0), 291) + self.assertEqual(int('0b100', 0), 4) + self.assertEqual(int(' 0O123 ', 0), 83) + self.assertEqual(int(' 0X123 ', 0), 291) + self.assertEqual(int(' 0B100 ', 0), 4) + self.assertEqual(int('0', 0), 0) + self.assertEqual(int('+0', 0), 0) + self.assertEqual(int('-0', 0), 0) + self.assertEqual(int('00', 0), 0) + self.assertRaises(ValueError, int, '08', 0) + self.assertRaises(ValueError, int, '-012395', 0) + + # invalid bases + invalid_bases = [-909, + 2**31-1, 2**31, -2**31, -2**31-1, + 2**63-1, 2**63, -2**63, -2**63-1, + 2**100, -2**100, + ] + for base in invalid_bases: + self.assertRaises(ValueError, int, '42', base) + + def test_conversion(self): class JustLong: Modified: python/branches/py3k-cdecimal/Lib/test/test_os.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_os.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_os.py Mon Jun 7 12:46:02 2010 @@ -933,20 +933,64 @@ @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") class Win32KillTests(unittest.TestCase): - def _kill(self, sig, *args): - # Send a subprocess a signal (or in some cases, just an int to be - # the return value) - proc = subprocess.Popen(*args) + def _kill(self, sig): + # Start sys.executable as a subprocess and communicate from the + # subprocess to the parent that the interpreter is ready. When it + # becomes ready, send *sig* via os.kill to the subprocess and check + # that the return code is equal to *sig*. + import ctypes + from ctypes import wintypes + import msvcrt + + # Since we can't access the contents of the process' stdout until the + # process has exited, use PeekNamedPipe to see what's inside stdout + # without waiting. This is done so we can tell that the interpreter + # is started and running at a point where it could handle a signal. + PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe + PeekNamedPipe.restype = wintypes.BOOL + PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle + ctypes.POINTER(ctypes.c_char), # stdout buf + wintypes.DWORD, # Buffer size + ctypes.POINTER(wintypes.DWORD), # bytes read + ctypes.POINTER(wintypes.DWORD), # bytes avail + ctypes.POINTER(wintypes.DWORD)) # bytes left + msg = "running" + proc = subprocess.Popen([sys.executable, "-c", + "import sys;" + "sys.stdout.write('{}');" + "sys.stdout.flush();" + "input()".format(msg)], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE) + + count, max = 0, 100 + while count < max and proc.poll() is None: + # Create a string buffer to store the result of stdout from the pipe + buf = ctypes.create_string_buffer(len(msg)) + # Obtain the text currently in proc.stdout + # Bytes read/avail/left are left as NULL and unused + rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()), + buf, ctypes.sizeof(buf), None, None, None) + self.assertNotEqual(rslt, 0, "PeekNamedPipe failed") + if buf.value: + self.assertEqual(msg, buf.value.decode()) + break + time.sleep(0.1) + count += 1 + else: + self.fail("Did not receive communication from the subprocess") + os.kill(proc.pid, sig) self.assertEqual(proc.wait(), sig) def test_kill_sigterm(self): # SIGTERM doesn't mean anything special, but make sure it works - self._kill(signal.SIGTERM, [sys.executable]) + self._kill(signal.SIGTERM) def test_kill_int(self): # os.kill on Windows can take an int which gets set as the exit code - self._kill(100, [sys.executable]) + self._kill(100) def _kill_with_event(self, event, name): # Run a script which has console control handling enabled. Modified: python/branches/py3k-cdecimal/Lib/test/test_pipes.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_pipes.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_pipes.py Mon Jun 7 12:46:02 2010 @@ -70,9 +70,10 @@ self.assertEqual(open(TESTFN).read(), d) def testQuoting(self): - safeunquoted = string.ascii_letters + string.digits + '!@%_-+=:,./' - unsafe = '"`$\\' + safeunquoted = string.ascii_letters + string.digits + '@%_-+=:,./' + unsafe = '"`$\\!' + self.assertEqual(pipes.quote(''), "''") self.assertEqual(pipes.quote(safeunquoted), safeunquoted) self.assertEqual(pipes.quote('test file name'), "'test file name'") for u in unsafe: @@ -80,9 +81,7 @@ "'test%sname'" % u) for u in unsafe: self.assertEqual(pipes.quote("test%s'name'" % u), - '"test\\%s\'name\'"' % u) - - self.assertEqual(pipes.quote(''), "''") + "'test%s'\"'\"'name'\"'\"''" % u) def testRepr(self): t = pipes.Template() Modified: python/branches/py3k-cdecimal/Lib/test/test_socketserver.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_socketserver.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_socketserver.py Mon Jun 7 12:46:02 2010 @@ -61,6 +61,7 @@ testcase.assertEquals(72 << 8, status) + at unittest.skipUnless(threading, 'Threading required for this test.') class SocketServerTest(unittest.TestCase): """Test all socket servers.""" Modified: python/branches/py3k-cdecimal/Lib/test/test_ssl.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_ssl.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_ssl.py Mon Jun 7 12:46:02 2010 @@ -57,6 +57,14 @@ if support.verbose: sys.stdout.write(prefix + exc_format) +def can_clear_options(): + # 0.9.8m or higher + return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 13, 15) + +def no_sslv2_implies_sslv3_hello(): + # 0.9.7h or higher + return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15) + class BasicSocketTests(unittest.TestCase): @@ -189,6 +197,26 @@ with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"): ctx.set_ciphers("^$:,;?*'dorothyx") + def test_options(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + # OP_ALL is the default value + self.assertEqual(ssl.OP_ALL, ctx.options) + ctx.options |= ssl.OP_NO_SSLv2 + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2, + ctx.options) + ctx.options |= ssl.OP_NO_SSLv3 + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, + ctx.options) + if can_clear_options(): + ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1 + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3, + ctx.options) + ctx.options = 0 + self.assertEqual(0, ctx.options) + else: + with self.assertRaises(ValueError): + ctx.options = 0 + def test_verify(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) # Default value @@ -445,12 +473,8 @@ def wrap_conn(self): try: - self.sslconn = ssl.wrap_socket(self.sock, server_side=True, - certfile=self.server.certificate, - ssl_version=self.server.protocol, - ca_certs=self.server.cacerts, - cert_reqs=self.server.certreqs, - ciphers=self.server.ciphers) + self.sslconn = self.server.context.wrap_socket( + self.sock, server_side=True) except ssl.SSLError: # XXX Various errors can have happened here, for example # a mismatching protocol version, an invalid certificate, @@ -462,7 +486,7 @@ self.close() return False else: - if self.server.certreqs == ssl.CERT_REQUIRED: + if self.server.context.verify_mode == ssl.CERT_REQUIRED: cert = self.sslconn.getpeercert() if support.verbose and self.server.chatty: sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n") @@ -542,19 +566,24 @@ # harness, we want to stop the server self.server.stop() - def __init__(self, certificate, ssl_version=None, + def __init__(self, certificate=None, ssl_version=None, certreqs=None, cacerts=None, chatty=True, connectionchatty=False, starttls_server=False, - ciphers=None): - if ssl_version is None: - ssl_version = ssl.PROTOCOL_TLSv1 - if certreqs is None: - certreqs = ssl.CERT_NONE - self.certificate = certificate - self.protocol = ssl_version - self.certreqs = certreqs - self.cacerts = cacerts - self.ciphers = ciphers + ciphers=None, context=None): + if context: + self.context = context + else: + self.context = ssl.SSLContext(ssl_version + if ssl_version is not None + else ssl.PROTOCOL_TLSv1) + self.context.verify_mode = (certreqs if certreqs is not None + else ssl.CERT_NONE) + if cacerts: + self.context.load_verify_locations(cacerts) + if certificate: + self.context.load_cert_chain(certificate) + if ciphers: + self.context.set_ciphers(ciphers) self.chatty = chatty self.connectionchatty = connectionchatty self.starttls_server = starttls_server @@ -820,18 +849,13 @@ server.stop() server.join() - def server_params_test(certfile, protocol, certreqs, cacertsfile, - client_certfile, client_protocol=None, indata=b"FOO\n", - ciphers=None, chatty=True, connectionchatty=False): + def server_params_test(client_context, server_context, indata=b"FOO\n", + chatty=True, connectionchatty=False): """ Launch a server, connect a client to it and try various reads and writes. """ - server = ThreadedEchoServer(certfile, - certreqs=certreqs, - ssl_version=protocol, - cacerts=cacertsfile, - ciphers=ciphers, + server = ThreadedEchoServer(context=server_context, chatty=chatty, connectionchatty=False) flag = threading.Event() @@ -839,15 +863,8 @@ # wait for it to start flag.wait() # try to connect - if client_protocol is None: - client_protocol = protocol try: - s = ssl.wrap_socket(socket.socket(), - certfile=client_certfile, - ca_certs=cacertsfile, - ciphers=ciphers, - cert_reqs=certreqs, - ssl_version=client_protocol) + s = client_context.wrap_socket(socket.socket()) s.connect((HOST, server.port)) for arg in [indata, bytearray(indata), memoryview(indata)]: if connectionchatty: @@ -873,10 +890,8 @@ server.stop() server.join() - def try_protocol_combo(server_protocol, - client_protocol, - expect_success, - certsreqs=None): + def try_protocol_combo(server_protocol, client_protocol, expect_success, + certsreqs=None, server_options=0, client_options=0): if certsreqs is None: certsreqs = ssl.CERT_NONE certtype = { @@ -890,14 +905,21 @@ (ssl.get_protocol_name(client_protocol), ssl.get_protocol_name(server_protocol), certtype)) - try: + client_context = ssl.SSLContext(client_protocol) + client_context.options = ssl.OP_ALL | client_options + server_context = ssl.SSLContext(server_protocol) + server_context.options = ssl.OP_ALL | server_options + for ctx in (client_context, server_context): + ctx.verify_mode = certsreqs # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client # will send an SSLv3 hello (rather than SSLv2) starting from # OpenSSL 1.0.0 (see issue #8322). - server_params_test(CERTFILE, server_protocol, certsreqs, - CERTFILE, CERTFILE, client_protocol, - ciphers="ALL", chatty=False, - connectionchatty=False) + ctx.set_ciphers("ALL") + ctx.load_cert_chain(CERTFILE) + ctx.load_verify_locations(CERTFILE) + try: + server_params_test(client_context, server_context, + chatty=False, connectionchatty=False) # Protocol mismatch can result in either an SSLError, or a # "Connection reset by peer" error. except ssl.SSLError: @@ -920,30 +942,27 @@ """Basic test of an SSL client connecting to a server""" if support.verbose: sys.stdout.write("\n") - server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE, - CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1, - chatty=True, connectionchatty=True) + for protocol in PROTOCOLS: + context = ssl.SSLContext(protocol) + context.load_cert_chain(CERTFILE) + server_params_test(context, context, + chatty=True, connectionchatty=True) def test_getpeercert(self): if support.verbose: sys.stdout.write("\n") - s2 = socket.socket() - server = ThreadedEchoServer(CERTFILE, - certreqs=ssl.CERT_NONE, - ssl_version=ssl.PROTOCOL_SSLv23, - cacerts=CERTFILE, - chatty=False) + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.verify_mode = ssl.CERT_REQUIRED + context.load_verify_locations(CERTFILE) + context.load_cert_chain(CERTFILE) + server = ThreadedEchoServer(context=context, chatty=False) flag = threading.Event() server.start(flag) # wait for it to start flag.wait() # try to connect try: - s = ssl.wrap_socket(socket.socket(), - certfile=CERTFILE, - ca_certs=CERTFILE, - cert_reqs=ssl.CERT_REQUIRED, - ssl_version=ssl.PROTOCOL_SSLv23) + s = context.wrap_socket(socket.socket()) s.connect((HOST, server.port)) cert = s.getpeercert() self.assertTrue(cert, "Can't get peer certificate.") @@ -1031,6 +1050,15 @@ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True) try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False) + # SSLv23 client with specific SSL options + if no_sslv2_implies_sslv3_hello(): + # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs + try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False, + client_options=ssl.OP_NO_SSLv2) + try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True, + client_options=ssl.OP_NO_SSLv3) + try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True, + client_options=ssl.OP_NO_TLSv1) def test_protocol_sslv23(self): """Connecting to an SSLv23 server with various client options""" @@ -1056,6 +1084,16 @@ try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED) + # Server with specific SSL options + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, + server_options=ssl.OP_NO_SSLv3) + # Will choose TLSv1 + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, + server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False, + server_options=ssl.OP_NO_TLSv1) + + def test_protocol_sslv3(self): """Connecting to an SSLv3 server with various client options""" if support.verbose: @@ -1066,6 +1104,10 @@ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False) + if no_sslv2_implies_sslv3_hello(): + # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs + try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True, + client_options=ssl.OP_NO_SSLv2) def test_protocol_tlsv1(self): """Connecting to a TLSv1 server with various client options""" Modified: python/branches/py3k-cdecimal/Lib/test/test_subprocess.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_subprocess.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_subprocess.py Mon Jun 7 12:46:02 2010 @@ -535,6 +535,17 @@ if c.exception.errno != 2: # ignore "no such file" raise c.exception + def test_issue8780(self): + # Ensure that stdout is inherited from the parent + # if stdout=PIPE is not used + code = ';'.join(( + 'import subprocess, sys', + 'retcode = subprocess.call(' + "[sys.executable, '-c', 'print(\"Hello World!\")'])", + 'assert retcode == 0')) + output = subprocess.check_output([sys.executable, '-c', code]) + self.assert_(output.startswith(b'Hello World!'), ascii(output)) + # context manager class _SuppressCoreFiles(object): Modified: python/branches/py3k-cdecimal/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_sys.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_sys.py Mon Jun 7 12:46:02 2010 @@ -146,9 +146,9 @@ "raise SystemExit(47)"]) self.assertEqual(rc, 47) - def check_exit_message(code, expected): + def check_exit_message(code, expected, env=None): process = subprocess.Popen([sys.executable, "-c", code], - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, env=env) stdout, stderr = process.communicate() self.assertEqual(process.returncode, 1) self.assertTrue(stderr.startswith(expected), @@ -166,6 +166,14 @@ r'import sys; sys.exit("surrogates:\uDCFF")', b"surrogates:\\udcff") + # test that the unicode message is encoded to the stderr encoding + # instead of the default encoding (utf8) + env = os.environ.copy() + env['PYTHONIOENCODING'] = 'latin-1' + check_exit_message( + r'import sys; sys.exit("h\xe9")', + b"h\xe9", env=env) + def test_getdefaultencoding(self): self.assertRaises(TypeError, sys.getdefaultencoding, 42) # can't check more than the type, as the user might have changed it @@ -418,6 +426,23 @@ self.assertEqual(type(sys.int_info.bits_per_digit), int) self.assertEqual(type(sys.int_info.sizeof_digit), int) self.assertIsInstance(sys.hexversion, int) + + self.assertEqual(len(sys.hash_info), 5) + self.assertLess(sys.hash_info.modulus, 2**sys.hash_info.width) + # sys.hash_info.modulus should be a prime; we do a quick + # probable primality test (doesn't exclude the possibility of + # a Carmichael number) + for x in range(1, 100): + self.assertEqual( + pow(x, sys.hash_info.modulus-1, sys.hash_info.modulus), + 1, + "sys.hash_info.modulus {} is a non-prime".format( + sys.hash_info.modulus) + ) + self.assertIsInstance(sys.hash_info.inf, int) + self.assertIsInstance(sys.hash_info.nan, int) + self.assertIsInstance(sys.hash_info.imag, int) + self.assertIsInstance(sys.maxsize, int) self.assertIsInstance(sys.maxunicode, int) self.assertIsInstance(sys.platform, str) Modified: python/branches/py3k-cdecimal/Lib/test/test_sysconfig.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_sysconfig.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_sysconfig.py Mon Jun 7 12:46:02 2010 @@ -11,13 +11,14 @@ import shutil from copy import copy, deepcopy -from test.support import run_unittest, TESTFN, unlink, get_attribute +from test.support import (run_unittest, TESTFN, unlink, get_attribute, + captured_stdout) import sysconfig from sysconfig import (get_paths, get_platform, get_config_vars, get_path, get_path_names, _INSTALL_SCHEMES, _get_default_scheme, _expand_vars, - get_scheme_names) + get_scheme_names, get_config_var, _main) class TestSysConfig(unittest.TestCase): @@ -254,6 +255,22 @@ finally: unlink(link) + def test_user_similar(self): + # Issue 8759 : make sure the posix scheme for the users + # is similar to the global posix_prefix one + base = get_config_var('base') + user = get_config_var('userbase') + for name in ('stdlib', 'platstdlib', 'purelib', 'platlib'): + global_path = get_path(name, 'posix_prefix') + user_path = get_path(name, 'posix_user') + self.assertEquals(user_path, global_path.replace(base, user)) + + def test_main(self): + # just making sure _main() runs and returns things in the stdout + with captured_stdout() as output: + _main() + self.assertTrue(len(output.getvalue().split('\n')) > 0) + def test_main(): run_unittest(TestSysConfig) Modified: python/branches/py3k-cdecimal/Lib/test/test_tarfile.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_tarfile.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_tarfile.py Mon Jun 7 12:46:02 2010 @@ -133,6 +133,26 @@ "read() after readline() failed") fobj.close() + # Test if symbolic and hard links are resolved by extractfile(). The + # test link members each point to a regular member whose data is + # supposed to be exported. + def _test_fileobj_link(self, lnktype, regtype): + a = self.tar.extractfile(lnktype) + b = self.tar.extractfile(regtype) + self.assertEqual(a.name, b.name) + + def test_fileobj_link1(self): + self._test_fileobj_link("ustar/lnktype", "ustar/regtype") + + def test_fileobj_link2(self): + self._test_fileobj_link("./ustar/linktest2/lnktype", "ustar/linktest1/regtype") + + def test_fileobj_symlink1(self): + self._test_fileobj_link("ustar/symtype", "ustar/regtype") + + def test_fileobj_symlink2(self): + self._test_fileobj_link("./ustar/linktest2/symtype", "ustar/linktest1/regtype") + class CommonReadTest(ReadTest): @@ -661,10 +681,14 @@ if hasattr(os, "link"): link = os.path.join(TEMPDIR, "link") target = os.path.join(TEMPDIR, "link_target") - open(target, "wb").close() + fobj = open(target, "wb") + fobj.write(b"aaa") + fobj.close() os.link(target, link) try: tar = tarfile.open(tmpname, self.mode) + # Record the link target in the inodes list. + tar.gettarinfo(target) tarinfo = tar.gettarinfo(link) self.assertEqual(tarinfo.size, 0) finally: @@ -1374,6 +1398,29 @@ fobj.close() +class LinkEmulationTest(ReadTest): + + # Test for issue #8741 regression. On platforms that do not support + # symbolic or hard links tarfile tries to extract these types of members as + # the regular files they point to. + def _test_link_extraction(self, name): + self.tar.extract(name, TEMPDIR) + data = open(os.path.join(TEMPDIR, name), "rb").read() + self.assertEqual(md5sum(data), md5_regtype) + + def test_hardlink_extraction1(self): + self._test_link_extraction("ustar/lnktype") + + def test_hardlink_extraction2(self): + self._test_link_extraction("./ustar/linktest2/lnktype") + + def test_symlink_extraction1(self): + self._test_link_extraction("ustar/symtype") + + def test_symlink_extraction2(self): + self._test_link_extraction("./ustar/linktest2/symtype") + + class GzipMiscReadTest(MiscReadTest): tarname = gzipname mode = "r:gz" @@ -1459,6 +1506,8 @@ if hasattr(os, "link"): tests.append(HardlinkTest) + else: + tests.append(LinkEmulationTest) fobj = open(tarname, "rb") data = fobj.read() Modified: python/branches/py3k-cdecimal/Lib/test/test_tcl.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_tcl.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_tcl.py Mon Jun 7 12:46:02 2010 @@ -127,6 +127,31 @@ tcl = self.interp self.assertRaises(TclError,tcl.eval,'package require DNE') + def testLoadWithUNC(self): + import sys + if sys.platform != 'win32': + return + + # Build a UNC path from the regular path. + # Something like + # \\%COMPUTERNAME%\c$\python27\python.exe + + fullname = os.path.abspath(sys.executable) + if fullname[1] != ':': + return + unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'], + fullname[0], + fullname[3:]) + + with test_support.EnvironmentVarGuard() as env: + env.unset("TCL_LIBRARY") + f = os.popen('%s -c "import Tkinter; print Tkinter"' % (unc_name,)) + + self.assert_('Tkinter.py' in f.read()) + # exit code must be zero + self.assertEqual(f.close(), None) + + def test_main(): support.run_unittest(TclTest, TkinterTest) Modified: python/branches/py3k-cdecimal/Lib/test/test_urllib2.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_urllib2.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_urllib2.py Mon Jun 7 12:46:02 2010 @@ -1151,7 +1151,6 @@ self.assertEqual(len(http_handler.requests), 1) self.assertFalse(http_handler.requests[0].has_header(auth_header)) - class MiscTests(unittest.TestCase): def test_build_opener(self): Modified: python/branches/py3k-cdecimal/Lib/test/test_warnings.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_warnings.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_warnings.py Mon Jun 7 12:46:02 2010 @@ -738,20 +738,38 @@ module = py_warnings +class BootstrapTest(unittest.TestCase): + def test_issue_8766(self): + # "import encodings" emits a warning whereas the warnings is not loaded + # or not completly loaded (warnings imports indirectly encodings by + # importing linecache) yet + with support.temp_cwd() as cwd, support.temp_cwd('encodings'): + env = os.environ.copy() + env['PYTHONPATH'] = cwd + + # encodings loaded by initfsencoding() + retcode = subprocess.call([sys.executable, '-c', 'pass'], env=env) + self.assertEqual(retcode, 0) + + # Use -W to load warnings module at startup + retcode = subprocess.call( + [sys.executable, '-c', 'pass', '-W', 'always'], + env=env) + self.assertEqual(retcode, 0) + def test_main(): py_warnings.onceregistry.clear() c_warnings.onceregistry.clear() - support.run_unittest(CFilterTests, - PyFilterTests, - CWarnTests, - PyWarnTests, - CWCmdLineTests, PyWCmdLineTests, - _WarningsTests, - CWarningsDisplayTests, PyWarningsDisplayTests, - CCatchWarningTests, PyCatchWarningTests, - CEnvironmentVariableTests, - PyEnvironmentVariableTests - ) + support.run_unittest( + CFilterTests, PyFilterTests, + CWarnTests, PyWarnTests, + CWCmdLineTests, PyWCmdLineTests, + _WarningsTests, + CWarningsDisplayTests, PyWarningsDisplayTests, + CCatchWarningTests, PyCatchWarningTests, + CEnvironmentVariableTests, PyEnvironmentVariableTests, + BootstrapTest, + ) if __name__ == "__main__": Modified: python/branches/py3k-cdecimal/Lib/test/test_winreg.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_winreg.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_winreg.py Mon Jun 7 12:46:02 2010 @@ -5,6 +5,7 @@ import os, sys import unittest from test import support +threading = support.import_module("threading") from platform import machine # Do this first so test will be skipped if module doesn't exist @@ -227,6 +228,58 @@ except WindowsError: self.assertEqual(h.handle, 0) + def test_changing_value(self): + # Issue2810: A race condition in 2.6 and 3.1 may cause + # EnumValue or QueryValue to throw "WindowsError: More data is + # available" + done = False + + class VeryActiveThread(threading.Thread): + def run(self): + with CreateKey(HKEY_CURRENT_USER, test_key_name) as key: + use_short = True + long_string = 'x'*2000 + while not done: + s = 'x' if use_short else long_string + use_short = not use_short + SetValue(key, 'changing_value', REG_SZ, s) + + thread = VeryActiveThread() + thread.start() + try: + with CreateKey(HKEY_CURRENT_USER, + test_key_name+'\\changing_value') as key: + for _ in range(1000): + num_subkeys, num_values, t = QueryInfoKey(key) + for i in range(num_values): + name = EnumValue(key, i) + QueryValue(key, name[0]) + finally: + done = True + thread.join() + DeleteKey(HKEY_CURRENT_USER, test_key_name+'\\changing_value') + DeleteKey(HKEY_CURRENT_USER, test_key_name) + + def test_long_key(self): + # Issue2810, in 2.6 and 3.1 when the key name was exactly 256 + # characters, EnumKey threw "WindowsError: More data is + # available" + name = 'x'*256 + try: + with CreateKey(HKEY_CURRENT_USER, test_key_name) as key: + SetValue(key, name, REG_SZ, 'x') + num_subkeys, num_values, t = QueryInfoKey(key) + EnumKey(key, 0) + finally: + DeleteKey(HKEY_CURRENT_USER, '\\'.join((test_key_name, name))) + DeleteKey(HKEY_CURRENT_USER, test_key_name) + + def test_dynamic_key(self): + # Issue2810, when the value is dynamically generated, these + # throw "WindowsError: More data is available" in 2.6 and 3.1 + EnumValue(HKEY_PERFORMANCE_DATA, 0) + QueryValueEx(HKEY_PERFORMANCE_DATA, "") + # Reflection requires XP x64/Vista at a minimum. XP doesn't have this stuff # or DeleteKeyEx so make sure their use raises NotImplementedError @unittest.skipUnless(WIN_VER < (5, 2), "Requires Windows XP") Modified: python/branches/py3k-cdecimal/Lib/test/test_winsound.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_winsound.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_winsound.py Mon Jun 7 12:46:02 2010 @@ -6,6 +6,7 @@ import time import os import subprocess +import ctypes winsound = support.import_module('winsound') import winreg @@ -13,6 +14,11 @@ def has_sound(sound): """Find out if a particular event is configured with a default sound""" try: + # Ask the mixer API for the number of devices it knows about. + # When there are no devices, PlaySound will fail. + if ctypes.windll.winmm.mixerGetNumDevs() is 0: + return False + key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, "AppEvents\Schemes\Apps\.Default\{0}\.Default".format(sound)) value = winreg.EnumValue(key, 0)[1] Modified: python/branches/py3k-cdecimal/Lib/test/testtar.tar ============================================================================== Binary files. No diff available. Modified: python/branches/py3k-cdecimal/Lib/tkinter/_fix.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/tkinter/_fix.py (original) +++ python/branches/py3k-cdecimal/Lib/tkinter/_fix.py Mon Jun 7 12:46:02 2010 @@ -42,6 +42,8 @@ # Ignore leading \\?\ if s.startswith("\\\\?\\"): s = s[4:] + if s.startswith("UNC"): + s = "\\" + s[3:] return s prefix = os.path.join(sys.prefix,"tcl") Modified: python/branches/py3k-cdecimal/Lib/unittest/case.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/case.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/case.py Mon Jun 7 12:46:02 2010 @@ -14,6 +14,9 @@ __unittest = True +DIFF_OMITTED = ('\nDiff is %s characters long. ' + 'Set self.maxDiff to None to see it.') + class SkipTest(Exception): """ Raise this exception in a test to skip it. @@ -169,6 +172,12 @@ longMessage = False + # This attribute sets the maximum length of a diff in failure messsages + # by assert methods using difflib. It is looked up as an instance attribute + # so can be configured by individual tests if required. + + maxDiff = 80*8 + # Attribute used by TestSuite for classSetUp _classSetupFailed = False @@ -694,12 +703,21 @@ except (TypeError, IndexError, NotImplementedError): differing += ('Unable to index element %d ' 'of second %s\n' % (len1, seq_type_name)) - standardMsg = differing + '\n' + '\n'.join( + standardMsg = differing + diffMsg = '\n' + '\n'.join( difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) + + standardMsg = self._truncateMessage(standardMsg, diffMsg) msg = self._formatMessage(msg, standardMsg) self.fail(msg) + def _truncateMessage(self, message, diff): + max_diff = self.maxDiff + if max_diff is None or len(diff) <= max_diff: + return message + diff + return message + (DIFF_OMITTED % len(diff)) + def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. @@ -798,9 +816,11 @@ self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') if d1 != d2: - standardMsg = ('\n' + '\n'.join(difflib.ndiff( + standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) + diff = ('\n' + '\n'.join(difflib.ndiff( pprint.pformat(d1).splitlines(), pprint.pformat(d2).splitlines()))) + standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertDictContainsSubset(self, expected, actual, msg=None): @@ -917,8 +937,10 @@ 'Second argument is not a string')) if first != second: - standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), + standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True)) + diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) + standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertLess(self, a, b, msg=None): Modified: python/branches/py3k-cdecimal/Lib/unittest/loader.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/loader.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/loader.py Mon Jun 7 12:46:02 2010 @@ -235,6 +235,10 @@ __import__(name) return sys.modules[name] + def _match_path(self, path, full_path, pattern): + # override this method to use alternative matching strategy + return fnmatch(path, pattern) + def _find_tests(self, start_dir, pattern): """Used by discovery. Yields test suites it loads.""" paths = os.listdir(start_dir) @@ -245,26 +249,26 @@ if not VALID_MODULE_NAME.match(path): # valid Python identifiers only continue - - if fnmatch(path, pattern): - # if the test file matches, load it - name = self._get_name_from_path(full_path) - try: - module = self._get_module_from_name(name) - except: - yield _make_failed_import_test(name, self.suiteClass) - else: - mod_file = os.path.abspath(getattr(module, '__file__', full_path)) - realpath = os.path.splitext(mod_file)[0] - fullpath_noext = os.path.splitext(full_path)[0] - if realpath.lower() != fullpath_noext.lower(): - module_dir = os.path.dirname(realpath) - mod_name = os.path.splitext(os.path.basename(full_path))[0] - expected_dir = os.path.dirname(full_path) - msg = ("%r module incorrectly imported from %r. Expected %r. " - "Is this module globally installed?") - raise ImportError(msg % (mod_name, module_dir, expected_dir)) - yield self.loadTestsFromModule(module) + if not self._match_path(path, full_path, pattern): + continue + # if the test file matches, load it + name = self._get_name_from_path(full_path) + try: + module = self._get_module_from_name(name) + except: + yield _make_failed_import_test(name, self.suiteClass) + else: + mod_file = os.path.abspath(getattr(module, '__file__', full_path)) + realpath = os.path.splitext(mod_file)[0] + fullpath_noext = os.path.splitext(full_path)[0] + if realpath.lower() != fullpath_noext.lower(): + module_dir = os.path.dirname(realpath) + mod_name = os.path.splitext(os.path.basename(full_path))[0] + expected_dir = os.path.dirname(full_path) + msg = ("%r module incorrectly imported from %r. Expected %r. " + "Is this module globally installed?") + raise ImportError(msg % (mod_name, module_dir, expected_dir)) + yield self.loadTestsFromModule(module) elif os.path.isdir(full_path): if not os.path.isfile(os.path.join(full_path, '__init__.py')): continue Modified: python/branches/py3k-cdecimal/Lib/unittest/suite.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/suite.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/suite.py Mon Jun 7 12:46:02 2010 @@ -127,9 +127,11 @@ if setUpClass is not None: try: setUpClass() - except: + except Exception as e: currentClass._classSetupFailed = True - self._addClassSetUpError(result, currentClass) + className = util.strclass(currentClass) + errorName = 'setUpClass (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) def _get_previous_module(self, result): previousModule = None @@ -157,10 +159,18 @@ if setUpModule is not None: try: setUpModule() - except: + except Exception as e: result._moduleSetUpFailed = True - error = _ErrorHolder('setUpModule (%s)' % currentModule) - result.addError(error, sys.exc_info()) + errorName = 'setUpModule (%s)' % currentModule + self._addClassOrModuleLevelException(result, e, errorName) + + def _addClassOrModuleLevelException(self, result, exception, errorName): + error = _ErrorHolder(errorName) + addSkip = getattr(result, 'addSkip', None) + if addSkip is not None and isinstance(exception, case.SkipTest): + addSkip(error, str(exception)) + else: + result.addError(error, sys.exc_info()) def _handleModuleTearDown(self, result): previousModule = self._get_previous_module(result) @@ -178,9 +188,9 @@ if tearDownModule is not None: try: tearDownModule() - except: - error = _ErrorHolder('tearDownModule (%s)' % previousModule) - result.addError(error, sys.exc_info()) + except Exception as e: + errorName = 'tearDownModule (%s)' % previousModule + self._addClassOrModuleLevelException(result, e, errorName) def _tearDownPreviousClass(self, test, result): previousClass = getattr(result, '_previousTestClass', None) @@ -198,18 +208,11 @@ if tearDownClass is not None: try: tearDownClass() - except: - self._addClassTearDownError(result) + except Exception as e: + className = util.strclass(previousClass) + errorName = 'tearDownClass (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) - def _addClassTearDownError(self, result): - className = util.strclass(result._previousTestClass) - error = _ErrorHolder('classTearDown (%s)' % className) - result.addError(error, sys.exc_info()) - - def _addClassSetUpError(self, result, klass): - className = util.strclass(klass) - error = _ErrorHolder('classSetUp (%s)' % className) - result.addError(error, sys.exc_info()) class _ErrorHolder(object): Modified: python/branches/py3k-cdecimal/Lib/unittest/test/test_case.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/test/test_case.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/test/test_case.py Mon Jun 7 12:46:02 2010 @@ -1,3 +1,5 @@ +import difflib +import pprint import re import sys @@ -589,6 +591,84 @@ self.assertRaises(self.failureException, self.assertDictEqual, [], d) self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) + def testAssertSequenceEqualMaxDiff(self): + self.assertEqual(self.maxDiff, 80*8) + seq1 = 'a' + 'x' * 80**2 + seq2 = 'b' + 'x' * 80**2 + diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), + pprint.pformat(seq2).splitlines())) + # the +1 is the leading \n added by assertSequenceEqual + omitted = unittest.case.DIFF_OMITTED % (len(diff) + 1,) + + self.maxDiff = len(diff)//2 + try: + + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: + msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') + self.assertTrue(len(msg) < len(diff)) + self.assertIn(omitted, msg) + + self.maxDiff = len(diff) * 2 + try: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: + msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') + self.assertTrue(len(msg) > len(diff)) + self.assertNotIn(omitted, msg) + + self.maxDiff = None + try: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: + msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') + self.assertTrue(len(msg) > len(diff)) + self.assertNotIn(omitted, msg) + + def testTruncateMessage(self): + self.maxDiff = 1 + message = self._truncateMessage('foo', 'bar') + omitted = unittest.case.DIFF_OMITTED % len('bar') + self.assertEqual(message, 'foo' + omitted) + + self.maxDiff = None + message = self._truncateMessage('foo', 'bar') + self.assertEqual(message, 'foobar') + + self.maxDiff = 4 + message = self._truncateMessage('foo', 'bar') + self.assertEqual(message, 'foobar') + + def testAssertDictEqualTruncates(self): + test = unittest.TestCase('assertEqual') + def truncate(msg, diff): + return 'foo' + test._truncateMessage = truncate + try: + test.assertDictEqual({}, {1: 0}) + except self.failureException as e: + self.assertEqual(str(e), 'foo') + else: + self.fail('assertDictEqual did not fail') + + def testAssertMultiLineEqualTruncates(self): + test = unittest.TestCase('assertEqual') + def truncate(msg, diff): + return 'foo' + test._truncateMessage = truncate + try: + test.assertMultiLineEqual('foo', 'bar') + except self.failureException as e: + self.assertEqual(str(e), 'foo') + else: + self.fail('assertMultiLineEqual did not fail') + def testAssertItemsEqual(self): a = object() self.assertItemsEqual([1, 2, 3], [3, 2, 1]) @@ -739,7 +819,7 @@ A test case is the smallest unit of testing. [...] You may provide your own implementation that does not subclass from TestCase, of course. """ - sample_text_error = """ + sample_text_error = """\ - http://www.python.org/doc/2.3/lib/module-unittest.html ? ^ + http://www.python.org/doc/2.4.1/lib/module-unittest.html @@ -750,13 +830,16 @@ ? +++++++++++++++++++++ + own implementation that does not subclass from TestCase, of course. """ - + self.maxDiff = None try: self.assertMultiLineEqual(sample_text, revised_sample_text) except self.failureException as e: + # need to remove the first line of the error message + error = str(e).split('\n', 1)[1] + # no fair testing ourself with ourself, and assertEqual is used for strings # so can't use assertEqual either. Just use assertTrue. - self.assertTrue(sample_text_error == str(e)) + self.assertTrue(sample_text_error == error) def testAssertIsNone(self): self.assertIsNone(None) Modified: python/branches/py3k-cdecimal/Lib/unittest/test/test_setups.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/test/test_setups.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/test/test_setups.py Mon Jun 7 12:46:02 2010 @@ -111,7 +111,7 @@ self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), - 'classSetUp (%s.BrokenTest)' % __name__) + 'setUpClass (%s.BrokenTest)' % __name__) def test_error_in_teardown_class(self): class Test(unittest.TestCase): @@ -144,7 +144,7 @@ error, _ = result.errors[0] self.assertEqual(str(error), - 'classTearDown (%s.Test)' % __name__) + 'tearDownClass (%s.Test)' % __name__) def test_class_not_torndown_when_setup_fails(self): class Test(unittest.TestCase): @@ -398,3 +398,46 @@ self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), 'tearDownModule (Module)') + + def test_skiptest_in_setupclass(self): + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + raise unittest.SkipTest('foo') + def test_one(self): + pass + def test_two(self): + pass + + result = self.runTests(Test) + self.assertEqual(result.testsRun, 0) + self.assertEqual(len(result.errors), 0) + self.assertEqual(len(result.skipped), 1) + skipped = result.skipped[0][0] + self.assertEqual(str(skipped), 'setUpClass (%s.Test)' % __name__) + + def test_skiptest_in_setupmodule(self): + class Test(unittest.TestCase): + def test_one(self): + pass + def test_two(self): + pass + + class Module(object): + @staticmethod + def setUpModule(): + raise unittest.SkipTest('foo') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + result = self.runTests(Test) + self.assertEqual(result.testsRun, 0) + self.assertEqual(len(result.errors), 0) + self.assertEqual(len(result.skipped), 1) + skipped = result.skipped[0][0] + self.assertEqual(str(skipped), 'setUpModule (Module)') + + +if __name__ == '__main__': + unittest.main() Modified: python/branches/py3k-cdecimal/Lib/unittest/util.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/util.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/util.py Mon Jun 7 12:46:02 2010 @@ -2,12 +2,16 @@ __unittest = True - -def safe_repr(obj): +_MAX_LENGTH = 80 +def safe_repr(obj, short=False): try: - return repr(obj) + result = repr(obj) except Exception: - return object.__repr__(obj) + result = object.__repr__(obj) + if not short or len(result) < _MAX_LENGTH: + return result + return result[:_MAX_LENGTH] + ' [truncated]...' + def strclass(cls): return "%s.%s" % (cls.__module__, cls.__name__) Modified: python/branches/py3k-cdecimal/Lib/urllib/request.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/urllib/request.py (original) +++ python/branches/py3k-cdecimal/Lib/urllib/request.py Mon Jun 7 12:46:02 2010 @@ -775,12 +775,21 @@ password_mgr = HTTPPasswordMgr() self.passwd = password_mgr self.add_password = self.passwd.add_password + self.retried = 0 def http_error_auth_reqed(self, authreq, host, req, headers): # host may be an authority (without userinfo) or a URL with an # authority # XXX could be multiple headers authreq = headers.get(authreq, None) + + if self.retried > 5: + # retry sending the username:password 5 times before failing. + raise HTTPError(req.get_full_url(), 401, "basic auth failed", + headers, None) + else: + self.retried += 1 + if authreq: mo = AbstractBasicAuthHandler.rx.search(authreq) if mo: Modified: python/branches/py3k-cdecimal/Lib/webbrowser.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/webbrowser.py (original) +++ python/branches/py3k-cdecimal/Lib/webbrowser.py Mon Jun 7 12:46:02 2010 @@ -540,18 +540,6 @@ # Platform support for MacOS # -try: - import ic -except ImportError: - pass -else: - class InternetConfig(BaseBrowser): - def open(self, url, new=0, autoraise=True): - ic.launchurl(url) - return True # Any way to get status? - - register("internet-config", InternetConfig, update_tryorder=-1) - if sys.platform == 'darwin': # Adapted from patch submitted to SourceForge by Steven J. Burr class MacOSX(BaseBrowser): Modified: python/branches/py3k-cdecimal/Mac/Tools/pythonw.c ============================================================================== --- python/branches/py3k-cdecimal/Mac/Tools/pythonw.c (original) +++ python/branches/py3k-cdecimal/Mac/Tools/pythonw.c Mon Jun 7 12:46:02 2010 @@ -151,6 +151,14 @@ main(int argc, char **argv) { char* exec_path = get_python_path(); + /* + * Let argv[0] refer to the new interpreter. This is needed to + * get the effect we want on OSX 10.5 or earlier. That is, without + * changing argv[0] the real interpreter won't have access to + * the Window Server. + */ + argv[0] = exec_path; + #ifdef HAVE_SPAWN_H /* We're weak-linking to posix-spawnv to ensure that * an executable build on 10.5 can work on 10.4. Modified: python/branches/py3k-cdecimal/Misc/ACKS ============================================================================== --- python/branches/py3k-cdecimal/Misc/ACKS (original) +++ python/branches/py3k-cdecimal/Misc/ACKS Mon Jun 7 12:46:02 2010 @@ -19,6 +19,7 @@ Kevin Altis Joe Amenta Mark Anacker +Shashwat Anand Anders Andersen John Anderson Erik Anders?n @@ -82,6 +83,7 @@ Paul Boddie Matthew Boedicker David Bolen +Forest Bond Gawain Bolton Gregory Bond Jurjen Bos @@ -363,6 +365,7 @@ Eric Huss Jeremy Hylton Gerhard H?ring +Fredrik H??rd Mihai Ibanescu Lars Immisch Meador Inge @@ -424,6 +427,7 @@ Damon Kohler Joseph Koshy Maksim Kozyarchuk +Stefan Krah Bob Kras Holger Krekel Michael Kremer Modified: python/branches/py3k-cdecimal/Misc/NEWS ============================================================================== --- python/branches/py3k-cdecimal/Misc/NEWS (original) +++ python/branches/py3k-cdecimal/Misc/NEWS Mon Jun 7 12:46:02 2010 @@ -12,6 +12,31 @@ Core and Builtins ----------------- +- Issue #8837: Remove "O?" format of PyArg_Parse*() functions. The format is no + used anymore and it was never documented. + +- Issue #2844: Make int('42', n) consistently raise ValueError for + invalid integers n (including n = -909). + +- Issue #8188: Introduce a new scheme for computing hashes of numbers + (instances of int, float, complex, decimal.Decimal and + fractions.Fraction) that makes it easy to maintain the invariant + that hash(x) == hash(y) whenever x and y have equal value. + +- Issue #8748: Fix two issues with comparisons between complex and integer + objects. (1) The comparison could incorrectly return True in some cases + (2**53+1 == complex(2**53) == 2**53), breaking transivity of equality. + (2) The comparison raised an OverflowError for large integers, leading + to unpredictable exceptions when combining integers and complex objects + in sets or dicts. + +- Issue #8766: Initialize _warnings module before importing the first module. + Fix a crash if an empty directory called "encodings" exists in sys.path. + +- Issue #8589: Decode PYTHONWARNINGS environment variable with the file system + encoding and surrogateespace error handler instead of the locale encoding to + be consistent with os.environ. Add PySys_AddWarnOptionUnicode() function. + - PyObject_Dump() encodes unicode objects to utf8 with backslashreplace (instead of strict) error handler to escape surrogates @@ -31,6 +56,8 @@ PyUnicode_FromString() to support surrogates in the filename and use the right encoding +- Issue #7507: Quote "!" in pipes.quote(); it is special to some shells. + - PyUnicode_DecodeFSDefaultAndSize() uses surrogateescape error handler - Issue #8419: Prevent the dict constructor from accepting non-string keyword @@ -312,6 +339,11 @@ C-API ----- +- Issue #5753: A new C API function, :cfunc:`PySys_SetArgvEx`, allows + embedders of the interpreter to set sys.argv without also modifying + sys.path. This helps fix `CVE-2008-5983 + `_. + - Add PyArg_ValidateKeywordArguments, which checks if all keyword arguments are strings in an efficient manner. @@ -366,6 +398,74 @@ Library ------- +- Issue #8899: time.struct_time now has class and atribute docstrings. + +- Issue #6470: Drop UNC prefix in FixTk. + +- Issue #4768: base64 encoded email body parts were incorrectly stored as + binary strings. They are now correctly converted to strings. + +- Issue #8833: tarfile created hard link entries with a size field != 0 by + mistake. + +- Charset.body_encode now correctly handles base64 encoding by encoding + with the output_charset before calling base64mime.encode. Passes the + tests from 2.x issue 1368247. + +- Issue #8845: sqlite3 Connection objects now have a read-only in_transaction + attribute that is True iff there are uncommitted changes. + +- Issue #1289118: datetime.timedelta objects can now be multiplied by float + and divided by float and int objects. Results are rounded to the nearest + multiple of timedelta.resolution with ties resolved using round-half-to-even + method. + +- Issue #7150: Raise OverflowError if the result of adding or subtracting + timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range. + +- Issue #8806: add SSL contexts support to ftplib. + +- Issue #4769: Fix main() function of the base64 module, use sys.stdin.buffer + and sys.stdout.buffer (instead of sys.stdin and sys.stdout) to use the bytes + API + +- Issue #8770: now sysconfig displays information when it's called as + a script. Initial idea by Sridhar Ratnakumar. + +- Issue #6662: Fix parsing of malformatted charref (&#bad;), patch written by + Fredrik H??rd + +- Issue #8540: Decimal module: rename the Context._clamp attribute to + Context.clamp and make it public. This is useful in creating + contexts that correspond to the decimal interchange formats + specified in IEEE 754. + +- Issue #6268: Fix seek() method of codecs.open(), don't read or write the BOM + twice after seek(0). Fix also reset() method of codecs, UTF-16, UTF-32 and + StreamWriter classes. + +- Issue #3798: sys.exit(message) writes the message to sys.stderr file, instead + of the C file stderr, to use stderr encoding and error handler + +- Issue #8782: Add a trailing newline in linecache.updatecache to the last line + of files without one. + +- Issue #8729: Return NotImplemented from collections.Mapping.__eq__ when + comparing to a non-mapping. + +- Issue #8774: tabnanny uses the encoding cookie (#coding:...) to use the + correct encoding + +- Issue #4870: Add an `options` attribute to SSL contexts, as well as + several ``OP_*`` constants to the `ssl` module. This allows to selectively + disable protocol versions, when used in combination with `PROTOCOL_SSLv23`. + +- Issue #8759: Fixed user paths in sysconfig for posix and os2 schemes. + +- Issue #8663: distutils.log emulates backslashreplace error handler. Fix + compilation in a non-ASCII directory if stdout encoding is ASCII (eg. if + stdout is not a TTY). + - Issue #8513: os.get_exec_path() supports b'PATH' key and bytes value. subprocess.Popen() and os._execvpe() support bytes program name. Add os.supports_bytes_environ flag: True if the native OS type of the environment @@ -442,7 +542,7 @@ - Issue #8354: The siginterrupt setting is now preserved for all signals, not just SIGCHLD. -- Issue #7192: webbrowser.get("firefox") now wors on Mac OS X, as does +- Issue #7192: webbrowser.get("firefox") now works on Mac OS X, as does webbrowser.get("safari"). - Issue #8464: tarfile no longer creates files with execute permissions set @@ -1153,6 +1253,9 @@ Extension Modules ----------------- +- Issue #2810: Fix cases where the Windows registry API returns + ERROR_MORE_DATA, requiring a re-try in order to get the complete result. + - Issue #8692: Optimize math.factorial: replace the previous naive algorithm with an improved 'binary-split' algorithm that uses fewer multiplications and allows many of the multiplications to be @@ -1229,6 +1332,9 @@ Build ----- +- Issue #1759169, #8864: Drop _XOPEN_SOURCE on Solaris, define it for + multiprocessing only. + - Issue #8625: Turn off optimization in --with-pydebug builds with gcc. (Optimization was unintentionally turned on in gcc --with-pydebug builds as a result of the issue #1628484 fix, @@ -1315,9 +1421,14 @@ - Update python manual page (options -B, -O0, -s, environment variables PYTHONDONTWRITEBYTECODE, PYTHONNOUSERSITE). +- Issue #8909: Added the size of the bitmap used in the installer created by + distutils' bdist_wininst. Patch by Anatoly Techtonik. + Tests ----- +- Issue #7449: Skip test_socketserver if threading support is disabled + - Issue #8672: Add a zlib test ensuring that an incomplete stream can be handled by a decompressor object without errors (it returns incomplete uncompressed data). @@ -1444,6 +1555,8 @@ Tools/Demos ----------- +- Issue #5464: Implement plural forms in msgfmt.py. + - iobench (a file I/O benchmark) and ccbench (a concurrency benchmark) were added to the `Tools/` directory. They were previously living in the sandbox. Modified: python/branches/py3k-cdecimal/Misc/developers.txt ============================================================================== --- python/branches/py3k-cdecimal/Misc/developers.txt (original) +++ python/branches/py3k-cdecimal/Misc/developers.txt Mon Jun 7 12:46:02 2010 @@ -20,6 +20,9 @@ Permissions History ------------------- +- Alexander Belopolsky was given commit access on May 25 2010 + by MvL at suggestion of Mark Dickinson. + - Tim Golden was given commit access on April 21 2010 by MvL, at suggestion of Michael Foord. Modified: python/branches/py3k-cdecimal/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/py3k-cdecimal/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/py3k-cdecimal/Modules/_multiprocessing/multiprocessing.h Mon Jun 7 12:46:02 2010 @@ -3,6 +3,12 @@ #define PY_SSIZE_T_CLEAN +#ifdef __sun +/* The control message API is only available on Solaris + if XPG 4.2 or later is requested. */ +#define _XOPEN_SOURCE 500 +#endif + #include "Python.h" #include "structmember.h" #include "pythread.h" Modified: python/branches/py3k-cdecimal/Modules/_sqlite/connection.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/_sqlite/connection.c (original) +++ python/branches/py3k-cdecimal/Modules/_sqlite/connection.c Mon Jun 7 12:46:02 2010 @@ -23,6 +23,7 @@ #include "cache.h" #include "module.h" +#include "structmember.h" #include "connection.h" #include "statement.h" #include "cursor.h" @@ -1551,6 +1552,7 @@ {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY}, {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, + {"in_transaction", T_BOOL, offsetof(pysqlite_Connection, inTransaction), READONLY}, {NULL} }; Modified: python/branches/py3k-cdecimal/Modules/_ssl.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/_ssl.c (original) +++ python/branches/py3k-cdecimal/Modules/_ssl.c Mon Jun 7 12:46:02 2010 @@ -113,6 +113,13 @@ # undef HAVE_OPENSSL_RAND #endif +/* SSL_CTX_clear_options() and SSL_clear_options() were first added in OpenSSL 0.9.8m */ +#if OPENSSL_VERSION_NUMBER >= 0x009080dfL +# define HAVE_SSL_CTX_CLEAR_OPTIONS +#else +# undef HAVE_SSL_CTX_CLEAR_OPTIONS +#endif + typedef struct { PyObject_HEAD SSL_CTX *ctx; @@ -1514,6 +1521,35 @@ } static PyObject * +get_options(PySSLContext *self, void *c) +{ + return PyLong_FromLong(SSL_CTX_get_options(self->ctx)); +} + +static int +set_options(PySSLContext *self, PyObject *arg, void *c) +{ + long new_opts, opts, set, clear; + if (!PyArg_Parse(arg, "l", &new_opts)) + return -1; + opts = SSL_CTX_get_options(self->ctx); + clear = opts & ~new_opts; + set = ~opts & new_opts; + if (clear) { +#ifdef HAVE_SSL_CTX_CLEAR_OPTIONS + SSL_CTX_clear_options(self->ctx, clear); +#else + PyErr_SetString(PyExc_ValueError, + "can't clear options before OpenSSL 0.9.8m"); + return -1; +#endif + } + if (set) + SSL_CTX_set_options(self->ctx, set); + return 0; +} + +static PyObject * load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"certfile", "keyfile", NULL}; @@ -1636,6 +1672,8 @@ } static PyGetSetDef context_getsetlist[] = { + {"options", (getter) get_options, + (setter) set_options, NULL}, {"verify_mode", (getter) get_verify_mode, (setter) set_verify_mode, NULL}, {NULL}, /* sentinel */ @@ -1953,6 +1991,12 @@ PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", PY_SSL_VERSION_TLS1); + /* protocol options */ + PyModule_AddIntConstant(m, "OP_ALL", SSL_OP_ALL); + PyModule_AddIntConstant(m, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); + PyModule_AddIntConstant(m, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); + PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); + /* OpenSSL version */ /* SSLeay() gives us the version of the library linked against, which could be different from the headers version. Modified: python/branches/py3k-cdecimal/Modules/config.c.in ============================================================================== --- python/branches/py3k-cdecimal/Modules/config.c.in (original) +++ python/branches/py3k-cdecimal/Modules/config.c.in Mon Jun 7 12:46:02 2010 @@ -34,28 +34,28 @@ /* -- ADDMODULE MARKER 2 -- */ - /* This module lives in marshal.c */ - {"marshal", PyMarshal_Init}, + /* This module lives in marshal.c */ + {"marshal", PyMarshal_Init}, - /* This lives in import.c */ - {"imp", PyInit_imp}, + /* This lives in import.c */ + {"imp", PyInit_imp}, - /* This lives in Python/Python-ast.c */ - {"_ast", PyInit__ast}, + /* This lives in Python/Python-ast.c */ + {"_ast", PyInit__ast}, - /* These entries are here for sys.builtin_module_names */ - {"__main__", NULL}, - {"builtins", NULL}, - {"sys", NULL}, + /* These entries are here for sys.builtin_module_names */ + {"__main__", NULL}, + {"builtins", NULL}, + {"sys", NULL}, - /* This lives in gcmodule.c */ - {"gc", PyInit_gc}, + /* This lives in gcmodule.c */ + {"gc", PyInit_gc}, - /* This lives in _warnings.c */ - {"_warnings", _PyWarnings_Init}, + /* This lives in _warnings.c */ + {"_warnings", _PyWarnings_Init}, - /* Sentinel */ - {0, 0} + /* Sentinel */ + {0, 0} }; Modified: python/branches/py3k-cdecimal/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/datetimemodule.c (original) +++ python/branches/py3k-cdecimal/Modules/datetimemodule.c Mon Jun 7 12:46:02 2010 @@ -30,6 +30,7 @@ #define MINYEAR 1 #define MAXYEAR 9999 +#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */ /* Nine decimal digits is easy to communicate, and leaves enough room * so that two delta days can be added w/o fear of overflowing a signed @@ -151,6 +152,25 @@ return (long)x; } +/* Nearest integer to m / n for integers m and n. Half-integer results + * are rounded to even. + */ +static PyObject * +divide_nearest(PyObject *m, PyObject *n) +{ + PyObject *result; + PyObject *temp; + + temp = _PyLong_Divmod_Near(m, n); + if (temp == NULL) + return NULL; + result = PyTuple_GET_ITEM(temp, 0); + Py_INCREF(result); + Py_DECREF(temp); + + return result; +} + /* --------------------------------------------------------------------------- * General calendrical helper functions */ @@ -480,7 +500,7 @@ * The input values must be such that the internals don't overflow. * The way this routine is used, we don't get close. */ -static void +static int normalize_y_m_d(int *y, int *m, int *d) { int dim; /* # of days in month */ @@ -534,11 +554,23 @@ else { int ordinal = ymd_to_ord(*y, *m, 1) + *d - 1; - ord_to_ymd(ordinal, y, m, d); + if (ordinal < 1 || ordinal > MAXORDINAL) { + goto error; + } else { + ord_to_ymd(ordinal, y, m, d); + return 0; + } } } assert(*m > 0); assert(*d > 0); + if (MINYEAR <= *y && *y <= MAXYEAR) + return 0; + error: + PyErr_SetString(PyExc_OverflowError, + "date value out of range"); + return -1; + } /* Fiddle out-of-bounds months and days so that the result makes some kind @@ -548,17 +580,7 @@ static int normalize_date(int *year, int *month, int *day) { - int result; - - normalize_y_m_d(year, month, day); - if (MINYEAR <= *year && *year <= MAXYEAR) - result = 0; - else { - PyErr_SetString(PyExc_OverflowError, - "date value out of range"); - result = -1; - } - return result; + return normalize_y_m_d(year, month, day); } /* Force all the datetime fields into range. The parameters are both @@ -1645,6 +1667,37 @@ } static PyObject * +multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta) +{ + PyObject *result = NULL; + PyObject *pyus_in = NULL, *temp, *pyus_out; + PyObject *ratio = NULL; + + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL); + if (ratio == NULL) + goto error; + temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0)); + Py_DECREF(pyus_in); + pyus_in = NULL; + if (temp == NULL) + goto error; + pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1)); + Py_DECREF(temp); + if (pyus_out == NULL) + goto error; + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + error: + Py_XDECREF(pyus_in); + Py_XDECREF(ratio); + + return result; +} + +static PyObject * divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj) { PyObject *pyus_in; @@ -1712,6 +1765,55 @@ } static PyObject * +truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f) +{ + PyObject *result = NULL; + PyObject *pyus_in = NULL, *temp, *pyus_out; + PyObject *ratio = NULL; + + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL); + if (ratio == NULL) + goto error; + temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1)); + Py_DECREF(pyus_in); + pyus_in = NULL; + if (temp == NULL) + goto error; + pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0)); + Py_DECREF(temp); + if (pyus_out == NULL) + goto error; + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + error: + Py_XDECREF(pyus_in); + Py_XDECREF(ratio); + + return result; +} + +static PyObject * +truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i) +{ + PyObject *result; + PyObject *pyus_in, *pyus_out; + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + pyus_out = divide_nearest(pyus_in, i); + Py_DECREF(pyus_in); + if (pyus_out == NULL) + return NULL; + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + + return result; +} + +static PyObject * delta_add(PyObject *left, PyObject *right) { PyObject *result = Py_NotImplemented; @@ -1835,10 +1937,16 @@ if (PyLong_Check(right)) result = multiply_int_timedelta(right, (PyDateTime_Delta *) left); + else if (PyFloat_Check(right)) + result = multiply_float_timedelta(right, + (PyDateTime_Delta *) left); } else if (PyLong_Check(left)) result = multiply_int_timedelta(left, - (PyDateTime_Delta *) right); + (PyDateTime_Delta *) right); + else if (PyFloat_Check(left)) + result = multiply_float_timedelta(left, + (PyDateTime_Delta *) right); if (result == Py_NotImplemented) Py_INCREF(result); @@ -1877,6 +1985,12 @@ result = truedivide_timedelta_timedelta( (PyDateTime_Delta *)left, (PyDateTime_Delta *)right); + else if (PyFloat_Check(right)) + result = truedivide_timedelta_float( + (PyDateTime_Delta *)left, right); + else if (PyLong_Check(right)) + result = truedivide_timedelta_int( + (PyDateTime_Delta *)left, right); } if (result == Py_NotImplemented) @@ -3109,8 +3223,8 @@ PyDoc_STR("datetime -> string name of time zone.")}, {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O, - PyDoc_STR("datetime -> minutes east of UTC (negative for " - "west of UTC).")}, + PyDoc_STR("datetime -> timedelta showing offset from UTC, negative " + "values indicating West of UTC")}, {"dst", (PyCFunction)tzinfo_dst, METH_O, PyDoc_STR("datetime -> DST offset in minutes east of UTC.")}, Modified: python/branches/py3k-cdecimal/Modules/main.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/main.c (original) +++ python/branches/py3k-cdecimal/Modules/main.c Mon Jun 7 12:46:02 2010 @@ -425,7 +425,7 @@ #else if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') { char *buf, *oldloc; - wchar_t *warning; + PyObject *warning; /* settle for strtok here as there's no one standard C89 wcstok */ @@ -437,9 +437,10 @@ oldloc = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, ""); for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { - if ((warning = _Py_char2wchar(p)) != NULL) { - PySys_AddWarnOption(warning); - PyMem_Free(warning); + warning = PyUnicode_DecodeFSDefault(p); + if (warning != NULL) { + PySys_AddWarnOptionUnicode(warning); + Py_DECREF(warning); } } setlocale(LC_ALL, oldloc); Modified: python/branches/py3k-cdecimal/Modules/timemodule.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/timemodule.c (original) +++ python/branches/py3k-cdecimal/Modules/timemodule.c Mon Jun 7 12:46:02 2010 @@ -208,21 +208,27 @@ a floating point number for subsecond precision."); static PyStructSequence_Field struct_time_type_fields[] = { - {"tm_year", NULL}, - {"tm_mon", NULL}, - {"tm_mday", NULL}, - {"tm_hour", NULL}, - {"tm_min", NULL}, - {"tm_sec", NULL}, - {"tm_wday", NULL}, - {"tm_yday", NULL}, - {"tm_isdst", NULL}, + {"tm_year", "year, for example, 1993"}, + {"tm_mon", "month of year, range [1, 12]"}, + {"tm_mday", "day of month, range [1, 31]"}, + {"tm_hour", "hours, range [0, 23]"}, + {"tm_min", "minutes, range [0, 59]"}, + {"tm_sec", "seconds, range [0, 61])"}, + {"tm_wday", "day of week, range [0, 6], Monday is 0"}, + {"tm_yday", "day of year, range [1, 366]"}, + {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"}, {0} }; static PyStructSequence_Desc struct_time_type_desc = { "time.struct_time", - NULL, + "The time value as returned by gmtime(), localtime(), and strptime(), and\n" + " accepted by asctime(), mktime() and strftime(). May be considered as a\n" + " sequence of 9 integers.\n\n" + " Note that several fields' values are not the same as those defined by\n" + " the C language standard for struct tm. For example, the value of the\n" + " field tm_year is the actual year, not year - 1900. See individual\n" + " fields' descriptions for details.", struct_time_type_fields, 9, }; Modified: python/branches/py3k-cdecimal/Objects/abstract.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/abstract.c (original) +++ python/branches/py3k-cdecimal/Objects/abstract.c Mon Jun 7 12:46:02 2010 @@ -693,48 +693,37 @@ PyObject * PyObject_Format(PyObject *obj, PyObject *format_spec) { - static PyObject * str__format__ = NULL; PyObject *meth; PyObject *empty = NULL; PyObject *result = NULL; - - /* Initialize cached value */ - if (str__format__ == NULL) { - /* Initialize static variable needed by _PyType_Lookup */ - str__format__ = PyUnicode_FromString("__format__"); - if (str__format__ == NULL) - goto done; - } + static PyObject *format_cache = NULL; /* If no format_spec is provided, use an empty string */ if (format_spec == NULL) { - empty = PyUnicode_FromUnicode(NULL, 0); - format_spec = empty; + empty = PyUnicode_FromUnicode(NULL, 0); + format_spec = empty; } - /* Make sure the type is initialized. float gets initialized late */ - if (Py_TYPE(obj)->tp_dict == NULL) - if (PyType_Ready(Py_TYPE(obj)) < 0) - goto done; - /* Find the (unbound!) __format__ method (a borrowed reference) */ - meth = _PyType_Lookup(Py_TYPE(obj), str__format__); + meth = _PyObject_LookupSpecial(obj, "__format__", &format_cache); if (meth == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __format__", - Py_TYPE(obj)->tp_name); + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __format__", + Py_TYPE(obj)->tp_name); goto done; } - /* And call it, binding it to the value */ - result = PyObject_CallFunctionObjArgs(meth, obj, format_spec, NULL); + /* And call it. */ + result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL); + Py_DECREF(meth); if (result && !PyUnicode_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "__format__ method did not return string"); - Py_DECREF(result); - result = NULL; - goto done; + PyErr_SetString(PyExc_TypeError, + "__format__ method did not return string"); + Py_DECREF(result); + result = NULL; + goto done; } done: Modified: python/branches/py3k-cdecimal/Objects/complexobject.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/complexobject.c (original) +++ python/branches/py3k-cdecimal/Objects/complexobject.c Mon Jun 7 12:46:02 2010 @@ -403,12 +403,12 @@ static long complex_hash(PyComplexObject *v) { - long hashreal, hashimag, combined; - hashreal = _Py_HashDouble(v->cval.real); - if (hashreal == -1) + unsigned long hashreal, hashimag, combined; + hashreal = (unsigned long)_Py_HashDouble(v->cval.real); + if (hashreal == (unsigned long)-1) return -1; - hashimag = _Py_HashDouble(v->cval.imag); - if (hashimag == -1) + hashimag = (unsigned long)_Py_HashDouble(v->cval.imag); + if (hashimag == (unsigned long)-1) return -1; /* Note: if the imaginary part is 0, hashimag is 0 now, * so the following returns hashreal unchanged. This is @@ -416,10 +416,10 @@ * compare equal must have the same hash value, so that * hash(x + 0*j) must equal hash(x). */ - combined = hashreal + 1000003 * hashimag; - if (combined == -1) - combined = -2; - return combined; + combined = hashreal + _PyHASH_IMAG * hashimag; + if (combined == (unsigned long)-1) + combined = (unsigned long)-2; + return (long)combined; } /* This macro may return! */ @@ -620,22 +620,58 @@ complex_richcompare(PyObject *v, PyObject *w, int op) { PyObject *res; - Py_complex i, j; - TO_COMPLEX(v, i); - TO_COMPLEX(w, j); + Py_complex i; + int equal; if (op != Py_EQ && op != Py_NE) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + goto Unimplemented; + } + + assert(PyComplex_Check(v)); + TO_COMPLEX(v, i); + + if (PyLong_Check(w)) { + /* Check for 0.0 imaginary part first to avoid the rich + * comparison when possible. + */ + if (i.imag == 0.0) { + PyObject *j, *sub_res; + j = PyFloat_FromDouble(i.real); + if (j == NULL) + return NULL; + + sub_res = PyObject_RichCompare(j, w, op); + Py_DECREF(j); + return sub_res; + } + else { + equal = 0; + } } + else if (PyFloat_Check(w)) { + equal = (i.real == PyFloat_AsDouble(w) && i.imag == 0.0); + } + else if (PyComplex_Check(w)) { + Py_complex j; - if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ)) - res = Py_True; + TO_COMPLEX(w, j); + equal = (i.real == j.real && i.imag == j.imag); + } + else { + goto Unimplemented; + } + + if (equal == (op == Py_EQ)) + res = Py_True; else - res = Py_False; + res = Py_False; Py_INCREF(res); return res; + +Unimplemented: + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; } static PyObject * Modified: python/branches/py3k-cdecimal/Objects/longobject.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/longobject.c (original) +++ python/branches/py3k-cdecimal/Objects/longobject.c Mon Jun 7 12:46:02 2010 @@ -2571,18 +2571,37 @@ sign = -1; i = -(i); } - /* The following loop produces a C unsigned long x such that x is - congruent to the absolute value of v modulo ULONG_MAX. The - resulting x is nonzero if and only if v is. */ while (--i >= 0) { - /* Force a native long #-bits (32 or 64) circular shift */ - x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT); + /* Here x is a quantity in the range [0, _PyHASH_MODULUS); we + want to compute x * 2**PyLong_SHIFT + v->ob_digit[i] modulo + _PyHASH_MODULUS. + + The computation of x * 2**PyLong_SHIFT % _PyHASH_MODULUS + amounts to a rotation of the bits of x. To see this, write + + x * 2**PyLong_SHIFT = y * 2**_PyHASH_BITS + z + + where y = x >> (_PyHASH_BITS - PyLong_SHIFT) gives the top + PyLong_SHIFT bits of x (those that are shifted out of the + original _PyHASH_BITS bits, and z = (x << PyLong_SHIFT) & + _PyHASH_MODULUS gives the bottom _PyHASH_BITS - PyLong_SHIFT + bits of x, shifted up. Then since 2**_PyHASH_BITS is + congruent to 1 modulo _PyHASH_MODULUS, y*2**_PyHASH_BITS is + congruent to y modulo _PyHASH_MODULUS. So + + x * 2**PyLong_SHIFT = y + z (mod _PyHASH_MODULUS). + + The right-hand side is just the result of rotating the + _PyHASH_BITS bits of x left by PyLong_SHIFT places; since + not all _PyHASH_BITS bits of x are 1s, the same is true + after rotation, so 0 <= y+z < _PyHASH_MODULUS and y + z is + the reduction of x*2**PyLong_SHIFT modulo + _PyHASH_MODULUS. */ + x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) | + (x >> (_PyHASH_BITS - PyLong_SHIFT)); x += v->ob_digit[i]; - /* If the addition above overflowed we compensate by - incrementing. This preserves the value modulo - ULONG_MAX. */ - if (x < v->ob_digit[i]) - x++; + if (x >= _PyHASH_MODULUS) + x -= _PyHASH_MODULUS; } x = x * sign; if (x == (unsigned long)-1) @@ -4079,23 +4098,34 @@ static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *x = NULL; - int base = -909; /* unlikely! */ + PyObject *obase = NULL, *x = NULL; + long base; + int overflow; static char *kwlist[] = {"x", "base", 0}; if (type != &PyLong_Type) return long_subtype_new(type, args, kwds); /* Wimp out */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, - &x, &base)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:int", kwlist, + &x, &obase)) return NULL; if (x == NULL) return PyLong_FromLong(0L); - if (base == -909) + if (obase == NULL) return PyNumber_Long(x); - else if (PyUnicode_Check(x)) + + base = PyLong_AsLongAndOverflow(obase, &overflow); + if (base == -1 && PyErr_Occurred()) + return NULL; + if (overflow || (base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() arg 2 must be >= 2 and <= 36"); + return NULL; + } + + if (PyUnicode_Check(x)) return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x), PyUnicode_GET_SIZE(x), - base); + (int)base); else if (PyByteArray_Check(x) || PyBytes_Check(x)) { /* Since PyLong_FromString doesn't have a length parameter, * check here for possible NULs in the string. */ @@ -4110,10 +4140,10 @@ x is a bytes or buffer, *and* a base is given. */ PyErr_Format(PyExc_ValueError, "invalid literal for int() with base %d: %R", - base, x); + (int)base, x); return NULL; } - return PyLong_FromString(string, NULL, base); + return PyLong_FromString(string, NULL, (int)base); } else { PyErr_SetString(PyExc_TypeError, @@ -4182,140 +4212,169 @@ PyUnicode_GET_SIZE(format_spec)); } +/* Return a pair (q, r) such that a = b * q + r, and + abs(r) <= abs(b)/2, with equality possible only if q is even. + In other words, q == a / b, rounded to the nearest integer using + round-half-to-even. */ + +PyObject * +_PyLong_Divmod_Near(PyObject *a, PyObject *b) +{ + PyLongObject *quo = NULL, *rem = NULL; + PyObject *one = NULL, *twice_rem, *result, *temp; + int cmp, quo_is_odd, quo_is_neg; + + /* Equivalent Python code: + + def divmod_near(a, b): + q, r = divmod(a, b) + # round up if either r / b > 0.5, or r / b == 0.5 and q is odd. + # The expression r / b > 0.5 is equivalent to 2 * r > b if b is + # positive, 2 * r < b if b negative. + greater_than_half = 2*r > b if b > 0 else 2*r < b + exactly_half = 2*r == b + if greater_than_half or exactly_half and q % 2 == 1: + q += 1 + r -= b + return q, r + + */ + if (!PyLong_Check(a) || !PyLong_Check(b)) { + PyErr_SetString(PyExc_TypeError, + "non-integer arguments in division"); + return NULL; + } + + /* Do a and b have different signs? If so, quotient is negative. */ + quo_is_neg = (Py_SIZE(a) < 0) != (Py_SIZE(b) < 0); + + one = PyLong_FromLong(1L); + if (one == NULL) + return NULL; + + if (long_divrem((PyLongObject*)a, (PyLongObject*)b, &quo, &rem) < 0) + goto error; + + /* compare twice the remainder with the divisor, to see + if we need to adjust the quotient and remainder */ + twice_rem = long_lshift((PyObject *)rem, one); + if (twice_rem == NULL) + goto error; + if (quo_is_neg) { + temp = long_neg((PyLongObject*)twice_rem); + Py_DECREF(twice_rem); + twice_rem = temp; + if (twice_rem == NULL) + goto error; + } + cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b); + Py_DECREF(twice_rem); + + quo_is_odd = Py_SIZE(quo) != 0 && ((quo->ob_digit[0] & 1) != 0); + if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { + /* fix up quotient */ + if (quo_is_neg) + temp = long_sub(quo, (PyLongObject *)one); + else + temp = long_add(quo, (PyLongObject *)one); + Py_DECREF(quo); + quo = (PyLongObject *)temp; + if (quo == NULL) + goto error; + /* and remainder */ + if (quo_is_neg) + temp = long_add(rem, (PyLongObject *)b); + else + temp = long_sub(rem, (PyLongObject *)b); + Py_DECREF(rem); + rem = (PyLongObject *)temp; + if (rem == NULL) + goto error; + } + + result = PyTuple_New(2); + if (result == NULL) + goto error; + + /* PyTuple_SET_ITEM steals references */ + PyTuple_SET_ITEM(result, 0, (PyObject *)quo); + PyTuple_SET_ITEM(result, 1, (PyObject *)rem); + Py_DECREF(one); + return result; + + error: + Py_XDECREF(quo); + Py_XDECREF(rem); + Py_XDECREF(one); + return NULL; +} + static PyObject * long_round(PyObject *self, PyObject *args) { - PyObject *o_ndigits=NULL, *temp; - PyLongObject *pow=NULL, *q=NULL, *r=NULL, *ndigits=NULL, *one; - int errcode; - digit q_mod_4; - - /* Notes on the algorithm: to round to the nearest 10**n (n positive), - the straightforward method is: - - (1) divide by 10**n - (2) round to nearest integer (round to even in case of tie) - (3) multiply result by 10**n. - - But the rounding step involves examining the fractional part of the - quotient to see whether it's greater than 0.5 or not. Since we - want to do the whole calculation in integer arithmetic, it's - simpler to do: - - (1) divide by (10**n)/2 - (2) round to nearest multiple of 2 (multiple of 4 in case of tie) - (3) multiply result by (10**n)/2. - - Then all we need to know about the fractional part of the quotient - arising in step (2) is whether it's zero or not. - - Doing both a multiplication and division is wasteful, and is easily - avoided if we just figure out how much to adjust the original input - by to do the rounding. - - Here's the whole algorithm expressed in Python. - - def round(self, ndigits = None): - """round(int, int) -> int""" - if ndigits is None or ndigits >= 0: - return self - pow = 10**-ndigits >> 1 - q, r = divmod(self, pow) - self -= r - if (q & 1 != 0): - if (q & 2 == r == 0): - self -= pow - else: - self += pow - return self + PyObject *o_ndigits=NULL, *temp, *result, *ndigits; - */ + /* To round an integer m to the nearest 10**n (n positive), we make use of + * the divmod_near operation, defined by: + * + * divmod_near(a, b) = (q, r) + * + * where q is the nearest integer to the quotient a / b (the + * nearest even integer in the case of a tie) and r == a - q * b. + * Hence q * b = a - r is the nearest multiple of b to a, + * preferring even multiples in the case of a tie. + * + * So the nearest multiple of 10**n to m is: + * + * m - divmod_near(m, 10**n)[1]. + */ if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) return NULL; if (o_ndigits == NULL) return long_long(self); - ndigits = (PyLongObject *)PyNumber_Index(o_ndigits); + ndigits = PyNumber_Index(o_ndigits); if (ndigits == NULL) return NULL; + /* if ndigits >= 0 then no rounding is necessary; return self unchanged */ if (Py_SIZE(ndigits) >= 0) { Py_DECREF(ndigits); return long_long(self); } - Py_INCREF(self); /* to keep refcounting simple */ - /* we now own references to self, ndigits */ - - /* pow = 10 ** -ndigits >> 1 */ - pow = (PyLongObject *)PyLong_FromLong(10L); - if (pow == NULL) - goto error; - temp = long_neg(ndigits); + /* result = self - divmod_near(self, 10 ** -ndigits)[1] */ + temp = long_neg((PyLongObject*)ndigits); Py_DECREF(ndigits); - ndigits = (PyLongObject *)temp; + ndigits = temp; if (ndigits == NULL) - goto error; - temp = long_pow((PyObject *)pow, (PyObject *)ndigits, Py_None); - Py_DECREF(pow); - pow = (PyLongObject *)temp; - if (pow == NULL) - goto error; - assert(PyLong_Check(pow)); /* check long_pow returned a long */ - one = (PyLongObject *)PyLong_FromLong(1L); - if (one == NULL) - goto error; - temp = long_rshift(pow, one); - Py_DECREF(one); - Py_DECREF(pow); - pow = (PyLongObject *)temp; - if (pow == NULL) - goto error; + return NULL; - /* q, r = divmod(self, pow) */ - errcode = l_divmod((PyLongObject *)self, pow, &q, &r); - if (errcode == -1) - goto error; + result = PyLong_FromLong(10L); + if (result == NULL) { + Py_DECREF(ndigits); + return NULL; + } - /* self -= r */ - temp = long_sub((PyLongObject *)self, r); - Py_DECREF(self); - self = temp; - if (self == NULL) - goto error; + temp = long_pow(result, ndigits, Py_None); + Py_DECREF(ndigits); + Py_DECREF(result); + result = temp; + if (result == NULL) + return NULL; - /* get value of quotient modulo 4 */ - if (Py_SIZE(q) == 0) - q_mod_4 = 0; - else if (Py_SIZE(q) > 0) - q_mod_4 = q->ob_digit[0] & 3; - else - q_mod_4 = (PyLong_BASE-q->ob_digit[0]) & 3; + temp = _PyLong_Divmod_Near(self, result); + Py_DECREF(result); + result = temp; + if (result == NULL) + return NULL; - if ((q_mod_4 & 1) == 1) { - /* q is odd; round self up or down by adding or subtracting pow */ - if (q_mod_4 == 1 && Py_SIZE(r) == 0) - temp = (PyObject *)long_sub((PyLongObject *)self, pow); - else - temp = (PyObject *)long_add((PyLongObject *)self, pow); - Py_DECREF(self); - self = temp; - if (self == NULL) - goto error; - } - Py_DECREF(q); - Py_DECREF(r); - Py_DECREF(pow); - Py_DECREF(ndigits); - return self; + temp = long_sub((PyLongObject *)self, + (PyLongObject *)PyTuple_GET_ITEM(result, 1)); + Py_DECREF(result); + result = temp; - error: - Py_XDECREF(q); - Py_XDECREF(r); - Py_XDECREF(pow); - Py_XDECREF(self); - Py_XDECREF(ndigits); - return NULL; + return result; } static PyObject * Modified: python/branches/py3k-cdecimal/Objects/object.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/object.c (original) +++ python/branches/py3k-cdecimal/Objects/object.c Mon Jun 7 12:46:02 2010 @@ -647,63 +647,101 @@ All the utility functions (_Py_Hash*()) return "-1" to signify an error. */ +/* For numeric types, the hash of a number x is based on the reduction + of x modulo the prime P = 2**_PyHASH_BITS - 1. It's designed so that + hash(x) == hash(y) whenever x and y are numerically equal, even if + x and y have different types. + + A quick summary of the hashing strategy: + + (1) First define the 'reduction of x modulo P' for any rational + number x; this is a standard extension of the usual notion of + reduction modulo P for integers. If x == p/q (written in lowest + terms), the reduction is interpreted as the reduction of p times + the inverse of the reduction of q, all modulo P; if q is exactly + divisible by P then define the reduction to be infinity. So we've + got a well-defined map + + reduce : { rational numbers } -> { 0, 1, 2, ..., P-1, infinity }. + + (2) Now for a rational number x, define hash(x) by: + + reduce(x) if x >= 0 + -reduce(-x) if x < 0 + + If the result of the reduction is infinity (this is impossible for + integers, floats and Decimals) then use the predefined hash value + _PyHASH_INF for x >= 0, or -_PyHASH_INF for x < 0, instead. + _PyHASH_INF, -_PyHASH_INF and _PyHASH_NAN are also used for the + hashes of float and Decimal infinities and nans. + + A selling point for the above strategy is that it makes it possible + to compute hashes of decimal and binary floating-point numbers + efficiently, even if the exponent of the binary or decimal number + is large. The key point is that + + reduce(x * y) == reduce(x) * reduce(y) (modulo _PyHASH_MODULUS) + + provided that {reduce(x), reduce(y)} != {0, infinity}. The reduction of a + binary or decimal float is never infinity, since the denominator is a power + of 2 (for binary) or a divisor of a power of 10 (for decimal). So we have, + for nonnegative x, + + reduce(x * 2**e) == reduce(x) * reduce(2**e) % _PyHASH_MODULUS + + reduce(x * 10**e) == reduce(x) * reduce(10**e) % _PyHASH_MODULUS + + and reduce(10**e) can be computed efficiently by the usual modular + exponentiation algorithm. For reduce(2**e) it's even better: since + P is of the form 2**n-1, reduce(2**e) is 2**(e mod n), and multiplication + by 2**(e mod n) modulo 2**n-1 just amounts to a rotation of bits. + + */ + long _Py_HashDouble(double v) { - double intpart, fractpart; - int expo; - long hipart; - long x; /* the final hash value */ - /* This is designed so that Python numbers of different types - * that compare equal hash to the same value; otherwise comparisons - * of mapping keys will turn out weird. - */ + int e, sign; + double m; + unsigned long x, y; if (!Py_IS_FINITE(v)) { if (Py_IS_INFINITY(v)) - return v < 0 ? -271828 : 314159; + return v > 0 ? _PyHASH_INF : -_PyHASH_INF; else - return 0; + return _PyHASH_NAN; } - fractpart = modf(v, &intpart); - if (fractpart == 0.0) { - /* This must return the same hash as an equal int or long. */ - if (intpart > LONG_MAX/2 || -intpart > LONG_MAX/2) { - /* Convert to long and use its hash. */ - PyObject *plong; /* converted to Python long */ - plong = PyLong_FromDouble(v); - if (plong == NULL) - return -1; - x = PyObject_Hash(plong); - Py_DECREF(plong); - return x; - } - /* Fits in a C long == a Python int, so is its own hash. */ - x = (long)intpart; - if (x == -1) - x = -2; - return x; - } - /* The fractional part is non-zero, so we don't have to worry about - * making this match the hash of some other type. - * Use frexp to get at the bits in the double. - * Since the VAX D double format has 56 mantissa bits, which is the - * most of any double format in use, each of these parts may have as - * many as (but no more than) 56 significant bits. - * So, assuming sizeof(long) >= 4, each part can be broken into two - * longs; frexp and multiplication are used to do that. - * Also, since the Cray double format has 15 exponent bits, which is - * the most of any double format in use, shifting the exponent field - * left by 15 won't overflow a long (again assuming sizeof(long) >= 4). - */ - v = frexp(v, &expo); - v *= 2147483648.0; /* 2**31 */ - hipart = (long)v; /* take the top 32 bits */ - v = (v - (double)hipart) * 2147483648.0; /* get the next 32 bits */ - x = hipart + (long)v + (expo << 15); - if (x == -1) - x = -2; - return x; + + m = frexp(v, &e); + + sign = 1; + if (m < 0) { + sign = -1; + m = -m; + } + + /* process 28 bits at a time; this should work well both for binary + and hexadecimal floating point. */ + x = 0; + while (m) { + x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28); + m *= 268435456.0; /* 2**28 */ + e -= 28; + y = (unsigned long)m; /* pull out integer part */ + m -= y; + x += y; + if (x >= _PyHASH_MODULUS) + x -= _PyHASH_MODULUS; + } + + /* adjust for the exponent; first reduce it modulo _PyHASH_BITS */ + e = e >= 0 ? e % _PyHASH_BITS : _PyHASH_BITS-1-((-1-e) % _PyHASH_BITS); + x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e); + + x = x * sign; + if (x == (unsigned long)-1) + x = (unsigned long)-2; + return (long)x; } long @@ -950,31 +988,7 @@ goto done; } -#if 0 /* XXX this is not quite _PyType_Lookup anymore */ - /* Inline _PyType_Lookup */ - { - Py_ssize_t i, n; - PyObject *mro, *base, *dict; - - /* Look in tp_dict of types in MRO */ - mro = tp->tp_mro; - assert(mro != NULL); - assert(PyTuple_Check(mro)); - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - base = PyTuple_GET_ITEM(mro, i); - assert(PyType_Check(base)); - dict = ((PyTypeObject *)base)->tp_dict; - assert(dict && PyDict_Check(dict)); - descr = PyDict_GetItem(dict, name); - if (descr != NULL) - break; - } - } -#else descr = _PyType_Lookup(tp, name); -#endif - Py_XINCREF(descr); f = NULL; Modified: python/branches/py3k-cdecimal/Objects/typeobject.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/typeobject.c (original) +++ python/branches/py3k-cdecimal/Objects/typeobject.c Mon Jun 7 12:46:02 2010 @@ -3310,23 +3310,15 @@ PyObject *format_spec; PyObject *self_as_str = NULL; PyObject *result = NULL; - PyObject *format_meth = NULL; if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) return NULL; self_as_str = PyObject_Str(self); - if (self_as_str != NULL) { - /* find the format function */ - format_meth = PyObject_GetAttrString(self_as_str, "__format__"); - if (format_meth != NULL) { - /* and call it */ - result = PyObject_CallFunctionObjArgs(format_meth, format_spec, NULL); - } - } + if (self_as_str != NULL) + result = PyObject_Format(self_as_str, format_spec); Py_XDECREF(self_as_str); - Py_XDECREF(format_meth); return result; } @@ -4921,6 +4913,7 @@ PyObject *func, *res; static PyObject *hash_str; long h; + int overflow; func = lookup_method(self, "__hash__", &hash_str); @@ -4937,14 +4930,27 @@ Py_DECREF(func); if (res == NULL) return -1; - if (PyLong_Check(res)) + + if (!PyLong_Check(res)) { + PyErr_SetString(PyExc_TypeError, + "__hash__ method should return an integer"); + return -1; + } + /* Transform the PyLong `res` to a C long `h`. For an existing + hashable Python object x, hash(x) will always lie within the range + of a C long. Therefore our transformation must preserve values + that already lie within this range, to ensure that if x.__hash__() + returns hash(y) then hash(x) == hash(y). */ + h = PyLong_AsLongAndOverflow(res, &overflow); + if (overflow) + /* res was not within the range of a C long, so we're free to + use any sufficiently bit-mixing transformation; + long.__hash__ will do nicely. */ h = PyLong_Type.tp_hash(res); - else - h = PyLong_AsLong(res); Py_DECREF(res); - if (h == -1 && !PyErr_Occurred()) - h = -2; - return h; + if (h == -1 && !PyErr_Occurred()) + h = -2; + return h; } static PyObject * Modified: python/branches/py3k-cdecimal/PC/winreg.c ============================================================================== --- python/branches/py3k-cdecimal/PC/winreg.c (original) +++ python/branches/py3k-cdecimal/PC/winreg.c Mon Jun 7 12:46:02 2010 @@ -1096,7 +1096,14 @@ int index; long rc; PyObject *retStr; - wchar_t tmpbuf[256]; /* max key name length is 255 */ + + /* The Windows docs claim that the max key name length is 255 + * characters, plus a terminating nul character. However, + * empirical testing demonstrates that it is possible to + * create a 256 character key that is missing the terminating + * nul. RegEnumKeyEx requires a 257 character buffer to + * retrieve such a key name. */ + wchar_t tmpbuf[257]; DWORD len = sizeof(tmpbuf); /* includes NULL terminator */ if (!PyArg_ParseTuple(args, "Oi:EnumKey", &obKey, &index)) @@ -1123,8 +1130,8 @@ long rc; wchar_t *retValueBuf; BYTE *retDataBuf; - DWORD retValueSize; - DWORD retDataSize; + DWORD retValueSize, bufValueSize; + DWORD retDataSize, bufDataSize; DWORD typ; PyObject *obData; PyObject *retVal; @@ -1142,6 +1149,8 @@ "RegQueryInfoKey"); ++retValueSize; /* include null terminators */ ++retDataSize; + bufDataSize = retDataSize; + bufValueSize = retValueSize; retValueBuf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t) * retValueSize); if (retValueBuf == NULL) return PyErr_NoMemory(); @@ -1151,16 +1160,33 @@ return PyErr_NoMemory(); } - Py_BEGIN_ALLOW_THREADS - rc = RegEnumValueW(hKey, - index, - retValueBuf, - &retValueSize, - NULL, - &typ, - retDataBuf, - &retDataSize); - Py_END_ALLOW_THREADS + while (1) { + wchar_t *tmp; + Py_BEGIN_ALLOW_THREADS + rc = RegEnumValueW(hKey, + index, + retValueBuf, + &retValueSize, + NULL, + &typ, + (BYTE *)retDataBuf, + &retDataSize); + Py_END_ALLOW_THREADS + + if (rc != ERROR_MORE_DATA) + break; + + bufDataSize *= 2; + tmp = (char *)PyMem_Realloc(retDataBuf, bufDataSize); + if (tmp == NULL) { + PyErr_NoMemory(); + retVal = NULL; + goto fail; + } + retDataBuf = tmp; + retDataSize = bufDataSize; + retValueSize = bufValueSize; + } if (rc != ERROR_SUCCESS) { retVal = PyErr_SetFromWindowsErrWithFunction(rc, @@ -1317,23 +1343,44 @@ long rc; PyObject *retStr; wchar_t *retBuf; - long bufSize = 0; + DWORD bufSize = 0; + DWORD retSize = 0; + wchar_t *tmp; if (!PyArg_ParseTuple(args, "OZ:QueryValue", &obKey, &subKey)) return NULL; if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) return NULL; - if ((rc = RegQueryValueW(hKey, subKey, NULL, &bufSize)) - != ERROR_SUCCESS) + + rc = RegQueryValueW(hKey, subKey, NULL, &retSize); + if (rc == ERROR_MORE_DATA) + retSize = 256; + else if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValue"); - retBuf = (wchar_t *)PyMem_Malloc(bufSize); + + bufSize = retSize; + retBuf = (wchar_t *) PyMem_Malloc(bufSize); if (retBuf == NULL) return PyErr_NoMemory(); - if ((rc = RegQueryValueW(hKey, subKey, retBuf, &bufSize)) - != ERROR_SUCCESS) { + while (1) { + retSize = bufSize; + rc = RegQueryValueW(hKey, subKey, retBuf, &retSize); + if (rc != ERROR_MORE_DATA) + break; + + bufSize *= 2; + tmp = (wchar_t *) PyMem_Realloc(retBuf, bufSize); + if (tmp == NULL) { + PyMem_Free(retBuf); + return PyErr_NoMemory(); + } + retBuf = tmp; + } + + if (rc != ERROR_SUCCESS) { PyMem_Free(retBuf); return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValue"); @@ -1352,8 +1399,8 @@ wchar_t *valueName; long rc; - BYTE *retBuf; - DWORD bufSize = 0; + BYTE *retBuf, *tmp; + DWORD bufSize = 0, retSize; DWORD typ; PyObject *obData; PyObject *result; @@ -1363,18 +1410,34 @@ if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) return NULL; - if ((rc = RegQueryValueExW(hKey, valueName, - NULL, NULL, NULL, - &bufSize)) - != ERROR_SUCCESS) + + rc = RegQueryValueExW(hKey, valueName, NULL, NULL, NULL, &bufSize); + if (rc == ERROR_MORE_DATA) + bufSize = 256; + else if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValueEx"); retBuf = (BYTE *)PyMem_Malloc(bufSize); if (retBuf == NULL) return PyErr_NoMemory(); - if ((rc = RegQueryValueExW(hKey, valueName, NULL, - &typ, retBuf, &bufSize)) - != ERROR_SUCCESS) { + + while (1) { + retSize = bufSize; + rc = RegQueryValueExW(hKey, valueName, NULL, &typ, + (BYTE *)retBuf, &retSize); + if (rc != ERROR_MORE_DATA) + break; + + bufSize *= 2; + tmp = (char *) PyMem_Realloc(retBuf, bufSize); + if (tmp == NULL) { + PyMem_Free(retBuf); + return PyErr_NoMemory(); + } + retBuf = tmp; + } + + if (rc != ERROR_SUCCESS) { PyMem_Free(retBuf); return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValueEx"); Modified: python/branches/py3k-cdecimal/Python/_warnings.c ============================================================================== --- python/branches/py3k-cdecimal/Python/_warnings.c (original) +++ python/branches/py3k-cdecimal/Python/_warnings.c Mon Jun 7 12:46:02 2010 @@ -116,7 +116,7 @@ _filters = warnings_filters; } - if (!PyList_Check(_filters)) { + if (_filters == NULL || !PyList_Check(_filters)) { PyErr_SetString(PyExc_ValueError, MODULE_NAME ".filters must be a list"); return NULL; Modified: python/branches/py3k-cdecimal/Python/ceval.c ============================================================================== --- python/branches/py3k-cdecimal/Python/ceval.c (original) +++ python/branches/py3k-cdecimal/Python/ceval.c Mon Jun 7 12:46:02 2010 @@ -598,7 +598,7 @@ } pendingcalls[NPENDINGCALLS]; static volatile int pendingfirst = 0; static volatile int pendinglast = 0; -static volatile int pendingcalls_to_do = 0; +static _Py_atomic_int pendingcalls_to_do = {0}; int Py_AddPendingCall(int (*func)(void *), void *arg) Modified: python/branches/py3k-cdecimal/Python/getargs.c ============================================================================== --- python/branches/py3k-cdecimal/Python/getargs.c (original) +++ python/branches/py3k-cdecimal/Python/getargs.c Mon Jun 7 12:46:02 2010 @@ -1029,18 +1029,7 @@ else return converterr("string or None", arg, msgbuf, bufsize); - if (*format == '#') { - FETCH_SIZE; - assert(0); /* XXX redundant with if-case */ - if (arg == Py_None) { - STORE_SIZE(0); - } - else { - STORE_SIZE(PyBytes_Size(arg)); - } - format++; - } - else if (*p != NULL && uarg != NULL && + if (*p != NULL && uarg != NULL && (Py_ssize_t) strlen(*p) != PyBytes_GET_SIZE(uarg)) return converterr( "string without null bytes or None", @@ -1183,6 +1172,7 @@ *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); + PyErr_NoMemory(); return converterr( "(memory error)", arg, msgbuf, bufsize); @@ -1226,6 +1216,7 @@ *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); + PyErr_NoMemory(); return converterr("(memory error)", arg, msgbuf, bufsize); } @@ -1293,17 +1284,6 @@ return converterr(type->tp_name, arg, msgbuf, bufsize); } - else if (*format == '?') { - inquiry pred = va_arg(*p_va, inquiry); - p = va_arg(*p_va, PyObject **); - format++; - if ((*pred)(arg)) - *p = arg; - else - return converterr("(unspecified)", - arg, msgbuf, bufsize); - - } else if (*format == '&') { typedef int (*converter)(PyObject *, void *); converter convert = va_arg(*p_va, converter); @@ -1432,7 +1412,7 @@ static Py_ssize_t convertbuffer(PyObject *arg, void **p, char **errmsg) { - PyBufferProcs *pb = arg->ob_type->tp_as_buffer; + PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; Py_ssize_t count; Py_buffer view; @@ -1460,31 +1440,23 @@ static int getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) { - void *buf; - Py_ssize_t count; - PyBufferProcs *pb = arg->ob_type->tp_as_buffer; + PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; if (pb == NULL) { *errmsg = "bytes or buffer"; return -1; } - if (pb->bf_getbuffer) { - if (PyObject_GetBuffer(arg, view, 0) < 0) { - *errmsg = "convertible to a buffer"; - return -1; - } - if (!PyBuffer_IsContiguous(view, 'C')) { - *errmsg = "contiguous buffer"; - return -1; - } - return 0; + if (pb->bf_getbuffer == NULL) { + *errmsg = "convertible to a buffer"; + return -1; } - - count = convertbuffer(arg, &buf, errmsg); - if (count < 0) { + if (PyObject_GetBuffer(arg, view, 0) < 0) { *errmsg = "convertible to a buffer"; - return count; + return -1; + } + if (!PyBuffer_IsContiguous(view, 'C')) { + *errmsg = "contiguous buffer"; + return -1; } - PyBuffer_FillInfo(view, NULL, buf, count, 1, 0); return 0; } Modified: python/branches/py3k-cdecimal/Python/pythonrun.c ============================================================================== --- python/branches/py3k-cdecimal/Python/pythonrun.c (original) +++ python/branches/py3k-cdecimal/Python/pythonrun.c Mon Jun 7 12:46:02 2010 @@ -265,13 +265,15 @@ _PyImportHooks_Init(); + /* Initialize _warnings. */ + _PyWarnings_Init(); + initfsencoding(); if (install_sigs) initsigs(); /* Signal handling stuff, including initintr() */ /* Initialize warnings. */ - _PyWarnings_Init(); if (PySys_HasWarnOptions()) { PyObject *warnings_module = PyImport_ImportModule("warnings"); if (!warnings_module) @@ -1384,10 +1386,12 @@ exitcode = (int)PyLong_AsLong(value); else { PyObject *sys_stderr = PySys_GetObject("stderr"); - if (sys_stderr != NULL) - PyObject_CallMethod(sys_stderr, "flush", NULL); - PyObject_Print(value, stderr, Py_PRINT_RAW); - fflush(stderr); + if (sys_stderr != NULL && sys_stderr != Py_None) { + PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW); + } else { + PyObject_Print(value, stderr, Py_PRINT_RAW); + fflush(stderr); + } PySys_WriteStderr("\n"); exitcode = 1; } Modified: python/branches/py3k-cdecimal/Python/sysmodule.c ============================================================================== --- python/branches/py3k-cdecimal/Python/sysmodule.c (original) +++ python/branches/py3k-cdecimal/Python/sysmodule.c Mon Jun 7 12:46:02 2010 @@ -570,6 +570,57 @@ return Py_None; } +static PyTypeObject Hash_InfoType; + +PyDoc_STRVAR(hash_info_doc, +"hash_info\n\ +\n\ +A struct sequence providing parameters used for computing\n\ +numeric hashes. The attributes are read only."); + +static PyStructSequence_Field hash_info_fields[] = { + {"width", "width of the type used for hashing, in bits"}, + {"modulus", "prime number giving the modulus on which the hash " + "function is based"}, + {"inf", "value to be used for hash of a positive infinity"}, + {"nan", "value to be used for hash of a nan"}, + {"imag", "multiplier used for the imaginary part of a complex number"}, + {NULL, NULL} +}; + +static PyStructSequence_Desc hash_info_desc = { + "sys.hash_info", + hash_info_doc, + hash_info_fields, + 5, +}; + +PyObject * +get_hash_info(void) +{ + PyObject *hash_info; + int field = 0; + hash_info = PyStructSequence_New(&Hash_InfoType); + if (hash_info == NULL) + return NULL; + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(8*sizeof(long))); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(_PyHASH_MODULUS)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(_PyHASH_INF)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(_PyHASH_NAN)); + PyStructSequence_SET_ITEM(hash_info, field++, + PyLong_FromLong(_PyHASH_IMAG)); + if (PyErr_Occurred()) { + Py_CLEAR(hash_info); + return NULL; + } + return hash_info; +} + + PyDoc_STRVAR(setrecursionlimit_doc, "setrecursionlimit(n)\n\ \n\ @@ -1048,21 +1099,26 @@ } void -PySys_AddWarnOption(const wchar_t *s) +PySys_AddWarnOptionUnicode(PyObject *unicode) { - PyObject *str; - if (warnoptions == NULL || !PyList_Check(warnoptions)) { Py_XDECREF(warnoptions); warnoptions = PyList_New(0); if (warnoptions == NULL) return; } - str = PyUnicode_FromWideChar(s, -1); - if (str != NULL) { - PyList_Append(warnoptions, str); - Py_DECREF(str); - } + PyList_Append(warnoptions, unicode); +} + +void +PySys_AddWarnOption(const wchar_t *s) +{ + PyObject *unicode; + unicode = PyUnicode_FromWideChar(s, -1); + if (unicode == NULL) + return; + PySys_AddWarnOptionUnicode(unicode); + Py_DECREF(unicode); } int @@ -1477,6 +1533,11 @@ PyFloat_GetInfo()); SET_SYS_FROM_STRING("int_info", PyLong_GetInfo()); + /* initialize hash_info */ + if (Hash_InfoType.tp_name == 0) + PyStructSequence_InitType(&Hash_InfoType, &hash_info_desc); + SET_SYS_FROM_STRING("hash_info", + get_hash_info()); SET_SYS_FROM_STRING("maxunicode", PyLong_FromLong(PyUnicode_GetMax())); SET_SYS_FROM_STRING("builtin_module_names", @@ -1663,7 +1724,7 @@ #endif void -PySys_SetArgv(int argc, wchar_t **argv) +PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) { #if defined(HAVE_REALPATH) wchar_t fullpath[MAXPATHLEN]; @@ -1676,7 +1737,7 @@ Py_FatalError("no mem for sys.argv"); if (PySys_SetObject("argv", av) != 0) Py_FatalError("can't assign sys.argv"); - if (path != NULL) { + if (updatepath && path != NULL) { wchar_t *argv0 = argv[0]; wchar_t *p = NULL; Py_ssize_t n = 0; @@ -1763,6 +1824,12 @@ Py_DECREF(av); } +void +PySys_SetArgv(int argc, wchar_t **argv) +{ + PySys_SetArgvEx(argc, argv, 1); +} + /* Reimplementation of PyFile_WriteString() no calling indirectly PyErr_CheckSignals(): avoid the call to PyObject_Str(). */ Modified: python/branches/py3k-cdecimal/Tools/gdb/libpython.py ============================================================================== --- python/branches/py3k-cdecimal/Tools/gdb/libpython.py (original) +++ python/branches/py3k-cdecimal/Tools/gdb/libpython.py Mon Jun 7 12:46:02 2010 @@ -42,6 +42,7 @@ ''' from __future__ import with_statement import gdb +import locale # Look up the gdb.Type for some standard types: _type_char_ptr = gdb.lookup_type('char').pointer() # char* @@ -69,6 +70,7 @@ hexdigits = "0123456789abcdef" +ENCODING = locale.getpreferredencoding() class NullPyObjectPtr(RuntimeError): pass @@ -1128,53 +1130,68 @@ # Non-ASCII characters else: - ucs = ch; - - if self.char_width == 2: - ch2 = 0 + ucs = ch + orig_ucs = None + if self.char_width() == 2: # Get code point from surrogate pair - if i < len(proxy): + if (i < len(proxy) + and 0xD800 <= ord(ch) < 0xDC00 \ + and 0xDC00 <= ord(proxy[i]) <= 0xDFFF): ch2 = proxy[i] - if (ord(ch) >= 0xD800 and ord(ch) < 0xDC00 - and ord(ch2) >= 0xDC00 and ord(ch2) <= 0xDFFF): - ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000; - i += 1 + code = (ord(ch) & 0x03FF) << 10 + code |= ord(ch2) & 0x03FF + code += 0x00010000 + orig_ucs = ucs + ucs = unichr(code) + i += 1 + else: + ch2 = None + + printable = _unichr_is_printable(ucs) + if printable: + try: + ucs.encode(ENCODING) + except UnicodeEncodeError: + printable = False + if orig_ucs is not None: + ucs = orig_ucs + i -= 1 # Map Unicode whitespace and control characters # (categories Z* and C* except ASCII space) - if not _unichr_is_printable(ucs): + if not printable: # Unfortuately, Python 2's unicode type doesn't seem # to expose the "isprintable" method + code = ord(ucs) # Map 8-bit characters to '\\xhh' - if ucs <= 0xff: + if code <= 0xff: out.write('\\x') - out.write(hexdigits[(ord(ucs) >> 4) & 0x000F]) - out.write(hexdigits[ord(ucs) & 0x000F]) + out.write(hexdigits[(code >> 4) & 0x000F]) + out.write(hexdigits[code & 0x000F]) # Map 21-bit characters to '\U00xxxxxx' - elif ucs >= 0x10000: + elif code >= 0x10000: out.write('\\U') - out.write(hexdigits[(ord(ucs) >> 28) & 0x0000000F]) - out.write(hexdigits[(ord(ucs) >> 24) & 0x0000000F]) - out.write(hexdigits[(ord(ucs) >> 20) & 0x0000000F]) - out.write(hexdigits[(ord(ucs) >> 16) & 0x0000000F]) - out.write(hexdigits[(ord(ucs) >> 12) & 0x0000000F]) - out.write(hexdigits[(ord(ucs) >> 8) & 0x0000000F]) - out.write(hexdigits[(ord(ucs) >> 4) & 0x0000000F]) - out.write(hexdigits[ord(ucs) & 0x0000000F]) + out.write(hexdigits[(code >> 28) & 0x0000000F]) + out.write(hexdigits[(code >> 24) & 0x0000000F]) + out.write(hexdigits[(code >> 20) & 0x0000000F]) + out.write(hexdigits[(code >> 16) & 0x0000000F]) + out.write(hexdigits[(code >> 12) & 0x0000000F]) + out.write(hexdigits[(code >> 8) & 0x0000000F]) + out.write(hexdigits[(code >> 4) & 0x0000000F]) + out.write(hexdigits[code & 0x0000000F]) # Map 16-bit characters to '\uxxxx' else: out.write('\\u') - out.write(hexdigits[(ord(ucs) >> 12) & 0x000F]) - out.write(hexdigits[(ord(ucs) >> 8) & 0x000F]) - out.write(hexdigits[(ord(ucs) >> 4) & 0x000F]) - out.write(hexdigits[ord(ucs) & 0x000F]) + out.write(hexdigits[(code >> 12) & 0x000F]) + out.write(hexdigits[(code >> 8) & 0x000F]) + out.write(hexdigits[(code >> 4) & 0x000F]) + out.write(hexdigits[code & 0x000F]) else: # Copy characters as-is out.write(ch) - if self.char_width == 2: - if ord(ucs) >= 0x10000: - out.write(ch2) + if self.char_width() == 2 and (ch2 is not None): + out.write(ch2) out.write(quote) Modified: python/branches/py3k-cdecimal/Tools/i18n/msgfmt.py ============================================================================== --- python/branches/py3k-cdecimal/Tools/i18n/msgfmt.py (original) +++ python/branches/py3k-cdecimal/Tools/i18n/msgfmt.py Mon Jun 7 12:46:02 2010 @@ -30,6 +30,7 @@ import getopt import struct import array +from email.parser import HeaderParser __version__ = "1.1" @@ -59,13 +60,13 @@ # the keys are sorted in the .mo file keys = sorted(MESSAGES.keys()) offsets = [] - ids = strs = '' + ids = strs = b'' for id in keys: # For each string, we need size and file offset. Each string is NUL # terminated; the NUL does not count into the size. offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) - ids += id + '\0' - strs += MESSAGES[id] + '\0' + ids += id + b'\0' + strs += MESSAGES[id] + b'\0' output = '' # The header is 7 32-bit unsigned integers. We don't use hash tables, so # the keys start right after the index tables. @@ -108,7 +109,7 @@ outfile = os.path.splitext(infile)[0] + '.mo' try: - lines = open(infile).readlines() + lines = open(infile, 'rb').readlines() except IOError as msg: print(msg, file=sys.stderr) sys.exit(1) @@ -116,9 +117,14 @@ section = None fuzzy = 0 + # Start off assuming Latin-1, so everything decodes without failure, + # until we know the exact encoding + encoding = 'latin-1' + # Parse the catalog lno = 0 for l in lines: + l = l.decode(encoding) lno += 1 # If we get a comment line after a msgstr, this is a new entry if l[0] == '#' and section == STR: @@ -132,16 +138,45 @@ if l[0] == '#': continue # Now we are in a msgid section, output previous section - if l.startswith('msgid'): + if l.startswith('msgid') and not l.startswith('msgid_plural'): if section == STR: add(msgid, msgstr, fuzzy) + if not msgid: + # See whether there is an encoding declaration + p = HeaderParser() + charset = p.parsestr(msgstr.decode(encoding)).get_content_charset() + if charset: + encoding = charset section = ID l = l[5:] - msgid = msgstr = '' + msgid = msgstr = b'' + is_plural = False + # This is a message with plural forms + elif l.startswith('msgid_plural'): + if section != ID: + print('msgid_plural not preceeded by msgid on %s:%d' % (infile, lno), + file=sys.stderr) + sys.exit(1) + l = l[12:] + msgid += b'\0' # separator of singular and plural + is_plural = True # Now we are in a msgstr section elif l.startswith('msgstr'): section = STR - l = l[6:] + if l.startswith('msgstr['): + if not is_plural: + print(sys.stderr, 'plural without msgid_plural on %s:%d' % (infile, lno), + file=sys.stderr) + sys.exit(1) + l = l.split(']', 1)[1] + if msgstr: + msgstr += b'\0' # Separator of the various plural forms + else: + if is_plural: + print(sys.stderr, 'indexed msgstr required for plural on %s:%d' % (infile, lno), + file=sys.stderr) + sys.exit(1) + l = l[6:] # Skip empty lines l = l.strip() if not l: @@ -149,9 +184,9 @@ # XXX: Does this always follow Python escape semantics? l = eval(l) if section == ID: - msgid += l + msgid += l.encode(encoding) elif section == STR: - msgstr += l + msgstr += l.encode(encoding) else: print('Syntax error on %s:%d' % (infile, lno), \ 'before:', file=sys.stderr) Modified: python/branches/py3k-cdecimal/Tools/scripts/serve.py ============================================================================== --- python/branches/py3k-cdecimal/Tools/scripts/serve.py (original) +++ python/branches/py3k-cdecimal/Tools/scripts/serve.py Mon Jun 7 12:46:02 2010 @@ -28,5 +28,8 @@ path = sys.argv[1] port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000 httpd = simple_server.make_server('', port, app) - print("Serving {} on port {}".format(path, port)) - httpd.serve_forever() + print("Serving {} on port {}, control-C to stop".format(path, port)) + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("\b\bShutting down.") Modified: python/branches/py3k-cdecimal/configure ============================================================================== --- python/branches/py3k-cdecimal/configure (original) +++ python/branches/py3k-cdecimal/configure Mon Jun 7 12:46:02 2010 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 80834 . +# From configure.in Revision: 81078 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65 for python 3.2. # @@ -1929,11 +1929,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default - enum { N = $2 / 2 - 1 }; int main () { -static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +static int test_array [1 - 2 * !(enum { N = $2 / 2 - 1 }; + 0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; test_array [0] = 0 ; @@ -1944,11 +1944,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default - enum { N = $2 / 2 - 1 }; int main () { -static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) +static int test_array [1 - 2 * !(enum { N = $2 / 2 - 1 }; + ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; test_array [0] = 0 @@ -3013,9 +3013,12 @@ # Marc Recht NetBSD/1.5 | NetBSD/1.5.* | NetBSD/1.6 | NetBSD/1.6.* | NetBSD/1.6[A-S]) define_xopen_source=no;; - # On Solaris 2.6, sys/wait.h is inconsistent in the usage - # of union __?sigval. Reported by Stuart Bishop. - SunOS/5.6) + # From the perspective of Solaris, _XOPEN_SOURCE is not so much a + # request to enable features supported by the standard as a request + # to disable features not supported by the standard. The best way + # for Python to use Solaris is simply to leave _XOPEN_SOURCE out + # entirely and define __EXTENSIONS__ instead. + SunOS/*) define_xopen_source=no;; # On UnixWare 7, u_long is never defined with _XOPEN_SOURCE, # but used in /usr/include/netinet/tcp.h. Reported by Tim Rice. @@ -3061,38 +3064,17 @@ if test $define_xopen_source = yes then - # On Solaris w/ g++ it appears that _XOPEN_SOURCE has to be - # defined precisely as g++ defines it - # Furthermore, on Solaris 10, XPG6 requires the use of a C99 - # compiler - case $ac_sys_system/$ac_sys_release in - SunOS/5.8|SunOS/5.9|SunOS/5.10) - -$as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h - - ;; - *) $as_echo "#define _XOPEN_SOURCE 600" >>confdefs.h - ;; - esac # On Tru64 Unix 4.0F, defining _XOPEN_SOURCE also requires # definition of _XOPEN_SOURCE_EXTENDED and _POSIX_C_SOURCE, or else # several APIs are not declared. Since this is also needed in some # cases for HP-UX, we define it globally. - # except for Solaris 10, where it must not be defined, - # as it implies XPG4.2 - case $ac_sys_system/$ac_sys_release in - SunOS/5.10) - ;; - *) $as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h - ;; - esac $as_echo "#define _POSIX_C_SOURCE 200112L" >>confdefs.h Modified: python/branches/py3k-cdecimal/configure.in ============================================================================== --- python/branches/py3k-cdecimal/configure.in (original) +++ python/branches/py3k-cdecimal/configure.in Mon Jun 7 12:46:02 2010 @@ -330,9 +330,12 @@ # Marc Recht NetBSD/1.5 | NetBSD/1.5.* | NetBSD/1.6 | NetBSD/1.6.* | NetBSD/1.6@<:@A-S@:>@) define_xopen_source=no;; - # On Solaris 2.6, sys/wait.h is inconsistent in the usage - # of union __?sigval. Reported by Stuart Bishop. - SunOS/5.6) + # From the perspective of Solaris, _XOPEN_SOURCE is not so much a + # request to enable features supported by the standard as a request + # to disable features not supported by the standard. The best way + # for Python to use Solaris is simply to leave _XOPEN_SOURCE out + # entirely and define __EXTENSIONS__ instead. + SunOS/*) define_xopen_source=no;; # On UnixWare 7, u_long is never defined with _XOPEN_SOURCE, # but used in /usr/include/netinet/tcp.h. Reported by Tim Rice. @@ -378,35 +381,15 @@ if test $define_xopen_source = yes then - # On Solaris w/ g++ it appears that _XOPEN_SOURCE has to be - # defined precisely as g++ defines it - # Furthermore, on Solaris 10, XPG6 requires the use of a C99 - # compiler - case $ac_sys_system/$ac_sys_release in - SunOS/5.8|SunOS/5.9|SunOS/5.10) - AC_DEFINE(_XOPEN_SOURCE, 500, - Define to the level of X/Open that your system supports) - ;; - *) - AC_DEFINE(_XOPEN_SOURCE, 600, - Define to the level of X/Open that your system supports) - ;; - esac + AC_DEFINE(_XOPEN_SOURCE, 600, + Define to the level of X/Open that your system supports) # On Tru64 Unix 4.0F, defining _XOPEN_SOURCE also requires # definition of _XOPEN_SOURCE_EXTENDED and _POSIX_C_SOURCE, or else # several APIs are not declared. Since this is also needed in some # cases for HP-UX, we define it globally. - # except for Solaris 10, where it must not be defined, - # as it implies XPG4.2 - case $ac_sys_system/$ac_sys_release in - SunOS/5.10) - ;; - *) - AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, - Define to activate Unix95-and-earlier features) - ;; - esac + AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, + Define to activate Unix95-and-earlier features) AC_DEFINE(_POSIX_C_SOURCE, 200112L, Define to activate features from IEEE Stds 1003.1-2001) Modified: python/branches/py3k-cdecimal/setup.py ============================================================================== --- python/branches/py3k-cdecimal/setup.py (original) +++ python/branches/py3k-cdecimal/setup.py Mon Jun 7 12:46:02 2010 @@ -28,6 +28,25 @@ if dir is not None and os.path.isdir(dir) and dir not in dirlist: dirlist.insert(0, dir) +def macosx_sdk_root(): + """ + Return the directory of the current OSX SDK, + or '/' if no SDK was specified. + """ + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + return sysroot + +def is_macosx_sdk_path(path): + """ + Returns True if 'path' can be located in an OSX SDK + """ + return path.startswith('/usr/') or path.startswith('/System/') + def find_file(filename, std_dirs, paths): """Searches for the directory where a given file is located, and returns a possibly-empty list of additional directories, or None @@ -39,15 +58,28 @@ 'paths' is a list of additional locations to check; if the file is found in one of them, the resulting list will contain the directory. """ + if sys.platform == 'darwin': + # Honor the MacOSX SDK setting when one was specified. + # An SDK is a directory with the same structure as a real + # system, but with only header files and libraries. + sysroot = macosx_sdk_root() # Check the standard locations for dir in std_dirs: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [] # Check the additional directories for dir in paths: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [dir] @@ -59,11 +91,19 @@ if result is None: return None + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + # Check whether the found file is in one of the standard directories dirname = os.path.dirname(result) for p in std_dirs: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ ] + if p == dirname: return [ ] @@ -72,6 +112,11 @@ for p in paths: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ p ] + if p == dirname: return [p] else: @@ -497,7 +542,7 @@ # library and then a static library, instead of first looking # for dynamic libraries on the entire path. # This way a staticly linked custom readline gets picked up - # before the (broken) dynamic library in /usr/lib. + # before the (possibly broken) dynamic library in /usr/lib. readline_extra_link_args = ('-Wl,-search_paths_first',) else: readline_extra_link_args = () @@ -571,22 +616,23 @@ openssl_ver = 0 openssl_ver_re = re.compile( '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' ) - for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in: - name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h') - if os.path.isfile(name): - try: - incfile = open(name, 'r') - for line in incfile: - m = openssl_ver_re.match(line) - if m: - openssl_ver = eval(m.group(1)) - break - except IOError: - pass - # first version found is what we'll use (as the compiler should) - if openssl_ver: - break + # look for the openssl version header on the compiler search path. + opensslv_h = find_file('openssl/opensslv.h', [], + inc_dirs + search_for_ssl_incs_in) + if opensslv_h: + name = os.path.join(opensslv_h[0], 'openssl/opensslv.h') + if sys.platform == 'darwin' and is_macosx_sdk_path(name): + name = os.path.join(macosx_sdk_root(), name[1:]) + try: + incfile = open(name, 'r') + for line in incfile: + m = openssl_ver_re.match(line) + if m: + openssl_ver = eval(m.group(1)) + except IOError as msg: + print("IOError while reading opensshv.h:", msg) + pass #print('openssl_ver = 0x%08x' % openssl_ver) min_openssl_ver = 0x00907000 @@ -715,12 +761,18 @@ db_ver_inc_map = {} + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + class db_found(Exception): pass try: # See whether there is a Sleepycat header in the standard # search path. for d in inc_dirs + db_inc_paths: f = os.path.join(d, "db.h") + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "db.h") + if db_setup_debug: print("db: looking for db.h in", f) if os.path.exists(f): f = open(f, "rb").read() @@ -767,7 +819,22 @@ db_incdir.replace("include", 'lib64'), db_incdir.replace("include", 'lib'), ] - db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + if sys.platform != 'darwin': + db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + else: + # Same as other branch, but takes OSX SDK into account + tmp = [] + for dn in db_dirs_to_check: + if is_macosx_sdk_path(dn): + if os.path.isdir(os.path.join(sysroot, dn[1:])): + tmp.append(dn) + else: + if os.path.isdir(dn): + tmp.append(dn) + + db_dirs_to_check = tmp # Look for a version specific db-X.Y before an ambiguoius dbX # XXX should we -ever- look for a dbX name? Do any @@ -816,8 +883,15 @@ # Scan the default include directories before the SQLite specific # ones. This allows one to override the copy of sqlite on OSX, # where /usr/include contains an old version of sqlite. + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + for d in inc_dirs + sqlite_inc_paths: f = os.path.join(d, "sqlite3.h") + + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "sqlite3.h") + if os.path.exists(f): if sqlite_setup_debug: print("sqlite: found %s"%f) incf = open(f).read() @@ -1256,14 +1330,22 @@ join(os.getenv('HOME'), '/Library/Frameworks') ] + sysroot = macosx_sdk_root() + # Find the directory that contains the Tcl.framework and Tk.framework # bundles. # XXX distutils should support -F! for F in framework_dirs: # both Tcl.framework and Tk.framework should be present + + for fw in 'Tcl', 'Tk': - if not exists(join(F, fw + '.framework')): - break + if is_macosx_sdk_path(F): + if not exists(join(sysroot, F[1:], fw + '.framework')): + break + else: + if not exists(join(F, fw + '.framework')): + break else: # ok, F is now directory with both frameworks. Continure # building @@ -1300,8 +1382,12 @@ # Note: cannot use os.popen or subprocess here, that # requires extensions that are not available here. - os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) + if is_macosx_sdk_path(F): + os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(os.path.join(sysroot, F[1:]), tmpfile)) + else: + os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) fp = open(tmpfile) + detected_archs = [] for ln in fp: a = ln.split()[-1] From python-checkins at python.org Mon Jun 7 12:57:22 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 7 Jun 2010 12:57:22 +0200 (CEST) Subject: [Python-checkins] r81797 - in python/branches/py3k-cdecimal: configure configure.in pyconfig.h.in setup.py Message-ID: <20100607105722.4BA2AEEE97@mail.python.org> Author: stefan.krah Date: Mon Jun 7 12:57:22 2010 New Revision: 81797 Log: Add configure checks for x64 inline assembler and __uint128_t. Modified: python/branches/py3k-cdecimal/configure python/branches/py3k-cdecimal/configure.in python/branches/py3k-cdecimal/pyconfig.h.in python/branches/py3k-cdecimal/setup.py Modified: python/branches/py3k-cdecimal/configure ============================================================================== --- python/branches/py3k-cdecimal/configure (original) +++ python/branches/py3k-cdecimal/configure Mon Jun 7 12:57:22 2010 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 81078 . +# From configure.in Revision: 81796 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65 for python 3.2. # @@ -6554,6 +6554,13 @@ fi +ac_fn_c_check_type "$LINENO" "__uint128_t" "ac_cv_type___uint128_t" "$ac_includes_default" +if test "x$ac_cv_type___uint128_t" = x""yes; then : + +$as_echo "#define HAVE_GCC_UINT128_T 1" >>confdefs.h + +fi + # Sizes of various common basic types # ANSI C requires sizeof(char) == 1, so no need to check it @@ -11508,6 +11515,41 @@ fi +# ************************************** +# * Check for gcc x64 inline assembler * +# ************************************** + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x64 gcc inline assembler" >&5 +$as_echo_n "checking for x64 gcc inline assembler... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + unsigned long long b; + __asm__ __volatile__ ("mulq %0" : : "m" (b)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + have_gcc_asm_for_x64=yes +else + have_gcc_asm_for_x64=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_asm_for_x64" >&5 +$as_echo "$have_gcc_asm_for_x64" >&6; } +if test "$have_gcc_asm_for_x64" = yes +then + +$as_echo "#define HAVE_GCC_ASM_FOR_X64 1" >>confdefs.h + +fi + # ************************************************** # * Check for various properties of floating point * # ************************************************** Modified: python/branches/py3k-cdecimal/configure.in ============================================================================== --- python/branches/py3k-cdecimal/configure.in (original) +++ python/branches/py3k-cdecimal/configure.in Mon Jun 7 12:57:22 2010 @@ -1417,6 +1417,8 @@ AC_TYPE_INT64_T AC_CHECK_TYPE(ssize_t, AC_DEFINE(HAVE_SSIZE_T, 1, [Define if your compiler provides ssize_t]),,) +AC_CHECK_TYPE(__uint128_t, + AC_DEFINE(HAVE_GCC_UINT128_T, 1, [Define if your compiler provides __uint128_t]),,) # Sizes of various common basic types # ANSI C requires sizeof(char) == 1, so no need to check it @@ -3258,6 +3260,22 @@ fi], [AC_MSG_RESULT(default LIBC="$LIBC")]) +# ************************************** +# * Check for gcc x64 inline assembler * +# ************************************** + +AC_MSG_CHECKING(for x64 gcc inline assembler) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ + unsigned long long b; + __asm__ __volatile__ ("mulq %0" : : "m" (b)); +]])],[have_gcc_asm_for_x64=yes],[have_gcc_asm_for_x64=no]) +AC_MSG_RESULT($have_gcc_asm_for_x64) +if test "$have_gcc_asm_for_x64" = yes +then + AC_DEFINE(HAVE_GCC_ASM_FOR_X64, 1, + [Define if we can use x64 gcc inline assembler]) +fi + # ************************************************** # * Check for various properties of floating point * # ************************************************** Modified: python/branches/py3k-cdecimal/pyconfig.h.in ============================================================================== --- python/branches/py3k-cdecimal/pyconfig.h.in (original) +++ python/branches/py3k-cdecimal/pyconfig.h.in Mon Jun 7 12:57:22 2010 @@ -253,10 +253,16 @@ /* Define to 1 if you have the `gamma' function. */ #undef HAVE_GAMMA +/* Define if we can use x64 gcc inline assembler */ +#undef HAVE_GCC_ASM_FOR_X64 + /* Define if we can use gcc inline assembler to get and set x87 control word */ #undef HAVE_GCC_ASM_FOR_X87 +/* Define if your compiler provides __uint128_t */ +#undef HAVE_GCC_UINT128_T + /* Define if you have the getaddrinfo function. */ #undef HAVE_GETADDRINFO Modified: python/branches/py3k-cdecimal/setup.py ============================================================================== --- python/branches/py3k-cdecimal/setup.py (original) +++ python/branches/py3k-cdecimal/setup.py Mon Jun 7 12:57:22 2010 @@ -1730,19 +1730,21 @@ extra_objects = [] platform = self.get_platform() cc = sysconfig.get_config_var('CC') - SIZEOF_SIZE_T = sysconfig.get_config_var('SIZEOF_SIZE_T') - HAVE_GCC_ASM_FOR_X87 = sysconfig.get_config_var('HAVE_GCC_ASM_FOR_X87') - define_macros = [('CONFIG_32', '1')] - if SIZEOF_SIZE_T == 8: - if HAVE_GCC_ASM_FOR_X87: # HAVE_GCC_ASM_FOR_AMD64 + sizeof_size_t = sysconfig.get_config_var('SIZEOF_SIZE_T') + if sizeof_size_t == 8: + if sysconfig.get_config_var('HAVE_GCC_ASM_FOR_X64'): define_macros = [('CONFIG_64', '1')] + elif sysconfig.get_config_var('HAVE_GCC_UINT128_T'): + define_macros = [('CONFIG_64', '1'), ('HAVE_UINT128_T', '1')] else: define_macros = [('CONFIG_32', '1'), ('ANSI', '1')] - elif SIZEOF_SIZE_T == 4: + elif sizeof_size_t == 4: define_macros = [('CONFIG_32', '1')] - if HAVE_GCC_ASM_FOR_X87 and 'gcc' in cc and platform != 'darwin': - # XXX icc >= 11.0 and clang work as well. - # XXX link errors on darwin. + ppro = sysconfig.get_config_var('HAVE_GCC_ASM_FOR_X87') + if ppro and ('gcc' in cc or 'clang' in cc) and \ + platform != 'darwin': + # XXX icc >= 11.0 works as well. + # XXX darwin: problems with global constant in inline asm. define_macros.append(('PPRO', '1')) else: define_macros.append(('ANSI', '1')) @@ -1751,7 +1753,7 @@ # Faster version without thread local contexts: # define_macros.append(('WITHOUT_THREADS', 1)) if 'sunos' in platform and cc == 'cc': # suncc - extra_compile_args.extend(['-erroff=E_ARGUEMENT_MISMATCH']) + extra_compile_args.extend(['-erroff=E_ARGUEMENT_MISMATCH']) # [sic] ext = Extension ( 'cdecimal', define_macros=define_macros, From python-checkins at python.org Mon Jun 7 13:54:23 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 7 Jun 2010 13:54:23 +0200 (CEST) Subject: [Python-checkins] r81798 - in python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests: Makefile.unix Makefile.vc README.txt runallconfigs.bat runallconfigs.sh Message-ID: <20100607115423.54562EEE9D@mail.python.org> Author: stefan.krah Date: Mon Jun 7 13:54:23 2010 New Revision: 81798 Log: New values for the MACHINE variable. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/Makefile.unix python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/Makefile.vc python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/README.txt python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.bat python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.sh Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/Makefile.unix ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/Makefile.unix (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/Makefile.unix Mon Jun 7 13:54:23 2010 @@ -7,6 +7,10 @@ endif ifeq ($(MACHINE), ansi64) +CFLAGS = -DCONFIG_64 -DHAVE_UINT128_T -DTEST_UINT128_T -Wall -W -O2 -fomit-frame-pointer -s +endif + +ifeq ($(MACHINE), ansi64c32) CFLAGS = -DCONFIG_32 -DANSI -Wall -W -O2 -fomit-frame-pointer -s endif @@ -14,12 +18,12 @@ CFLAGS = -m32 -DCONFIG_32 -DPPRO -Wall -W -O2 -fomit-frame-pointer -s endif -ifeq ($(MACHINE), ansi) +ifeq ($(MACHINE), ansi32) CFLAGS = -m32 -DCONFIG_32 -DANSI -Wall -W -O2 -fomit-frame-pointer -s endif ifeq ($(MACHINE), ansi-legacy) -CFLAGS = -m32 -DCONFIG_32 -DANSI -DLEGACY_COMPILER -Wall -W -O2 -fomit-frame-pointer -s +CFLAGS = -DCONFIG_32 -DANSI -DLEGACY_COMPILER -Wall -W -O2 -fomit-frame-pointer -s endif Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/Makefile.vc ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/Makefile.vc (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/Makefile.vc Mon Jun 7 13:54:23 2010 @@ -21,7 +21,7 @@ GMPINC = "C:\Program Files\gmp" !endif -!if "$(MACHINE)" == "ansi64" +!if "$(MACHINE)" == "ansi64c32" CFLAGS = /DCONFIG_32 /DANSI /W3 /D_CRT_SECURE_NO_WARNINGS /nologo /MT /Ox /GS /EHsc GMPLIB = "C:\Program Files\gmp\gmp.lib" GMPINC = "C:\Program Files\gmp" @@ -33,7 +33,7 @@ GMPINC = "C:\Program Files (x86)\gmp" !endif -!if "$(MACHINE)" == "ansi" +!if "$(MACHINE)" == "ansi32" CFLAGS = /DCONFIG_32 /DANSI /W3 /D_CRT_SECURE_NO_WARNINGS /nologo /MT /Ox /GS /EHsc GMPLIB = "C:\Program Files (x86)\gmp\gmp.lib" GMPINC = "C:\Program Files (x86)\gmp" Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/README.txt ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/README.txt (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/README.txt Mon Jun 7 13:54:23 2010 @@ -10,7 +10,7 @@ 1. Tests that do not require gmp: # Use gmake on *BSD - make MACHINE=[x64|ansi64|ppro|ansi|ansi-legacy] && ./runalltests.sh + make MACHINE=[x64|ansi64|ansi64c32|ppro|ansi32|ansi-legacy] && ./runalltests.sh This runs: @@ -24,7 +24,7 @@ 2. Tests that require gmp: # Use gmake on *BSD - make MACHINE=[x64|ansi64|ppro|ansi|ansi-legacy] gmp && ./runalltests.sh + make MACHINE=[x64|ansi64|ansi64c32|ppro|ansi32|ansi-legacy] gmp && ./runalltests.sh This runs all the above tests and: Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.bat ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.bat (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.bat Mon Jun 7 13:54:23 2010 @@ -16,11 +16,11 @@ echo. echo # ======================================================================== -echo # ansi64 +echo # ansi64c32 echo # ======================================================================== echo. nmake clean -nmake MACHINE=ansi64 gmp +nmake MACHINE=ansi64c32 gmp call runalltests.bat @@ -37,11 +37,11 @@ echo. echo # ======================================================================== -echo # ansi +echo # ansi32 echo # ======================================================================== echo. nmake clean -nmake MACHINE=ansi gmp +nmake MACHINE=ansi32 gmp call runalltests.bat echo. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.sh ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.sh (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.sh Mon Jun 7 13:54:23 2010 @@ -2,7 +2,7 @@ VALGRIND= -if [ "$1" == "--valgrind" ]; then +if [ X"$1" = X"--valgrind" ]; then shift VALGRIND="valgrind --tool=memcheck --leak-check=full --leak-resolution=high --db-attach=yes --show-reachable=yes" fi @@ -11,7 +11,7 @@ if [ X"$@" != X"" ]; then CONFIGS="$@" else - CONFIGS="x64 ansi64 ppro ansi ansi-legacy" + CONFIGS="x64 ansi64 ansi64c32 ppro ansi32 ansi-legacy" fi GMAKE=`which gmake` From python-checkins at python.org Mon Jun 7 15:10:10 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 7 Jun 2010 15:10:10 +0200 (CEST) Subject: [Python-checkins] r81799 - in python/branches/py3k-cdecimal: Lib/test/decimal_tests.py setup.py Message-ID: <20100607131010.490F7E8EC@mail.python.org> Author: stefan.krah Date: Mon Jun 7 15:10:10 2010 New Revision: 81799 Log: 1) If Python is compiled --without-threads, use the faster non-threaded version. 2) Fix bugs in skipping tests. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_tests.py python/branches/py3k-cdecimal/setup.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_tests.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_tests.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_tests.py Mon Jun 7 15:10:10 2010 @@ -1362,17 +1362,11 @@ cls.assertFalse(thiscontext.flags[sig]) return + at unittest.skipUnless(threading, 'threading required') class DecimalUseOfContextTest(unittest.TestCase): - '''Unit tests for Use of Context cases in Decimal.''' - - try: - import threading - except ImportError: - self.skipTest("importing threading failed") # Take care executing this test from IDLE, there's an issue in threading # that hangs IDLE and I couldn't find it - def test_threading(self): if HAVE_CDECIMAL and not HAVE_THREADS: self.skipTest("compiled without threading") @@ -1507,8 +1501,7 @@ ]) if HAVE_CDECIMAL: - self.skipTest("new hashing scheme and float comparisons not " - "implemented yet") + self.skipTest("new hashing scheme: not yet implemented") # check that hash(d) == hash(int(d)) for integral values for value in test_values: self.assertEqual(hash(value), hash(int(value))) Modified: python/branches/py3k-cdecimal/setup.py ============================================================================== --- python/branches/py3k-cdecimal/setup.py (original) +++ python/branches/py3k-cdecimal/setup.py Mon Jun 7 15:10:10 2010 @@ -1751,7 +1751,8 @@ else: raise DistutilsError("cdecimal: unsupported architecture") # Faster version without thread local contexts: - # define_macros.append(('WITHOUT_THREADS', 1)) + if '--without-threads' in sysconfig.get_config_var('CONFIG_ARGS'): + define_macros.append(('WITHOUT_THREADS', 1)) if 'sunos' in platform and cc == 'cc': # suncc extra_compile_args.extend(['-erroff=E_ARGUEMENT_MISMATCH']) # [sic] ext = Extension ( From python-checkins at python.org Mon Jun 7 15:36:57 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 7 Jun 2010 15:36:57 +0200 (CEST) Subject: [Python-checkins] r81800 - python/branches/py3k-cdecimal/setup.py Message-ID: <20100607133657.09560EE986@mail.python.org> Author: stefan.krah Date: Mon Jun 7 15:36:56 2010 New Revision: 81800 Log: Use WITH_THREAD Modified: python/branches/py3k-cdecimal/setup.py Modified: python/branches/py3k-cdecimal/setup.py ============================================================================== --- python/branches/py3k-cdecimal/setup.py (original) +++ python/branches/py3k-cdecimal/setup.py Mon Jun 7 15:36:56 2010 @@ -1751,7 +1751,7 @@ else: raise DistutilsError("cdecimal: unsupported architecture") # Faster version without thread local contexts: - if '--without-threads' in sysconfig.get_config_var('CONFIG_ARGS'): + if not sysconfig.get_config_var('WITH_THREAD'): define_macros.append(('WITHOUT_THREADS', 1)) if 'sunos' in platform and cc == 'cc': # suncc extra_compile_args.extend(['-erroff=E_ARGUEMENT_MISMATCH']) # [sic] From python-checkins at python.org Mon Jun 7 15:38:40 2010 From: python-checkins at python.org (andrew.kuchling) Date: Mon, 7 Jun 2010 15:38:40 +0200 (CEST) Subject: [Python-checkins] r81801 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: <20100607133840.DC4FFEE986@mail.python.org> Author: andrew.kuchling Date: Mon Jun 7 15:38:40 2010 New Revision: 81801 Log: #8875: Remove duplicated paragraph 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 Mon Jun 7 15:38:40 2010 @@ -1455,16 +1455,6 @@ will be called and :meth:`handle_request` will return. (Contributed by Kristj?n Valur J?nsson; :issue:`6192` and :issue:`6267`.) -* The XML-RPC client and server, provided by the :mod:`xmlrpclib` and - :mod:`SimpleXMLRPCServer` modules, have improved performance by - supporting HTTP/1.1 keep-alive and by optionally using gzip encoding - to compress the XML being exchanged. The gzip compression is - controlled by the :attr:`encode_threshold` attribute of - :class:`SimpleXMLRPCRequestHandler`, which contains a size in bytes; - responses larger than this will be compressed. - (Contributed by Kristj?n Valur J?nsson; :issue:`6267`.) - - * Updated module: the :mod:`sqlite3` module has been updated to version 2.6.0 of the `pysqlite package `__. Version 2.6.0 includes a number of bugfixes, and adds the ability to load SQLite extensions from shared libraries. From python-checkins at python.org Mon Jun 7 15:57:50 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 7 Jun 2010 15:57:50 +0200 (CEST) Subject: [Python-checkins] r81802 - in python/branches/py3k-cdecimal: configure configure.in Message-ID: <20100607135750.08502EEC62@mail.python.org> Author: stefan.krah Date: Mon Jun 7 15:57:49 2010 New Revision: 81802 Log: Test issue 8719. Will revert. Modified: python/branches/py3k-cdecimal/configure python/branches/py3k-cdecimal/configure.in Modified: python/branches/py3k-cdecimal/configure ============================================================================== --- python/branches/py3k-cdecimal/configure (original) +++ python/branches/py3k-cdecimal/configure Mon Jun 7 15:57:49 2010 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 81796 . +# From configure.in Revision: 81797 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65 for python 3.2. # @@ -8285,6 +8285,7 @@ if test -z "$with_threads" then with_threads="yes" fi +with_threads="no" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_threads" >&5 $as_echo "$with_threads" >&6; } Modified: python/branches/py3k-cdecimal/configure.in ============================================================================== --- python/branches/py3k-cdecimal/configure.in (original) +++ python/branches/py3k-cdecimal/configure.in Mon Jun 7 15:57:49 2010 @@ -2079,6 +2079,7 @@ if test -z "$with_threads" then with_threads="yes" fi +with_threads="no" AC_MSG_RESULT($with_threads) AC_SUBST(THREADOBJ) From python-checkins at python.org Mon Jun 7 18:04:54 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 7 Jun 2010 18:04:54 +0200 (CEST) Subject: [Python-checkins] r81803 - in python/branches/py3k-cdecimal: configure configure.in Message-ID: <20100607160454.CFF79EEEB0@mail.python.org> Author: stefan.krah Date: Mon Jun 7 18:04:54 2010 New Revision: 81803 Log: Revert commit for testing issue 8719. Modified: python/branches/py3k-cdecimal/configure python/branches/py3k-cdecimal/configure.in Modified: python/branches/py3k-cdecimal/configure ============================================================================== --- python/branches/py3k-cdecimal/configure (original) +++ python/branches/py3k-cdecimal/configure Mon Jun 7 18:04:54 2010 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 81797 . +# From configure.in Revision: 81802 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65 for python 3.2. # @@ -8285,7 +8285,6 @@ if test -z "$with_threads" then with_threads="yes" fi -with_threads="no" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_threads" >&5 $as_echo "$with_threads" >&6; } Modified: python/branches/py3k-cdecimal/configure.in ============================================================================== --- python/branches/py3k-cdecimal/configure.in (original) +++ python/branches/py3k-cdecimal/configure.in Mon Jun 7 18:04:54 2010 @@ -2079,7 +2079,6 @@ if test -z "$with_threads" then with_threads="yes" fi -with_threads="no" AC_MSG_RESULT($with_threads) AC_SUBST(THREADOBJ) From python-checkins at python.org Mon Jun 7 18:21:45 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 7 Jun 2010 18:21:45 +0200 (CEST) Subject: [Python-checkins] r81804 - in python/branches/py3k-cdecimal: configure configure.in Message-ID: <20100607162145.0EB5BEEC91@mail.python.org> Author: stefan.krah Date: Mon Jun 7 18:21:44 2010 New Revision: 81804 Log: On FreeBSD-i386, gcc accepts mulq without error. Modified: python/branches/py3k-cdecimal/configure python/branches/py3k-cdecimal/configure.in Modified: python/branches/py3k-cdecimal/configure ============================================================================== --- python/branches/py3k-cdecimal/configure (original) +++ python/branches/py3k-cdecimal/configure Mon Jun 7 18:21:44 2010 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 81802 . +# From configure.in Revision: 81803 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65 for python 3.2. # @@ -11528,8 +11528,7 @@ main () { - unsigned long long b; - __asm__ __volatile__ ("mulq %0" : : "m" (b)); + __asm__ __volatile__ ("movq %rcx, %rax"); ; return 0; Modified: python/branches/py3k-cdecimal/configure.in ============================================================================== --- python/branches/py3k-cdecimal/configure.in (original) +++ python/branches/py3k-cdecimal/configure.in Mon Jun 7 18:21:44 2010 @@ -3266,8 +3266,7 @@ AC_MSG_CHECKING(for x64 gcc inline assembler) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ - unsigned long long b; - __asm__ __volatile__ ("mulq %0" : : "m" (b)); + __asm__ __volatile__ ("movq %rcx, %rax"); ]])],[have_gcc_asm_for_x64=yes],[have_gcc_asm_for_x64=no]) AC_MSG_RESULT($have_gcc_asm_for_x64) if test "$have_gcc_asm_for_x64" = yes From python-checkins at python.org Mon Jun 7 18:37:38 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 7 Jun 2010 18:37:38 +0200 (CEST) Subject: [Python-checkins] r81805 - python/branches/py3k-cdecimal/Modules/cdecimal/constants.h Message-ID: <20100607163738.0F70DEEEC3@mail.python.org> Author: stefan.krah Date: Mon Jun 7 18:37:37 2010 New Revision: 81805 Log: CONFIG_64 is now also used for architectures other than x64. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/constants.h Modified: python/branches/py3k-cdecimal/Modules/cdecimal/constants.h ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/constants.h (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/constants.h Mon Jun 7 18:37:37 2010 @@ -21,8 +21,13 @@ #define SETMODULUS(modnum) std_setmodulus(modnum, &umod) #define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod) - #define BSR(a) x86_bsr(a) - #define BSF(a) x86_bsf(a) + #if defined(__x86_64__) + #define BSR(a) x86_bsr(a) + #define BSF(a) x86_bsf(a) + #else + #define BSR(a) std_bsr(a) + #define BSF(a) std_bsf(a) + #endif #elif defined(PPRO) /* PentiumPro (or later) gcc inline asm */ #define MULMOD(a, b) ppro_mulmod(a, b, &dmod, dinvmod) From python-checkins at python.org Mon Jun 7 20:47:10 2010 From: python-checkins at python.org (mark.dickinson) Date: Mon, 7 Jun 2010 20:47:10 +0200 (CEST) Subject: [Python-checkins] r81806 - in python/branches/py3k: Include/longobject.h Modules/datetimemodule.c Objects/longobject.c Message-ID: <20100607184710.27149EEA09@mail.python.org> Author: mark.dickinson Date: Mon Jun 7 20:47:09 2010 New Revision: 81806 Log: Fix naming inconsistency. Modified: python/branches/py3k/Include/longobject.h python/branches/py3k/Modules/datetimemodule.c python/branches/py3k/Objects/longobject.c Modified: python/branches/py3k/Include/longobject.h ============================================================================== --- python/branches/py3k/Include/longobject.h (original) +++ python/branches/py3k/Include/longobject.h Mon Jun 7 20:47:09 2010 @@ -101,13 +101,13 @@ */ PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); -/* _PyLong_Divmod_Near. Given integers a and b, compute the nearest +/* _PyLong_DivmodNear. Given integers a and b, compute the nearest integer q to the exact quotient a / b, rounding to the nearest even integer in the case of a tie. Return (q, r), where r = a - q*b. The remainder r will satisfy abs(r) <= abs(b)/2, with equality possible only if q is even. */ -PyAPI_FUNC(PyObject *) _PyLong_Divmod_Near(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *); /* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in base 256, and return a Python long with the same numeric value. Modified: python/branches/py3k/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k/Modules/datetimemodule.c (original) +++ python/branches/py3k/Modules/datetimemodule.c Mon Jun 7 20:47:09 2010 @@ -161,7 +161,7 @@ PyObject *result; PyObject *temp; - temp = _PyLong_Divmod_Near(m, n); + temp = _PyLong_DivmodNear(m, n); if (temp == NULL) return NULL; result = PyTuple_GET_ITEM(temp, 0); Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Mon Jun 7 20:47:09 2010 @@ -4218,7 +4218,7 @@ round-half-to-even. */ PyObject * -_PyLong_Divmod_Near(PyObject *a, PyObject *b) +_PyLong_DivmodNear(PyObject *a, PyObject *b) { PyLongObject *quo = NULL, *rem = NULL; PyObject *one = NULL, *twice_rem, *result, *temp; @@ -4363,7 +4363,7 @@ if (result == NULL) return NULL; - temp = _PyLong_Divmod_Near(self, result); + temp = _PyLong_DivmodNear(self, result); Py_DECREF(result); result = temp; if (result == NULL) From python-checkins at python.org Mon Jun 7 21:57:46 2010 From: python-checkins at python.org (victor.stinner) Date: Mon, 7 Jun 2010 21:57:46 +0200 (CEST) Subject: [Python-checkins] r81807 - in python/branches/py3k: Doc/c-api/arg.rst Modules/_ctypes/_ctypes.c Objects/exceptions.c Python/Python-ast.c Python/errors.c Python/modsupport.c Python/sysmodule.c Message-ID: <20100607195746.9AE94EEA31@mail.python.org> Author: victor.stinner Date: Mon Jun 7 21:57:46 2010 New Revision: 81807 Log: Issue #8848: U / U# formats of Py_BuildValue() are just alias to s / s# Modified: python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Objects/exceptions.c python/branches/py3k/Python/Python-ast.c python/branches/py3k/Python/errors.c python/branches/py3k/Python/modsupport.c python/branches/py3k/Python/sysmodule.c Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Mon Jun 7 21:57:46 2010 @@ -530,12 +530,10 @@ and ``None`` is returned. ``U`` (string) [char \*] - Convert a null-terminated C string to a Python unicode object. If the C string - pointer is *NULL*, ``None`` is used. + Same as ``s``. ``U#`` (string) [char \*, int] - Convert a C string and its length to a Python unicode object. If the C string - pointer is *NULL*, the length is ignored and ``None`` is returned. + Same as ``s#``. ``i`` (integer) [int] Convert a plain C :ctype:`int` to a Python integer object. Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Mon Jun 7 21:57:46 2010 @@ -4467,7 +4467,7 @@ #endif result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type, - "U(O){s:n,s:O}", + "s(O){s:n,s:O}", name, &PyCArray_Type, "_length_", Modified: python/branches/py3k/Objects/exceptions.c ============================================================================== --- python/branches/py3k/Objects/exceptions.c (original) +++ python/branches/py3k/Objects/exceptions.c Mon Jun 7 21:57:46 2010 @@ -1510,7 +1510,7 @@ const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason) { - return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU", + return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns", encoding, object, length, start, end, reason); } @@ -1625,7 +1625,7 @@ assert(length < INT_MAX); assert(start < INT_MAX); assert(end < INT_MAX); - return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU", + return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns", encoding, object, length, start, end, reason); } Modified: python/branches/py3k/Python/Python-ast.c ============================================================================== --- python/branches/py3k/Python/Python-ast.c (original) +++ python/branches/py3k/Python/Python-ast.c Mon Jun 7 21:57:46 2010 @@ -527,7 +527,7 @@ } PyTuple_SET_ITEM(fnames, i, field); } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "U(O){sOss}", + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sOss}", type, base, "_fields", fnames, "__module__", "_ast"); Py_DECREF(fnames); return (PyTypeObject*)result; Modified: python/branches/py3k/Python/errors.c ============================================================================== --- python/branches/py3k/Python/errors.c (original) +++ python/branches/py3k/Python/errors.c Mon Jun 7 21:57:46 2010 @@ -679,7 +679,7 @@ goto failure; } /* Create a real new-style class. */ - result = PyObject_CallFunction((PyObject *)&PyType_Type, "UOO", + result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO", dot+1, bases, dict); failure: Py_XDECREF(bases); Modified: python/branches/py3k/Python/modsupport.c ============================================================================== --- python/branches/py3k/Python/modsupport.c (original) +++ python/branches/py3k/Python/modsupport.c Mon Jun 7 21:57:46 2010 @@ -302,39 +302,7 @@ case 's': case 'z': - { - PyObject *v; - char *str = va_arg(*p_va, char *); - Py_ssize_t n; - if (**p_format == '#') { - ++*p_format; - if (flags & FLAG_SIZE_T) - n = va_arg(*p_va, Py_ssize_t); - else - n = va_arg(*p_va, int); - } - else - n = -1; - if (str == NULL) { - v = Py_None; - Py_INCREF(v); - } - else { - if (n < 0) { - size_t m = strlen(str); - if (m > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "string too long for Python string"); - return NULL; - } - n = (Py_ssize_t)m; - } - v = PyUnicode_FromStringAndSize(str, n); - } - return v; - } - - case 'U': + case 'U': /* XXX deprecated alias */ { PyObject *v; char *str = va_arg(*p_va, char *); Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Mon Jun 7 21:57:46 2010 @@ -1510,7 +1510,7 @@ PyLong_FromLong(PY_VERSION_HEX)); svnversion_init(); SET_SYS_FROM_STRING("subversion", - Py_BuildValue("(UUU)", "CPython", branch, + Py_BuildValue("(sss)", "CPython", branch, svn_revision)); SET_SYS_FROM_STRING("dont_write_bytecode", PyBool_FromLong(Py_DontWriteBytecodeFlag)); From python-checkins at python.org Mon Jun 7 21:59:35 2010 From: python-checkins at python.org (victor.stinner) Date: Mon, 7 Jun 2010 21:59:35 +0200 (CEST) Subject: [Python-checkins] r81808 - python/branches/release31-maint Message-ID: <20100607195935.9D2A6EE98A@mail.python.org> Author: victor.stinner Date: Mon Jun 7 21:59:35 2010 New Revision: 81808 Log: Blocked revisions 81807 via svnmerge ........ r81807 | victor.stinner | 2010-06-07 21:57:46 +0200 (lun., 07 juin 2010) | 2 lines Issue #8848: U / U# formats of Py_BuildValue() are just alias to s / s# ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Jun 7 22:14:04 2010 From: python-checkins at python.org (victor.stinner) Date: Mon, 7 Jun 2010 22:14:04 +0200 (CEST) Subject: [Python-checkins] r81809 - in python/branches/py3k: Lib/sunau.py Lib/test/test_sunau.py Misc/ACKS Misc/NEWS Message-ID: <20100607201404.7807BEE994@mail.python.org> Author: victor.stinner Date: Mon Jun 7 22:14:04 2010 New Revision: 81809 Log: Issue #8897: Fix sunau module, use bytes to write the header. Patch written by Thomas Jollans. Added: python/branches/py3k/Lib/test/test_sunau.py Modified: python/branches/py3k/Lib/sunau.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/sunau.py ============================================================================== --- python/branches/py3k/Lib/sunau.py (original) +++ python/branches/py3k/Lib/sunau.py Mon Jun 7 22:14:04 2010 @@ -299,7 +299,7 @@ self._nframeswritten = 0 self._datawritten = 0 self._datalength = 0 - self._info = '' + self._info = b'' self._comptype = 'ULAW' # default is U-law def setnchannels(self, nchannels): Added: python/branches/py3k/Lib/test/test_sunau.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/test/test_sunau.py Mon Jun 7 22:14:04 2010 @@ -0,0 +1,70 @@ +from test.support import run_unittest, TESTFN +import unittest +import os + +import sunau + +nchannels = 2 +sampwidth = 2 +framerate = 8000 +nframes = 100 + +class SunAUTest(unittest.TestCase): + + def setUp(self): + self.f = None + + def tearDown(self): + if self.f is not None: + self.f.close() + try: + os.remove(TESTFN) + except OSError: + pass + + def test_lin(self): + self.f = sunau.open(TESTFN, 'w') + self.f.setnchannels(nchannels) + self.f.setsampwidth(sampwidth) + self.f.setframerate(framerate) + self.f.setcomptype('NONE', 'not compressed') + output = b'\xff\x00\x12\xcc' * (nframes * nchannels * sampwidth // 4) + self.f.writeframes(output) + self.f.close() + + self.f = sunau.open(TESTFN, 'rb') + self.assertEqual(nchannels, self.f.getnchannels()) + self.assertEqual(sampwidth, self.f.getsampwidth()) + self.assertEqual(framerate, self.f.getframerate()) + self.assertEqual(nframes, self.f.getnframes()) + self.assertEqual('NONE', self.f.getcomptype()) + self.assertEqual(self.f.readframes(nframes), output) + self.f.close() + + def test_ulaw(self): + self.f = sunau.open(TESTFN, 'w') + self.f.setnchannels(nchannels) + self.f.setsampwidth(sampwidth) + self.f.setframerate(framerate) + self.f.setcomptype('ULAW', '') + # u-law compression is lossy, therefore we can't expect non-zero data + # to come back unchanged. + output = b'\0' * nframes * nchannels * sampwidth + self.f.writeframes(output) + self.f.close() + + self.f = sunau.open(TESTFN, 'rb') + self.assertEqual(nchannels, self.f.getnchannels()) + self.assertEqual(sampwidth, self.f.getsampwidth()) + self.assertEqual(framerate, self.f.getframerate()) + self.assertEqual(nframes, self.f.getnframes()) + self.assertEqual('ULAW', self.f.getcomptype()) + self.assertEqual(self.f.readframes(nframes), output) + self.f.close() + + +def test_main(): + run_unittest(SunAUTest) + +if __name__ == "__main__": + unittest.main() Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Mon Jun 7 22:14:04 2010 @@ -389,6 +389,7 @@ Fredrik Johansson Gregory K. Johnson Simon Johnston +Thomas Jollans Evan Jones Jeremy Jones Richard Jones Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Jun 7 22:14:04 2010 @@ -398,6 +398,9 @@ Library ------- +- Issue #8897: Fix sunau module, use bytes to write the header. Patch written + by Thomas Jollans. + - Issue #8899: time.struct_time now has class and atribute docstrings. - Issue #6470: Drop UNC prefix in FixTk. From python-checkins at python.org Mon Jun 7 22:24:48 2010 From: python-checkins at python.org (victor.stinner) Date: Mon, 7 Jun 2010 22:24:48 +0200 (CEST) Subject: [Python-checkins] r81810 - in python/branches/release31-maint: Lib/sunau.py Lib/test/test_sunau.py Misc/ACKS Misc/NEWS Message-ID: <20100607202448.49890EE994@mail.python.org> Author: victor.stinner Date: Mon Jun 7 22:24:48 2010 New Revision: 81810 Log: Merged revisions 81809 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81809 | victor.stinner | 2010-06-07 22:14:04 +0200 (lun., 07 juin 2010) | 3 lines Issue #8897: Fix sunau module, use bytes to write the header. Patch written by Thomas Jollans. ........ Added: python/branches/release31-maint/Lib/test/test_sunau.py - copied unchanged from r81809, /python/branches/py3k/Lib/test/test_sunau.py Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/sunau.py python/branches/release31-maint/Misc/ACKS python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/sunau.py ============================================================================== --- python/branches/release31-maint/Lib/sunau.py (original) +++ python/branches/release31-maint/Lib/sunau.py Mon Jun 7 22:24:48 2010 @@ -299,7 +299,7 @@ self._nframeswritten = 0 self._datawritten = 0 self._datalength = 0 - self._info = '' + self._info = b'' self._comptype = 'ULAW' # default is U-law def setnchannels(self, nchannels): Modified: python/branches/release31-maint/Misc/ACKS ============================================================================== --- python/branches/release31-maint/Misc/ACKS (original) +++ python/branches/release31-maint/Misc/ACKS Mon Jun 7 22:24:48 2010 @@ -375,6 +375,7 @@ Fredrik Johansson Gregory K. Johnson Simon Johnston +Thomas Jollans Evan Jones Jeremy Jones Richard Jones Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Jun 7 22:24:48 2010 @@ -54,6 +54,9 @@ Library ------- +- Issue #8897: Fix sunau module, use bytes to write the header. Patch written + by Thomas Jollans. + - Issue #6470: Drop UNC prefix in FixTk. - Issue #4768: base64 encoded email body parts were incorrectly stored as From python-checkins at python.org Mon Jun 7 23:20:42 2010 From: python-checkins at python.org (victor.stinner) Date: Mon, 7 Jun 2010 23:20:42 +0200 (CEST) Subject: [Python-checkins] r81811 - python/branches/py3k/Doc/c-api/arg.rst Message-ID: <20100607212042.0A63BEE9AD@mail.python.org> Author: victor.stinner Date: Mon Jun 7 23:20:41 2010 New Revision: 81811 Log: Issue #8925: fix types of Py_Parse*() and Py_BuildValue() functions * Add links to Python types * Replace "string" by bytes or str * Replace "long" by "int" * Specify the default encoding * Fix reST syntax ("..note ::") * etc. Modified: python/branches/py3k/Doc/c-api/arg.rst Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Mon Jun 7 23:20:41 2010 @@ -53,13 +53,13 @@ drop int support. It is best to always define :cmacro:`PY_SSIZE_T_CLEAN`. -``s`` (Unicode object) [const char \*] +``s`` (:class:`str`) [const char \*] Convert a Unicode object to a C pointer to a character string. A pointer to an existing string is stored in the character pointer variable whose address you pass. The C string is NUL-terminated. The Python string must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. Unicode objects are converted - to C strings using the default encoding. If this conversion fails, a + to C strings using ``'utf-8'`` encoding. If this conversion fails, a :exc:`UnicodeError` is raised. .. note:: @@ -68,111 +68,112 @@ preferrable to use the ``O&`` format with :cfunc:`PyUnicode_FSConverter` as *converter*. -``s*`` (Unicode object or any buffer compatible object) [Py_buffer] +``s*`` (:class:`str`, :class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer] This format accepts Unicode objects as well as objects supporting the - buffer protocol (such as :class:`bytes` or :class:`bytearray` objects). + buffer protocol. It fills a :ctype:`Py_buffer` structure provided by the caller. - Unicode objects are converted to C strings using the default encoding. In this case the resulting C string may contain embedded NUL bytes. + Unicode objects are converted to C strings using ``'utf-8'`` encoding. -``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int or :ctype:`Py_ssize_t`] +``s#`` (:class:`str`, :class:`bytes` or read-only buffer compatible object) [const char \*, int or :ctype:`Py_ssize_t`] Like ``s*``, except that it doesn't accept mutable buffer-like objects such as :class:`bytearray`. The result is stored into two C variables, the first one a pointer to a C string, the second one its length. - The string may contain embedded null bytes. + The string may contain embedded null bytes. Unicode objects are converted + to C strings using ``'utf-8'`` encoding. -``z`` (Unicode object or ``None``) [const char \*] +``z`` (:class:`str` or ``None``) [const char \*] Like ``s``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``z*`` (Unicode object or ``None`` or any buffer compatible object) [Py_buffer] +``z*`` (:class:`str`, :class:`bytes`, :class:`bytearray`, buffer compatible object or ``None``) [Py_buffer] Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :ctype:`Py_buffer` structure is set to *NULL*. -``z#`` (Unicode object or ``None`` or any read buffer compatible object) [const char \*, int] +``z#`` (:class:`str`, :class:`bytes`, read-only buffer compatible object or ``None``) [const char \*, int] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``y`` (bytes object) [const char \*] +``y`` (:class:`bytes`) [const char \*] This format converts a bytes-like object to a C pointer to a character string; it does not accept Unicode objects. The bytes buffer must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. -``y*`` (any buffer compatible object) [Py_buffer \*] +``y*`` (:class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer \*] This variant on ``s*`` doesn't accept Unicode objects, only objects supporting the buffer protocol. **This is the recommended way to accept binary data.** -``y#`` (bytes object) [const char \*, int] +``y#`` (:class:`bytes`) [const char \*, int] This variant on ``s#`` doesn't accept Unicode objects, only bytes-like objects. -``S`` (bytes object) [PyBytesObject \*] +``S`` (:class:`bytes`) [PyBytesObject \*] Requires that the Python object is a :class:`bytes` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a bytes object. The C variable may also be declared as :ctype:`PyObject\*`. -``Y`` (bytearray object) [PyByteArrayObject \*] +``Y`` (:class:`bytearray`) [PyByteArrayObject \*] Requires that the Python object is a :class:`bytearray` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not - a bytearray object. The C variable may also be declared as :ctype:`PyObject\*`. + a :class:`bytearray` object. The C variable may also be declared as :ctype:`PyObject\*`. -``u`` (Unicode object) [Py_UNICODE \*] +``u`` (:class:`str`) [Py_UNICODE \*] Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of Unicode characters. You must pass the address of a :ctype:`Py_UNICODE` pointer variable, which will be filled with the pointer to an existing Unicode buffer. Please note that the width of a :ctype:`Py_UNICODE` character depends on compilation options (it is either 16 or 32 bits). - ..note :: + .. note:: Since ``u`` doesn't give you back the length of the string, and it may contain embedded NUL characters, it is recommended to use ``u#`` or ``U`` instead. -``u#`` (Unicode object) [Py_UNICODE \*, int] +``u#`` (:class:`str`) [Py_UNICODE \*, int] This variant on ``u`` stores into two C variables, the first one a pointer to a Unicode data buffer, the second one its length. Non-Unicode objects are handled by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` array. -``Z`` (Unicode or ``None``) [Py_UNICODE \*] +``Z`` (:class:`str` or ``None``) [Py_UNICODE \*] Like ``u``, but the Python object may also be ``None``, in which case the :ctype:`Py_UNICODE` pointer is set to *NULL*. -``Z#`` (Unicode or ``None``) [Py_UNICODE \*, int] +``Z#`` (:class:`str` or ``None``) [Py_UNICODE \*, int] Like ``u#``, but the Python object may also be ``None``, in which case the :ctype:`Py_UNICODE` pointer is set to *NULL*. -``U`` (Unicode object) [PyUnicodeObject \*] +``U`` (:class:`str`) [PyUnicodeObject \*] Requires that the Python object is a Unicode object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a Unicode object. The C variable may also be declared as :ctype:`PyObject\*`. -``t#`` (read-only character buffer) [char \*, int] +``t#`` (:class:`bytes`, :class:`bytearray` or read-only character buffer) [char \*, int] Like ``s#``, but accepts any object which implements the read-only buffer interface. The :ctype:`char\*` variable is set to point to the first byte of the buffer, and the :ctype:`int` is set to the length of the buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``w`` (read-write character buffer) [char \*] +``w`` (:class:`bytearray` or read-write character buffer) [char \*] Similar to ``s``, but accepts any object which implements the read-write buffer interface. The caller must determine the length of the buffer by other means, or use ``w#`` instead. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``w*`` (read-write byte-oriented buffer) [Py_buffer] +``w*`` (:class:`bytearray` or read-write byte-oriented buffer) [Py_buffer] This is to ``w`` what ``s*`` is to ``s``. -``w#`` (read-write character buffer) [char \*, int] +``w#`` (:class:`bytearray` or read-write character buffer) [char \*, int] Like ``s#``, but accepts any object which implements the read-write buffer interface. The :ctype:`char \*` variable is set to point to the first byte of the buffer, and the :ctype:`int` is set to the length of the buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] +``es`` (:class:`str`) [const char \*encoding, char \*\*buffer] This variant on ``s`` is used for encoding Unicode and objects convertible to Unicode into a character buffer. It only works for encoded data without embedded NUL bytes. @@ -190,12 +191,12 @@ allocated storage. The caller is responsible for calling :cfunc:`PyMem_Free` to free the allocated buffer after use. -``et`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es`` except that 8-bit string objects are passed through without - recoding them. Instead, the implementation assumes that the string object uses +``et`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer] + Same as ``es`` except that byte string objects are passed through without + recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. -``es#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] This variant on ``s#`` is used for encoding Unicode and objects convertible to Unicode into a character buffer. Unlike the ``es`` format, this variant allows input data which contains NUL characters. @@ -226,71 +227,71 @@ In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. -``et#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - Same as ``es#`` except that string objects are passed through without recoding - them. Instead, the implementation assumes that the string object uses the +``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length] + Same as ``es#`` except that byte string objects are passed through without recoding + them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. Numbers ------- -``b`` (integer) [unsigned char] +``b`` (:class:`int`) [unsigned char] Convert a nonnegative Python integer to an unsigned tiny int, stored in a C :ctype:`unsigned char`. -``B`` (integer) [unsigned char] +``B`` (:class:`int`) [unsigned char] Convert a Python integer to a tiny int without overflow checking, stored in a C :ctype:`unsigned char`. -``h`` (integer) [short int] +``h`` (:class:`int`) [short int] Convert a Python integer to a C :ctype:`short int`. -``H`` (integer) [unsigned short int] +``H`` (:class:`int`) [unsigned short int] Convert a Python integer to a C :ctype:`unsigned short int`, without overflow checking. -``i`` (integer) [int] +``i`` (:class:`int`) [int] Convert a Python integer to a plain C :ctype:`int`. -``I`` (integer) [unsigned int] +``I`` (:class:`int`) [unsigned int] Convert a Python integer to a C :ctype:`unsigned int`, without overflow checking. -``l`` (integer) [long int] +``l`` (:class:`int`) [long int] Convert a Python integer to a C :ctype:`long int`. -``k`` (integer) [unsigned long] +``k`` (:class:`int`) [unsigned long] Convert a Python integer to a C :ctype:`unsigned long` without overflow checking. -``L`` (integer) [PY_LONG_LONG] +``L`` (:class:`int`) [PY_LONG_LONG] Convert a Python integer to a C :ctype:`long long`. This format is only available on platforms that support :ctype:`long long` (or :ctype:`_int64` on Windows). -``K`` (integer) [unsigned PY_LONG_LONG] +``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a Python integer to a C :ctype:`unsigned long long` without overflow checking. This format is only available on platforms that support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows). -``n`` (integer) [Py_ssize_t] +``n`` (:class:`int`) [Py_ssize_t] Convert a Python integer to a C :ctype:`Py_ssize_t`. -``c`` (bytes object of length 1) [char] +``c`` (:class:`bytes` of length 1) [char] Convert a Python byte, represented as a :class:`bytes` object of length 1, to a C :ctype:`char`. -``C`` (Unicode object of length 1) [int] - Convert a Python character, represented as a :class:`str`: object of +``C`` (:class:`str` of length 1) [int] + Convert a Python character, represented as a :class:`str` object of length 1, to a C :ctype:`int`. -``f`` (float) [float] +``f`` (:class:`float`) [float] Convert a Python floating point number to a C :ctype:`float`. -``d`` (float) [double] +``d`` (:class:`float`) [double] Convert a Python floating point number to a C :ctype:`double`. -``D`` (complex) [Py_complex] +``D`` (:class:`complex`) [Py_complex] Convert a Python complex number to a C :ctype:`Py_complex` structure. Other objects @@ -330,7 +331,7 @@ .. versionchanged:: 3.1 Py_CLEANUP_SUPPORTED was added. -``(items)`` (tuple) [*matching-items*] +``(items)`` (:class:`tuple`) [*matching-items*] The object must be a Python sequence whose length is the number of format units in *items*. The C arguments must correspond to the individual format units in *items*. Format units for sequences may be nested. @@ -498,93 +499,94 @@ not within format units such as ``s#``). This can be used to make long format strings a tad more readable. - ``s`` (string) [char \*] - Convert a null-terminated C string to a Python object. If the C string pointer - is *NULL*, ``None`` is used. - - ``s#`` (string) [char \*, int] - Convert a C string and its length to a Python object. If the C string pointer - is *NULL*, the length is ignored and ``None`` is returned. + ``s`` (:class:`str` or ``None``) [char \*] + Convert a null-terminated C string to a Python object using ``'utf-8'`` + encoding. If the C string pointer is *NULL*, ``None`` is used. + + ``s#`` (:class:`str` or ``None``) [char \*, int] + Convert a C string and its length to a Python object using ``'utf-8'`` + encoding. If the C string pointer is *NULL*, the length is ignored and + ``None`` is returned. - ``y`` (bytes) [char \*] + ``y`` (:class:`bytes`) [char \*] This converts a C string to a Python :func:`bytes` object. If the C string pointer is *NULL*, ``None`` is returned. - ``y#`` (bytes) [char \*, int] + ``y#`` (:class:`bytes`) [char \*, int] This converts a C string and its lengths to a Python object. If the C string pointer is *NULL*, ``None`` is returned. - ``z`` (string or ``None``) [char \*] + ``z`` (:class:`str` or ``None``) [char \*] Same as ``s``. - ``z#`` (string or ``None``) [char \*, int] + ``z#`` (:class:`str` or ``None``) [char \*, int] Same as ``s#``. - ``u`` (Unicode string) [Py_UNICODE \*] + ``u`` (:class:`str`) [Py_UNICODE \*] Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned. - ``u#`` (Unicode string) [Py_UNICODE \*, int] + ``u#`` (:class:`str`) [Py_UNICODE \*, int] Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored and ``None`` is returned. - ``U`` (string) [char \*] + ``U`` (:class:`str` or ``None``) [char \*] Same as ``s``. - ``U#`` (string) [char \*, int] + ``U#`` (:class:`str` or ``None``) [char \*, int] Same as ``s#``. - ``i`` (integer) [int] + ``i`` (:class:`int`) [int] Convert a plain C :ctype:`int` to a Python integer object. - ``b`` (integer) [char] + ``b`` (:class:`int`) [char] Convert a plain C :ctype:`char` to a Python integer object. - ``h`` (integer) [short int] + ``h`` (:class:`int`) [short int] Convert a plain C :ctype:`short int` to a Python integer object. - ``l`` (integer) [long int] + ``l`` (:class:`int`) [long int] Convert a C :ctype:`long int` to a Python integer object. - ``B`` (integer) [unsigned char] + ``B`` (:class:`int`) [unsigned char] Convert a C :ctype:`unsigned char` to a Python integer object. - ``H`` (integer) [unsigned short int] + ``H`` (:class:`int`) [unsigned short int] Convert a C :ctype:`unsigned short int` to a Python integer object. - ``I`` (integer) [unsigned int] + ``I`` (:class:`int`) [unsigned int] Convert a C :ctype:`unsigned int` to a Python integer object. - ``k`` (integer) [unsigned long] + ``k`` (:class:`int`) [unsigned long] Convert a C :ctype:`unsigned long` to a Python integer object. - ``L`` (long) [PY_LONG_LONG] + ``L`` (:class:`int`) [PY_LONG_LONG] Convert a C :ctype:`long long` to a Python integer object. Only available on platforms that support :ctype:`long long`. - ``K`` (long) [unsigned PY_LONG_LONG] + ``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a C :ctype:`unsigned long long` to a Python integer object. Only available on platforms that support :ctype:`unsigned long long`. - ``n`` (int) [Py_ssize_t] + ``n`` (:class:`int`) [Py_ssize_t] Convert a C :ctype:`Py_ssize_t` to a Python integer. - ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a byte to a Python byte string of + ``c`` (:class:`bytes` of length 1) [char] + Convert a C :ctype:`int` representing a byte to a Python :class:`bytes` object of length 1. - ``C`` (string of length 1) [int] - Convert a C :ctype:`int` representing a character to Python unicode - string of length 1. + ``C`` (:class:`str` of length 1) [int] + Convert a C :ctype:`int` representing a character to Python :class:`str` + object of length 1. - ``d`` (float) [double] + ``d`` (:class:`float`) [double] Convert a C :ctype:`double` to a Python floating point number. - ``f`` (float) [float] - Same as ``d``. + ``f`` (:class:`float`) [float] + Convert a C :ctype:`float` to a Python floating point number. - ``D`` (complex) [Py_complex \*] + ``D`` (:class:`complex`) [Py_complex \*] Convert a C :ctype:`Py_complex` structure to a Python complex number. ``O`` (object) [PyObject \*] @@ -609,13 +611,13 @@ \*`) as its argument and should return a "new" Python object, or *NULL* if an error occurred. - ``(items)`` (tuple) [*matching-items*] + ``(items)`` (:class:`tuple`) [*matching-items*] Convert a sequence of C values to a Python tuple with the same number of items. - ``[items]`` (list) [*matching-items*] + ``[items]`` (:class:`list`) [*matching-items*] Convert a sequence of C values to a Python list with the same number of items. - ``{items}`` (dictionary) [*matching-items*] + ``{items}`` (:class:`dict`) [*matching-items*] Convert a sequence of C values to a Python dictionary. Each pair of consecutive C values adds one item to the dictionary, serving as key and value, respectively. From python-checkins at python.org Mon Jun 7 23:29:23 2010 From: python-checkins at python.org (victor.stinner) Date: Mon, 7 Jun 2010 23:29:23 +0200 (CEST) Subject: [Python-checkins] r81812 - in python/branches/release31-maint: Doc/c-api/arg.rst Message-ID: <20100607212923.B3382EEA3B@mail.python.org> Author: victor.stinner Date: Mon Jun 7 23:29:23 2010 New Revision: 81812 Log: Merged revisions 81811 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81811 | victor.stinner | 2010-06-07 23:20:41 +0200 (lun., 07 juin 2010) | 9 lines Issue #8925: fix types of Py_Parse*() and Py_BuildValue() functions * Add links to Python types * Replace "string" by bytes or str * Replace "long" by "int" * Specify the default encoding * Fix reST syntax ("..note ::") * etc. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/c-api/arg.rst Modified: python/branches/release31-maint/Doc/c-api/arg.rst ============================================================================== --- python/branches/release31-maint/Doc/c-api/arg.rst (original) +++ python/branches/release31-maint/Doc/c-api/arg.rst Mon Jun 7 23:29:23 2010 @@ -53,13 +53,13 @@ drop int support. It is best to always define :cmacro:`PY_SSIZE_T_CLEAN`. -``s`` (Unicode object) [const char \*] +``s`` (:class:`str`) [const char \*] Convert a Unicode object to a C pointer to a character string. A pointer to an existing string is stored in the character pointer variable whose address you pass. The C string is NUL-terminated. The Python string must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. Unicode objects are converted - to C strings using the default encoding. If this conversion fails, a + to C strings using ``'utf-8'`` encoding. If this conversion fails, a :exc:`UnicodeError` is raised. .. note:: @@ -68,111 +68,112 @@ preferrable to use the ``O&`` format with :cfunc:`PyUnicode_FSConverter` as *converter*. -``s*`` (Unicode object or any buffer compatible object) [Py_buffer] +``s*`` (:class:`str`, :class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer] This format accepts Unicode objects as well as objects supporting the - buffer protocol (such as :class:`bytes` or :class:`bytearray` objects). + buffer protocol. It fills a :ctype:`Py_buffer` structure provided by the caller. - Unicode objects are converted to C strings using the default encoding. In this case the resulting C string may contain embedded NUL bytes. + Unicode objects are converted to C strings using ``'utf-8'`` encoding. -``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int or :ctype:`Py_ssize_t`] +``s#`` (:class:`str`, :class:`bytes` or read-only buffer compatible object) [const char \*, int or :ctype:`Py_ssize_t`] Like ``s*``, except that it doesn't accept mutable buffer-like objects such as :class:`bytearray`. The result is stored into two C variables, the first one a pointer to a C string, the second one its length. - The string may contain embedded null bytes. + The string may contain embedded null bytes. Unicode objects are converted + to C strings using ``'utf-8'`` encoding. -``z`` (Unicode object or ``None``) [const char \*] +``z`` (:class:`str` or ``None``) [const char \*] Like ``s``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``z*`` (Unicode object or ``None`` or any buffer compatible object) [Py_buffer] +``z*`` (:class:`str`, :class:`bytes`, :class:`bytearray`, buffer compatible object or ``None``) [Py_buffer] Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :ctype:`Py_buffer` structure is set to *NULL*. -``z#`` (Unicode object or ``None`` or any read buffer compatible object) [const char \*, int] +``z#`` (:class:`str`, :class:`bytes`, read-only buffer compatible object or ``None``) [const char \*, int] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``y`` (bytes object) [const char \*] +``y`` (:class:`bytes`) [const char \*] This format converts a bytes-like object to a C pointer to a character string; it does not accept Unicode objects. The bytes buffer must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. -``y*`` (any buffer compatible object) [Py_buffer \*] +``y*`` (:class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer \*] This variant on ``s*`` doesn't accept Unicode objects, only objects supporting the buffer protocol. **This is the recommended way to accept binary data.** -``y#`` (bytes object) [const char \*, int] +``y#`` (:class:`bytes`) [const char \*, int] This variant on ``s#`` doesn't accept Unicode objects, only bytes-like objects. -``S`` (bytes object) [PyBytesObject \*] +``S`` (:class:`bytes`) [PyBytesObject \*] Requires that the Python object is a :class:`bytes` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a bytes object. The C variable may also be declared as :ctype:`PyObject\*`. -``Y`` (bytearray object) [PyByteArrayObject \*] +``Y`` (:class:`bytearray`) [PyByteArrayObject \*] Requires that the Python object is a :class:`bytearray` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not - a bytearray object. The C variable may also be declared as :ctype:`PyObject\*`. + a :class:`bytearray` object. The C variable may also be declared as :ctype:`PyObject\*`. -``u`` (Unicode object) [Py_UNICODE \*] +``u`` (:class:`str`) [Py_UNICODE \*] Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of Unicode characters. You must pass the address of a :ctype:`Py_UNICODE` pointer variable, which will be filled with the pointer to an existing Unicode buffer. Please note that the width of a :ctype:`Py_UNICODE` character depends on compilation options (it is either 16 or 32 bits). - ..note :: + .. note:: Since ``u`` doesn't give you back the length of the string, and it may contain embedded NUL characters, it is recommended to use ``u#`` or ``U`` instead. -``u#`` (Unicode object) [Py_UNICODE \*, int] +``u#`` (:class:`str`) [Py_UNICODE \*, int] This variant on ``u`` stores into two C variables, the first one a pointer to a Unicode data buffer, the second one its length. Non-Unicode objects are handled by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` array. -``Z`` (Unicode or ``None``) [Py_UNICODE \*] +``Z`` (:class:`str` or ``None``) [Py_UNICODE \*] Like ``u``, but the Python object may also be ``None``, in which case the :ctype:`Py_UNICODE` pointer is set to *NULL*. -``Z#`` (Unicode or ``None``) [Py_UNICODE \*, int] +``Z#`` (:class:`str` or ``None``) [Py_UNICODE \*, int] Like ``u#``, but the Python object may also be ``None``, in which case the :ctype:`Py_UNICODE` pointer is set to *NULL*. -``U`` (Unicode object) [PyUnicodeObject \*] +``U`` (:class:`str`) [PyUnicodeObject \*] Requires that the Python object is a Unicode object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a Unicode object. The C variable may also be declared as :ctype:`PyObject\*`. -``t#`` (read-only character buffer) [char \*, int] +``t#`` (:class:`bytes`, :class:`bytearray` or read-only character buffer) [char \*, int] Like ``s#``, but accepts any object which implements the read-only buffer interface. The :ctype:`char\*` variable is set to point to the first byte of the buffer, and the :ctype:`int` is set to the length of the buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``w`` (read-write character buffer) [char \*] +``w`` (:class:`bytearray` or read-write character buffer) [char \*] Similar to ``s``, but accepts any object which implements the read-write buffer interface. The caller must determine the length of the buffer by other means, or use ``w#`` instead. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``w*`` (read-write byte-oriented buffer) [Py_buffer] +``w*`` (:class:`bytearray` or read-write byte-oriented buffer) [Py_buffer] This is to ``w`` what ``s*`` is to ``s``. -``w#`` (read-write character buffer) [char \*, int] +``w#`` (:class:`bytearray` or read-write character buffer) [char \*, int] Like ``s#``, but accepts any object which implements the read-write buffer interface. The :ctype:`char \*` variable is set to point to the first byte of the buffer, and the :ctype:`int` is set to the length of the buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] +``es`` (:class:`str`) [const char \*encoding, char \*\*buffer] This variant on ``s`` is used for encoding Unicode and objects convertible to Unicode into a character buffer. It only works for encoded data without embedded NUL bytes. @@ -190,12 +191,12 @@ allocated storage. The caller is responsible for calling :cfunc:`PyMem_Free` to free the allocated buffer after use. -``et`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es`` except that 8-bit string objects are passed through without - recoding them. Instead, the implementation assumes that the string object uses +``et`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer] + Same as ``es`` except that byte string objects are passed through without + recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. -``es#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] +``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] This variant on ``s#`` is used for encoding Unicode and objects convertible to Unicode into a character buffer. Unlike the ``es`` format, this variant allows input data which contains NUL characters. @@ -226,71 +227,71 @@ In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. -``et#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - Same as ``es#`` except that string objects are passed through without recoding - them. Instead, the implementation assumes that the string object uses the +``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length] + Same as ``es#`` except that byte string objects are passed through without recoding + them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. Numbers ------- -``b`` (integer) [unsigned char] +``b`` (:class:`int`) [unsigned char] Convert a nonnegative Python integer to an unsigned tiny int, stored in a C :ctype:`unsigned char`. -``B`` (integer) [unsigned char] +``B`` (:class:`int`) [unsigned char] Convert a Python integer to a tiny int without overflow checking, stored in a C :ctype:`unsigned char`. -``h`` (integer) [short int] +``h`` (:class:`int`) [short int] Convert a Python integer to a C :ctype:`short int`. -``H`` (integer) [unsigned short int] +``H`` (:class:`int`) [unsigned short int] Convert a Python integer to a C :ctype:`unsigned short int`, without overflow checking. -``i`` (integer) [int] +``i`` (:class:`int`) [int] Convert a Python integer to a plain C :ctype:`int`. -``I`` (integer) [unsigned int] +``I`` (:class:`int`) [unsigned int] Convert a Python integer to a C :ctype:`unsigned int`, without overflow checking. -``l`` (integer) [long int] +``l`` (:class:`int`) [long int] Convert a Python integer to a C :ctype:`long int`. -``k`` (integer) [unsigned long] +``k`` (:class:`int`) [unsigned long] Convert a Python integer to a C :ctype:`unsigned long` without overflow checking. -``L`` (integer) [PY_LONG_LONG] +``L`` (:class:`int`) [PY_LONG_LONG] Convert a Python integer to a C :ctype:`long long`. This format is only available on platforms that support :ctype:`long long` (or :ctype:`_int64` on Windows). -``K`` (integer) [unsigned PY_LONG_LONG] +``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a Python integer to a C :ctype:`unsigned long long` without overflow checking. This format is only available on platforms that support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows). -``n`` (integer) [Py_ssize_t] +``n`` (:class:`int`) [Py_ssize_t] Convert a Python integer to a C :ctype:`Py_ssize_t`. -``c`` (bytes object of length 1) [char] +``c`` (:class:`bytes` of length 1) [char] Convert a Python byte, represented as a :class:`bytes` object of length 1, to a C :ctype:`char`. -``C`` (Unicode object of length 1) [int] - Convert a Python character, represented as a :class:`str`: object of +``C`` (:class:`str` of length 1) [int] + Convert a Python character, represented as a :class:`str` object of length 1, to a C :ctype:`int`. -``f`` (float) [float] +``f`` (:class:`float`) [float] Convert a Python floating point number to a C :ctype:`float`. -``d`` (float) [double] +``d`` (:class:`float`) [double] Convert a Python floating point number to a C :ctype:`double`. -``D`` (complex) [Py_complex] +``D`` (:class:`complex`) [Py_complex] Convert a Python complex number to a C :ctype:`Py_complex` structure. Other objects @@ -330,7 +331,7 @@ .. versionchanged:: 3.1 Py_CLEANUP_SUPPORTED was added. -``(items)`` (tuple) [*matching-items*] +``(items)`` (:class:`tuple`) [*matching-items*] The object must be a Python sequence whose length is the number of format units in *items*. The C arguments must correspond to the individual format units in *items*. Format units for sequences may be nested. @@ -489,95 +490,96 @@ not within format units such as ``s#``). This can be used to make long format strings a tad more readable. - ``s`` (string) [char \*] - Convert a null-terminated C string to a Python object. If the C string pointer - is *NULL*, ``None`` is used. - - ``s#`` (string) [char \*, int] - Convert a C string and its length to a Python object. If the C string pointer - is *NULL*, the length is ignored and ``None`` is returned. + ``s`` (:class:`str` or ``None``) [char \*] + Convert a null-terminated C string to a Python object using ``'utf-8'`` + encoding. If the C string pointer is *NULL*, ``None`` is used. + + ``s#`` (:class:`str` or ``None``) [char \*, int] + Convert a C string and its length to a Python object using ``'utf-8'`` + encoding. If the C string pointer is *NULL*, the length is ignored and + ``None`` is returned. - ``y`` (bytes) [char \*] + ``y`` (:class:`bytes`) [char \*] This converts a C string to a Python :func:`bytes` object. If the C string pointer is *NULL*, ``None`` is returned. - ``y#`` (bytes) [char \*, int] + ``y#`` (:class:`bytes`) [char \*, int] This converts a C string and its lengths to a Python object. If the C string pointer is *NULL*, ``None`` is returned. - ``z`` (string or ``None``) [char \*] + ``z`` (:class:`str` or ``None``) [char \*] Same as ``s``. - ``z#`` (string or ``None``) [char \*, int] + ``z#`` (:class:`str` or ``None``) [char \*, int] Same as ``s#``. - ``u`` (Unicode string) [Py_UNICODE \*] + ``u`` (:class:`str`) [Py_UNICODE \*] Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned. - ``u#`` (Unicode string) [Py_UNICODE \*, int] + ``u#`` (:class:`str`) [Py_UNICODE \*, int] Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored and ``None`` is returned. - ``U`` (string) [char \*] + ``U`` (:class:`str` or ``None``) [char \*] Convert a null-terminated C string to a Python unicode object. If the C string pointer is *NULL*, ``None`` is used. - ``U#`` (string) [char \*, int] + ``U#`` (:class:`str` or ``None``) [char \*, int] Convert a C string and its length to a Python unicode object. If the C string pointer is *NULL*, the length is ignored and ``None`` is returned. - ``i`` (integer) [int] + ``i`` (:class:`int`) [int] Convert a plain C :ctype:`int` to a Python integer object. - ``b`` (integer) [char] + ``b`` (:class:`int`) [char] Convert a plain C :ctype:`char` to a Python integer object. - ``h`` (integer) [short int] + ``h`` (:class:`int`) [short int] Convert a plain C :ctype:`short int` to a Python integer object. - ``l`` (integer) [long int] + ``l`` (:class:`int`) [long int] Convert a C :ctype:`long int` to a Python integer object. - ``B`` (integer) [unsigned char] + ``B`` (:class:`int`) [unsigned char] Convert a C :ctype:`unsigned char` to a Python integer object. - ``H`` (integer) [unsigned short int] + ``H`` (:class:`int`) [unsigned short int] Convert a C :ctype:`unsigned short int` to a Python integer object. - ``I`` (integer) [unsigned int] + ``I`` (:class:`int`) [unsigned int] Convert a C :ctype:`unsigned int` to a Python integer object. - ``k`` (integer) [unsigned long] + ``k`` (:class:`int`) [unsigned long] Convert a C :ctype:`unsigned long` to a Python integer object. - ``L`` (long) [PY_LONG_LONG] + ``L`` (:class:`int`) [PY_LONG_LONG] Convert a C :ctype:`long long` to a Python integer object. Only available on platforms that support :ctype:`long long`. - ``K`` (long) [unsigned PY_LONG_LONG] + ``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a C :ctype:`unsigned long long` to a Python integer object. Only available on platforms that support :ctype:`unsigned long long`. - ``n`` (int) [Py_ssize_t] + ``n`` (:class:`int`) [Py_ssize_t] Convert a C :ctype:`Py_ssize_t` to a Python integer. - ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a byte to a Python byte string of + ``c`` (:class:`bytes` of length 1) [char] + Convert a C :ctype:`int` representing a byte to a Python :class:`bytes` object of length 1. - ``C`` (string of length 1) [int] - Convert a C :ctype:`int` representing a character to Python unicode - string of length 1. + ``C`` (:class:`str` of length 1) [int] + Convert a C :ctype:`int` representing a character to Python :class:`str` + object of length 1. - ``d`` (float) [double] + ``d`` (:class:`float`) [double] Convert a C :ctype:`double` to a Python floating point number. - ``f`` (float) [float] - Same as ``d``. + ``f`` (:class:`float`) [float] + Convert a C :ctype:`float` to a Python floating point number. - ``D`` (complex) [Py_complex \*] + ``D`` (:class:`complex`) [Py_complex \*] Convert a C :ctype:`Py_complex` structure to a Python complex number. ``O`` (object) [PyObject \*] @@ -602,13 +604,13 @@ \*`) as its argument and should return a "new" Python object, or *NULL* if an error occurred. - ``(items)`` (tuple) [*matching-items*] + ``(items)`` (:class:`tuple`) [*matching-items*] Convert a sequence of C values to a Python tuple with the same number of items. - ``[items]`` (list) [*matching-items*] + ``[items]`` (:class:`list`) [*matching-items*] Convert a sequence of C values to a Python list with the same number of items. - ``{items}`` (dictionary) [*matching-items*] + ``{items}`` (:class:`dict`) [*matching-items*] Convert a sequence of C values to a Python dictionary. Each pair of consecutive C values adds one item to the dictionary, serving as key and value, respectively. From python-checkins at python.org Mon Jun 7 23:37:09 2010 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 7 Jun 2010 23:37:09 +0200 (CEST) Subject: [Python-checkins] r81813 - python/trunk/Objects/stringlib/formatter.h Message-ID: <20100607213709.30D6CEC04@mail.python.org> Author: benjamin.peterson Date: Mon Jun 7 23:37:09 2010 New Revision: 81813 Log: locale grouping strings should end in '\0' Modified: python/trunk/Objects/stringlib/formatter.h Modified: python/trunk/Objects/stringlib/formatter.h ============================================================================== --- python/trunk/Objects/stringlib/formatter.h (original) +++ python/trunk/Objects/stringlib/formatter.h Mon Jun 7 23:37:09 2010 @@ -649,7 +649,7 @@ case LT_DEFAULT_LOCALE: locale_info->decimal_point = "."; locale_info->thousands_sep = ","; - locale_info->grouping = "\3"; /* Group every 3 characters, + locale_info->grouping = "\3\0"; /* Group every 3 characters, trailing 0 means repeat infinitely. */ break; From python-checkins at python.org Mon Jun 7 23:41:35 2010 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 7 Jun 2010 23:41:35 +0200 (CEST) Subject: [Python-checkins] r81814 - in python/branches/py3k: Objects/stringlib/formatter.h Message-ID: <20100607214135.B0F7AF26C@mail.python.org> Author: benjamin.peterson Date: Mon Jun 7 23:41:35 2010 New Revision: 81814 Log: Merged revisions 81813 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81813 | benjamin.peterson | 2010-06-07 16:37:09 -0500 (Mon, 07 Jun 2010) | 2 lines locale grouping strings should end in '\0' ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Objects/stringlib/formatter.h Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Mon Jun 7 23:41:35 2010 @@ -649,7 +649,7 @@ case LT_DEFAULT_LOCALE: locale_info->decimal_point = "."; locale_info->thousands_sep = ","; - locale_info->grouping = "\3"; /* Group every 3 characters, + locale_info->grouping = "\3\0"; /* Group every 3 characters, trailing 0 means repeat infinitely. */ break; From python-checkins at python.org Mon Jun 7 23:53:11 2010 From: python-checkins at python.org (ezio.melotti) Date: Mon, 7 Jun 2010 23:53:11 +0200 (CEST) Subject: [Python-checkins] r81815 - in python/branches/release26-maint: Lib/test/test_shutil.py Message-ID: <20100607215311.1465AEE9AB@mail.python.org> Author: ezio.melotti Date: Mon Jun 7 23:53:10 2010 New Revision: 81815 Log: Merged revisions 81769 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81769 | ezio.melotti | 2010-06-06 01:28:10 +0300 (Sun, 06 Jun 2010) | 1 line Replace deprecated fail* methods with the equivalent assert* ones. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_shutil.py Modified: python/branches/release26-maint/Lib/test/test_shutil.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_shutil.py (original) +++ python/branches/release26-maint/Lib/test/test_shutil.py Mon Jun 7 23:53:10 2010 @@ -422,8 +422,8 @@ self._set_shutil_open(_open) shutil.copyfile('srcfile', 'destfile') - self.failUnless(srcfile._entered) - self.failUnless(srcfile._exited_with[0] is IOError) + self.assertTrue(srcfile._entered) + self.assertTrue(srcfile._exited_with[0] is IOError) self.assertEqual(srcfile._exited_with[1].args, ('Cannot open "destfile"',)) @@ -442,10 +442,10 @@ self._set_shutil_open(_open) shutil.copyfile('srcfile', 'destfile') - self.failUnless(srcfile._entered) - self.failUnless(destfile._entered) - self.failUnless(destfile._raised) - self.failUnless(srcfile._exited_with[0] is IOError) + self.assertTrue(srcfile._entered) + self.assertTrue(destfile._entered) + self.assertTrue(destfile._raised) + self.assertTrue(srcfile._exited_with[0] is IOError) self.assertEqual(srcfile._exited_with[1].args, ('Cannot close',)) @@ -465,11 +465,11 @@ self.assertRaises(IOError, shutil.copyfile, 'srcfile', 'destfile') - self.failUnless(srcfile._entered) - self.failUnless(destfile._entered) - self.failIf(destfile._raised) - self.failUnless(srcfile._exited_with[0] is None) - self.failUnless(srcfile._raised) + self.assertTrue(srcfile._entered) + self.assertTrue(destfile._entered) + self.assertFalse(destfile._raised) + self.assertTrue(srcfile._exited_with[0] is None) + self.assertTrue(srcfile._raised) def test_main(): From python-checkins at python.org Mon Jun 7 23:57:18 2010 From: python-checkins at python.org (ezio.melotti) Date: Mon, 7 Jun 2010 23:57:18 +0200 (CEST) Subject: [Python-checkins] r81816 - python/branches/py3k Message-ID: <20100607215718.F40BFEFE5@mail.python.org> Author: ezio.melotti Date: Mon Jun 7 23:57:18 2010 New Revision: 81816 Log: Blocked revisions 81769 via svnmerge ........ r81769 | ezio.melotti | 2010-06-06 01:28:10 +0300 (Sun, 06 Jun 2010) | 1 line Replace deprecated fail* methods with the equivalent assert* ones. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Jun 8 00:00:18 2010 From: python-checkins at python.org (ezio.melotti) Date: Tue, 8 Jun 2010 00:00:18 +0200 (CEST) Subject: [Python-checkins] r81817 - python/trunk/Lib/test/test___all__.py Message-ID: <20100607220018.3033BEEA71@mail.python.org> Author: ezio.melotti Date: Tue Jun 8 00:00:18 2010 New Revision: 81817 Log: Silence deprecation warning in test___all__ caused by an import bsddb. Modified: python/trunk/Lib/test/test___all__.py Modified: python/trunk/Lib/test/test___all__.py ============================================================================== --- python/trunk/Lib/test/test___all__.py (original) +++ python/trunk/Lib/test/test___all__.py Tue Jun 8 00:00:18 2010 @@ -7,8 +7,8 @@ # Setup bsddb warnings try: - import bsddb -except ImportError: + bsddb = support.import_module('bsddb', deprecated=True) +except unittest.SkipTest: pass From python-checkins at python.org Tue Jun 8 00:02:50 2010 From: python-checkins at python.org (ezio.melotti) Date: Tue, 8 Jun 2010 00:02:50 +0200 (CEST) Subject: [Python-checkins] r81818 - python/branches/py3k Message-ID: <20100607220250.B9418EEAA0@mail.python.org> Author: ezio.melotti Date: Tue Jun 8 00:02:50 2010 New Revision: 81818 Log: Blocked revisions 81817 via svnmerge ........ r81817 | ezio.melotti | 2010-06-08 01:00:18 +0300 (Tue, 08 Jun 2010) | 1 line Silence deprecation warning in test___all__ caused by an import bsddb. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Jun 8 00:04:54 2010 From: python-checkins at python.org (ezio.melotti) Date: Tue, 8 Jun 2010 00:04:54 +0200 (CEST) Subject: [Python-checkins] r81819 - python/branches/release26-maint Message-ID: <20100607220454.A8800EEA9F@mail.python.org> Author: ezio.melotti Date: Tue Jun 8 00:04:54 2010 New Revision: 81819 Log: Blocked revisions 81817 via svnmerge ........ r81817 | ezio.melotti | 2010-06-08 01:00:18 +0300 (Tue, 08 Jun 2010) | 1 line Silence deprecation warning in test___all__ caused by an import bsddb. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Jun 8 00:23:23 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 00:23:23 +0200 (CEST) Subject: [Python-checkins] r81820 - in python/trunk: Lib/test/test_unicode.py Misc/NEWS Objects/stringlib/string_format.h Message-ID: <20100607222323.6522EEEAB3@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 00:23:23 2010 New Revision: 81820 Log: correctly overflow when indexes are too large Modified: python/trunk/Lib/test/test_unicode.py python/trunk/Misc/NEWS python/trunk/Objects/stringlib/string_format.h Modified: python/trunk/Lib/test/test_unicode.py ============================================================================== --- python/trunk/Lib/test/test_unicode.py (original) +++ python/trunk/Lib/test/test_unicode.py Tue Jun 8 00:23:23 2010 @@ -1282,6 +1282,9 @@ self.assertRaises(IndexError, u"{:}".format) self.assertRaises(IndexError, u"{:s}".format) self.assertRaises(IndexError, u"{}".format) + big = "23098475029384702983476098230754973209482573" + self.assertRaises(ValueError, ("{" + big + "}").format) + self.assertRaises(ValueError, ("{[" + big + "]}").format, [0]) # issue 6089 self.assertRaises(ValueError, u"{0[0]x}".format, [None]) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Jun 8 00:23:23 2010 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- In the unicode/str.format(), raise a ValueError when either indexes to + arguments are too large. + Library ------- Modified: python/trunk/Objects/stringlib/string_format.h ============================================================================== --- python/trunk/Objects/stringlib/string_format.h (original) +++ python/trunk/Objects/stringlib/string_format.h Tue Jun 8 00:23:23 2010 @@ -373,6 +373,8 @@ if (_FieldNameIterator_item(self, name) == 0) return 0; *name_idx = get_integer(name); + if (*name_idx == -1 && PyErr_Occurred()) + return 0; break; default: /* Invalid character follows ']' */ @@ -429,6 +431,8 @@ /* see if "first" is an integer, in which case it's used as an index */ *first_idx = get_integer(first); + if (*first_idx == -1 && PyErr_Occurred()) + return 0; field_name_is_empty = first->ptr >= first->end; From eric at trueblade.com Tue Jun 8 00:23:45 2010 From: eric at trueblade.com (Eric Smith) Date: Mon, 07 Jun 2010 18:23:45 -0400 Subject: [Python-checkins] r81813 - python/trunk/Objects/stringlib/formatter.h In-Reply-To: <20100607213709.30D6CEC04@mail.python.org> References: <20100607213709.30D6CEC04@mail.python.org> Message-ID: <4C0D7171.7050801@trueblade.com> String literals already have a trailing zero byte, so now you're wasting space! Maybe a better comment would be in line. Eric. benjamin.peterson wrote: > Author: benjamin.peterson > Date: Mon Jun 7 23:37:09 2010 > New Revision: 81813 > > Log: > locale grouping strings should end in '\0' > > > Modified: > python/trunk/Objects/stringlib/formatter.h > > Modified: python/trunk/Objects/stringlib/formatter.h > ============================================================================== > --- python/trunk/Objects/stringlib/formatter.h (original) > +++ python/trunk/Objects/stringlib/formatter.h Mon Jun 7 23:37:09 2010 > @@ -649,7 +649,7 @@ > case LT_DEFAULT_LOCALE: > locale_info->decimal_point = "."; > locale_info->thousands_sep = ","; > - locale_info->grouping = "\3"; /* Group every 3 characters, > + locale_info->grouping = "\3\0"; /* Group every 3 characters, > trailing 0 means repeat > infinitely. */ > break; > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > -- Eric. From python-checkins at python.org Tue Jun 8 00:24:18 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 00:24:18 +0200 (CEST) Subject: [Python-checkins] r81821 - python/branches/py3k/Parser/asdl_c.py Message-ID: <20100607222418.4BFE0EEABF@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 00:24:18 2010 New Revision: 81821 Log: use the 's' format code instead of 'U' Modified: python/branches/py3k/Parser/asdl_c.py Modified: python/branches/py3k/Parser/asdl_c.py ============================================================================== --- python/branches/py3k/Parser/asdl_c.py (original) +++ python/branches/py3k/Parser/asdl_c.py Tue Jun 8 00:24:18 2010 @@ -722,7 +722,7 @@ } PyTuple_SET_ITEM(fnames, i, field); } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "U(O){sOss}", + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sOss}", type, base, "_fields", fnames, "__module__", "_ast"); Py_DECREF(fnames); return (PyTypeObject*)result; From python-checkins at python.org Tue Jun 8 00:27:32 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 00:27:32 +0200 (CEST) Subject: [Python-checkins] r81822 - in python/branches/release26-maint: Lib/test/test_unicode.py Misc/NEWS Objects/stringlib/string_format.h Message-ID: <20100607222732.964B7EE9EE@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 00:27:32 2010 New Revision: 81822 Log: Merged revisions 81820 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81820 | benjamin.peterson | 2010-06-07 17:23:23 -0500 (Mon, 07 Jun 2010) | 1 line correctly overflow when indexes are too large ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_unicode.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/stringlib/string_format.h Modified: python/branches/release26-maint/Lib/test/test_unicode.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_unicode.py (original) +++ python/branches/release26-maint/Lib/test/test_unicode.py Tue Jun 8 00:27:32 2010 @@ -1103,6 +1103,9 @@ self.assertRaises(ValueError, u"{:}".format) self.assertRaises(ValueError, u"{:s}".format) self.assertRaises(ValueError, u"{}".format) + big = "23098475029384702983476098230754973209482573" + self.assertRaises(ValueError, ("{" + big + "}").format) + self.assertRaises(ValueError, ("{[" + big + "]}").format, [0]) # issue 6089 self.assertRaises(ValueError, u"{0[0]x}".format, [None]) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Tue Jun 8 00:27:32 2010 @@ -18,6 +18,9 @@ when turned into an exception: in this case the exception simply gets ignored. +- In the unicode/str.format(), raise a ValueError when either indexes to + arguments are too large. + - Issue #3798: Write sys.exit() message to sys.stderr to use stderr encoding and error handler, instead of writing to the C stderr file in utf-8 Modified: python/branches/release26-maint/Objects/stringlib/string_format.h ============================================================================== --- python/branches/release26-maint/Objects/stringlib/string_format.h (original) +++ python/branches/release26-maint/Objects/stringlib/string_format.h Tue Jun 8 00:27:32 2010 @@ -327,6 +327,8 @@ if (_FieldNameIterator_item(self, name) == 0) return 0; *name_idx = get_integer(name); + if (*name_idx == -1 && PyErr_Occurred()) + return 0; break; default: /* Invalid character follows ']' */ @@ -380,6 +382,8 @@ /* see if "first" is an integer, in which case it's used as an index */ *first_idx = get_integer(first); + if (*first_idx == -1 && PyErr_Occurred()) + return 0; /* zero length string is an error */ if (first->ptr >= first->end) { From python-checkins at python.org Tue Jun 8 00:31:26 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 00:31:26 +0200 (CEST) Subject: [Python-checkins] r81823 - in python/branches/py3k: Lib/test/test_unicode.py Misc/NEWS Objects/stringlib/string_format.h Message-ID: <20100607223126.C9817EE98A@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 00:31:26 2010 New Revision: 81823 Log: Merged revisions 81820 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81820 | benjamin.peterson | 2010-06-07 17:23:23 -0500 (Mon, 07 Jun 2010) | 1 line correctly overflow when indexes are too large ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_unicode.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/stringlib/string_format.h Modified: python/branches/py3k/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicode.py (original) +++ python/branches/py3k/Lib/test/test_unicode.py Tue Jun 8 00:31:26 2010 @@ -681,6 +681,9 @@ self.assertRaises(IndexError, "{:}".format) self.assertRaises(IndexError, "{:s}".format) self.assertRaises(IndexError, "{}".format) + big = "23098475029384702983476098230754973209482573" + self.assertRaises(ValueError, ("{" + big + "}").format) + self.assertRaises(ValueError, ("{[" + big + "]}").format, [0]) # issue 6089 self.assertRaises(ValueError, "{0[0]x}".format, [None]) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Jun 8 00:31:26 2010 @@ -15,6 +15,9 @@ - Issue #8837: Remove "O?" format of PyArg_Parse*() functions. The format is no used anymore and it was never documented. +- In the str.format(), raise a ValueError when either indexes to arguments are + too large. + - Issue #2844: Make int('42', n) consistently raise ValueError for invalid integers n (including n = -909). Modified: python/branches/py3k/Objects/stringlib/string_format.h ============================================================================== --- python/branches/py3k/Objects/stringlib/string_format.h (original) +++ python/branches/py3k/Objects/stringlib/string_format.h Tue Jun 8 00:31:26 2010 @@ -373,6 +373,8 @@ if (_FieldNameIterator_item(self, name) == 0) return 0; *name_idx = get_integer(name); + if (*name_idx == -1 && PyErr_Occurred()) + return 0; break; default: /* Invalid character follows ']' */ @@ -429,6 +431,8 @@ /* see if "first" is an integer, in which case it's used as an index */ *first_idx = get_integer(first); + if (*first_idx == -1 && PyErr_Occurred()) + return 0; field_name_is_empty = first->ptr >= first->end; From python-checkins at python.org Tue Jun 8 00:32:45 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 00:32:45 +0200 (CEST) Subject: [Python-checkins] r81824 - python/trunk/Objects/stringlib/formatter.h Message-ID: <20100607223245.0B597EEAAA@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 00:32:44 2010 New Revision: 81824 Log: remove extra byte and fix comment Modified: python/trunk/Objects/stringlib/formatter.h Modified: python/trunk/Objects/stringlib/formatter.h ============================================================================== --- python/trunk/Objects/stringlib/formatter.h (original) +++ python/trunk/Objects/stringlib/formatter.h Tue Jun 8 00:32:44 2010 @@ -649,8 +649,8 @@ case LT_DEFAULT_LOCALE: locale_info->decimal_point = "."; locale_info->thousands_sep = ","; - locale_info->grouping = "\3\0"; /* Group every 3 characters, - trailing 0 means repeat + locale_info->grouping = "\3"; /* Group every 3 characters. The + (implicit) trailing 0 means repeat infinitely. */ break; case LT_NO_LOCALE: From python-checkins at python.org Tue Jun 8 00:33:09 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 00:33:09 +0200 (CEST) Subject: [Python-checkins] r81825 - python/trunk/Lib/test/test_unicode.py Message-ID: <20100607223309.5A376EE9AA@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 00:33:09 2010 New Revision: 81825 Log: use unicode literals Modified: python/trunk/Lib/test/test_unicode.py Modified: python/trunk/Lib/test/test_unicode.py ============================================================================== --- python/trunk/Lib/test/test_unicode.py (original) +++ python/trunk/Lib/test/test_unicode.py Tue Jun 8 00:33:09 2010 @@ -1282,9 +1282,9 @@ self.assertRaises(IndexError, u"{:}".format) self.assertRaises(IndexError, u"{:s}".format) self.assertRaises(IndexError, u"{}".format) - big = "23098475029384702983476098230754973209482573" - self.assertRaises(ValueError, ("{" + big + "}").format) - self.assertRaises(ValueError, ("{[" + big + "]}").format, [0]) + big = u"23098475029384702983476098230754973209482573" + self.assertRaises(ValueError, (u"{" + big + u"}").format) + self.assertRaises(ValueError, (u"{[" + big + u"]}").format, [0]) # issue 6089 self.assertRaises(ValueError, u"{0[0]x}".format, [None]) From benjamin at python.org Tue Jun 8 00:34:46 2010 From: benjamin at python.org (Benjamin Peterson) Date: Mon, 7 Jun 2010 17:34:46 -0500 Subject: [Python-checkins] r81813 - python/trunk/Objects/stringlib/formatter.h In-Reply-To: <4C0D7171.7050801@trueblade.com> References: <20100607213709.30D6CEC04@mail.python.org> <4C0D7171.7050801@trueblade.com> Message-ID: 2010/6/7 Eric Smith : > String literals already have a trailing zero byte, so now you're wasting > space! Oops. Thanks for picking up. > > Maybe a better comment would be in line. Maybe I should study C again. :) -- Regards, Benjamin From python-checkins at python.org Tue Jun 8 00:35:08 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 00:35:08 +0200 (CEST) Subject: [Python-checkins] r81826 - in python/branches/py3k: Objects/stringlib/formatter.h Message-ID: <20100607223508.C90DBEEA18@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 00:35:08 2010 New Revision: 81826 Log: Merged revisions 81824 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81824 | benjamin.peterson | 2010-06-07 17:32:44 -0500 (Mon, 07 Jun 2010) | 1 line remove extra byte and fix comment ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Objects/stringlib/formatter.h Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Tue Jun 8 00:35:08 2010 @@ -649,8 +649,8 @@ case LT_DEFAULT_LOCALE: locale_info->decimal_point = "."; locale_info->thousands_sep = ","; - locale_info->grouping = "\3\0"; /* Group every 3 characters, - trailing 0 means repeat + locale_info->grouping = "\3"; /* Group every 3 characters. The + (implicit) trailing 0 means repeat infinitely. */ break; case LT_NO_LOCALE: From python-checkins at python.org Tue Jun 8 00:36:44 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 00:36:44 +0200 (CEST) Subject: [Python-checkins] r81827 - python/branches/py3k Message-ID: <20100607223644.A0AC8EEA03@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 00:36:44 2010 New Revision: 81827 Log: Blocked revisions 81825 via svnmerge ........ r81825 | benjamin.peterson | 2010-06-07 17:33:09 -0500 (Mon, 07 Jun 2010) | 1 line use unicode literals ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Jun 8 00:38:19 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 00:38:19 +0200 (CEST) Subject: [Python-checkins] r81828 - in python/branches/release26-maint: Lib/test/test_unicode.py Message-ID: <20100607223819.424FDEE9C7@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 00:38:19 2010 New Revision: 81828 Log: Merged revisions 81825 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81825 | benjamin.peterson | 2010-06-07 17:33:09 -0500 (Mon, 07 Jun 2010) | 1 line use unicode literals ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_unicode.py Modified: python/branches/release26-maint/Lib/test/test_unicode.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_unicode.py (original) +++ python/branches/release26-maint/Lib/test/test_unicode.py Tue Jun 8 00:38:19 2010 @@ -1103,9 +1103,9 @@ self.assertRaises(ValueError, u"{:}".format) self.assertRaises(ValueError, u"{:s}".format) self.assertRaises(ValueError, u"{}".format) - big = "23098475029384702983476098230754973209482573" - self.assertRaises(ValueError, ("{" + big + "}").format) - self.assertRaises(ValueError, ("{[" + big + "]}").format, [0]) + big = u"23098475029384702983476098230754973209482573" + self.assertRaises(ValueError, (u"{" + big + u"}").format) + self.assertRaises(ValueError, (u"{[" + big + u"]}").format, [0]) # issue 6089 self.assertRaises(ValueError, u"{0[0]x}".format, [None]) From solipsis at pitrou.net Tue Jun 8 01:26:58 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 8 Jun 2010 01:26:58 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81809): sum=0 Message-ID: <20100607232658.7E4E717758@ns6635.ovh.net> py3k results for svn r81809 (hg cset e147ff4e90fe) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog1DxDrH', '-x'] From ezio.melotti at gmail.com Tue Jun 8 04:04:44 2010 From: ezio.melotti at gmail.com (Ezio Melotti) Date: Tue, 08 Jun 2010 05:04:44 +0300 Subject: [Python-checkins] r81807 - in python/branches/py3k: Doc/c-api/arg.rst Modules/_ctypes/_ctypes.c Objects/exceptions.c Python/Python-ast.c Python/errors.c Python/modsupport.c Python/sysmodule.c In-Reply-To: <20100607195746.9AE94EEA31@mail.python.org> References: <20100607195746.9AE94EEA31@mail.python.org> Message-ID: <4C0DA53C.1030706@gmail.com> An HTML attachment was scrubbed... URL: From victor.stinner at haypocalc.com Tue Jun 8 14:32:53 2010 From: victor.stinner at haypocalc.com (Victor Stinner) Date: Tue, 8 Jun 2010 14:32:53 +0200 Subject: [Python-checkins] =?utf-8?q?r81807_-_in_python/branches/py3k=3A?= =?utf-8?q?=09Doc/c-api/arg=2Erst_Modules/=5Fctypes/=5Fctypes=2Ec=09Object?= =?utf-8?q?s/exceptions=2Ec_Python/Python-ast=2Ec_Python/errors=2Ec_Python?= =?utf-8?q?/modsupport=2Ec_Python/sysmodule=2Ec?= In-Reply-To: <4C0DA53C.1030706@gmail.com> References: <20100607195746.9AE94EEA31@mail.python.org> <4C0DA53C.1030706@gmail.com> Message-ID: <201006081432.53530.victor.stinner@haypocalc.com> Le mardi 08 juin 2010 04:04:44, Ezio Melotti a ?crit : > I didn't read the code of modsupport.c You should read the code before my commit: it was *exactly* the same. > However the doc (...) The doc is outdated: fixed by r81811. > (shouldn't they all have the same signature too?) (done in r81811) From solipsis at pitrou.net Tue Jun 8 14:40:18 2010 From: solipsis at pitrou.net (Antoine Pitrou) Date: Tue, 8 Jun 2010 14:40:18 +0200 Subject: [Python-checkins] r81811 - python/branches/py3k/Doc/c-api/arg.rst References: <20100607212042.0A63BEE9AD@mail.python.org> Message-ID: <20100608144018.295f1835@pitrou.net> On Mon, 7 Jun 2010 23:20:42 +0200 (CEST) victor.stinner wrote: > Issue #8925: fix types of Py_Parse*() and Py_BuildValue() functions > > * Add links to Python types > * Replace "string" by bytes or str > * Replace "long" by "int" I'm not sure this is a good idea, really. This file describes a part of the C API. Adding links to the Python facing types seems confusing to me. Also, the descriptions themselves still use terms such as "Unicode object" (rather than "str"), which makes things inconsistent and difficult to follow. From mal at egenix.com Tue Jun 8 14:44:05 2010 From: mal at egenix.com (M.-A. Lemburg) Date: Tue, 08 Jun 2010 14:44:05 +0200 Subject: [Python-checkins] r81811 - python/branches/py3k/Doc/c-api/arg.rst In-Reply-To: <20100608144018.295f1835@pitrou.net> References: <20100607212042.0A63BEE9AD@mail.python.org> <20100608144018.295f1835@pitrou.net> Message-ID: <4C0E3B15.50005@egenix.com> Antoine Pitrou wrote: > On Mon, 7 Jun 2010 23:20:42 +0200 (CEST) > victor.stinner wrote: >> Issue #8925: fix types of Py_Parse*() and Py_BuildValue() functions >> >> * Add links to Python types >> * Replace "string" by bytes or str >> * Replace "long" by "int" > > I'm not sure this is a good idea, really. This file describes a part of > the C API. Adding links to the Python facing types seems confusing to > me. Also, the descriptions themselves still use terms such as "Unicode > object" (rather than "str"), which makes things inconsistent and > difficult to follow. Agreed. Perhaps we should start using e.g. PyUnicode, PyBytes, PyLong, etc. in the docs to more closely follow the C API rather use the type names you see at the Python level. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Jun 08 2010) >>> Python/Zope Consulting and Support ... http://www.egenix.com/ >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ ________________________________________________________________________ 2010-07-19: EuroPython 2010, Birmingham, UK 40 days to go ::: Try our new mxODBC.Connect Python Database Interface for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/ From solipsis at pitrou.net Tue Jun 8 14:52:57 2010 From: solipsis at pitrou.net (Antoine Pitrou) Date: Tue, 8 Jun 2010 14:52:57 +0200 Subject: [Python-checkins] r81811 - python/branches/py3k/Doc/c-api/arg.rst In-Reply-To: <4C0E3B15.50005@egenix.com> References: <20100607212042.0A63BEE9AD@mail.python.org> <20100608144018.295f1835@pitrou.net> <4C0E3B15.50005@egenix.com> Message-ID: <20100608145257.11fc893c@pitrou.net> On Tue, 08 Jun 2010 14:44:05 +0200 "M.-A. Lemburg" wrote: > Antoine Pitrou wrote: > > On Mon, 7 Jun 2010 23:20:42 +0200 (CEST) > > victor.stinner wrote: > >> Issue #8925: fix types of Py_Parse*() and Py_BuildValue() functions > >> > >> * Add links to Python types > >> * Replace "string" by bytes or str > >> * Replace "long" by "int" > > > > I'm not sure this is a good idea, really. This file describes a part of > > the C API. Adding links to the Python facing types seems confusing to > > me. Also, the descriptions themselves still use terms such as "Unicode > > object" (rather than "str"), which makes things inconsistent and > > difficult to follow. > > Agreed. > > Perhaps we should start using e.g. PyUnicode, PyBytes, > PyLong, etc. in the docs to more closely follow the C API rather > use the type names you see at the Python level. Yes, I think this would be more useful for the reader. Regards Antoine. From python-checkins at python.org Tue Jun 8 15:26:50 2010 From: python-checkins at python.org (stefan.krah) Date: Tue, 8 Jun 2010 15:26:50 +0200 (CEST) Subject: [Python-checkins] r81829 - python/branches/py3k Message-ID: <20100608132650.524A2EE98D@mail.python.org> Author: stefan.krah Date: Tue Jun 8 15:26:49 2010 New Revision: 81829 Log: Blocked revisions 81669,81672,81683 via svnmerge ........ r81669 | stefan.krah | 2010-06-03 14:39:50 +0200 (Thu, 03 Jun 2010) | 9 lines Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. Thanks Thomas Dickey for answering questions about ncurses/ncursesw and readline! ........ r81672 | stefan.krah | 2010-06-03 16:25:16 +0200 (Thu, 03 Jun 2010) | 3 lines Use compiler rather than compiler_obj. Thanks Michael Foord for noticing. ........ r81683 | stefan.krah | 2010-06-04 11:49:20 +0200 (Fri, 04 Jun 2010) | 1 line Detect missing ldd on all systems. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Jun 8 15:41:44 2010 From: python-checkins at python.org (stefan.krah) Date: Tue, 8 Jun 2010 15:41:44 +0200 (CEST) Subject: [Python-checkins] r81830 - in python/branches/py3k: Lib/test/test_curses.py setup.py Message-ID: <20100608134144.913B4EE998@mail.python.org> Author: stefan.krah Date: Tue Jun 8 15:41:44 2010 New Revision: 81830 Log: Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. Thanks Thomas Dickey for answering questions about ncurses/ncursesw and readline! Modified: python/branches/py3k/Lib/test/test_curses.py python/branches/py3k/setup.py Modified: python/branches/py3k/Lib/test/test_curses.py ============================================================================== --- python/branches/py3k/Lib/test/test_curses.py (original) +++ python/branches/py3k/Lib/test/test_curses.py Tue Jun 8 15:41:44 2010 @@ -23,11 +23,6 @@ curses = import_module('curses') curses.panel = import_module('curses.panel') -# skip all these tests on FreeBSD: test_curses currently hangs the -# FreeBSD buildbots, preventing other tests from running. See issue -# #7384. -if 'freebsd' in sys.platform: - raise unittest.SkipTest('The curses module is broken on FreeBSD. See http://bugs.python.org/issue7384.') # XXX: if newterm was supported we could use it instead of initscr and not exit term = os.environ.get('TERM') Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Tue Jun 8 15:41:44 2010 @@ -14,6 +14,7 @@ from distutils.command.build_ext import build_ext from distutils.command.install import install from distutils.command.install_lib import install_lib +from distutils.spawn import find_executable # Were we compiled --with-pydebug or with #define Py_DEBUG? COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') @@ -525,6 +526,38 @@ # readline do_readline = self.compiler_obj.find_library_file(lib_dirs, 'readline') + readline_termcap_library = "" + curses_library = "" + # Determine if readline is already linked against curses or tinfo. + if do_readline and find_executable('ldd'): + # Cannot use os.popen here in py3k. + tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) + os.system("ldd %s > %s" % (do_readline, tmpfile)) + fp = open(tmpfile) + for ln in fp: + if 'curses' in ln: + readline_termcap_library = re.sub( + r'.*lib(n?cursesw?)\.so.*', r'\1', ln + ).rstrip() + break + if 'tinfo' in ln: # termcap interface split out from ncurses + readline_termcap_library = 'tinfo' + break + fp.close() + os.unlink(tmpfile) + # Issue 7384: If readline is already linked against curses, + # use the same library for the readline and curses modules. + if 'curses' in readline_termcap_library: + curses_library = readline_termcap_library + elif self.compiler_obj.find_library_file(lib_dirs, 'ncursesw'): + curses_library = 'ncursesw' + elif self.compiler_obj.find_library_file(lib_dirs, 'ncurses'): + curses_library = 'ncurses' + elif self.compiler_obj.find_library_file(lib_dirs, 'curses'): + curses_library = 'curses' + if platform == 'darwin': os_release = int(os.uname()[2].split('.')[0]) dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') @@ -548,14 +581,10 @@ readline_extra_link_args = () readline_libs = ['readline'] - if self.compiler_obj.find_library_file(lib_dirs, - 'ncursesw'): - readline_libs.append('ncursesw') - elif self.compiler_obj.find_library_file(lib_dirs, - 'ncurses'): - readline_libs.append('ncurses') - elif self.compiler_obj.find_library_file(lib_dirs, 'curses'): - readline_libs.append('curses') + if readline_termcap_library: + pass # Issue 7384: Already linked against curses or tinfo. + elif curses_library: + readline_libs.append(curses_library) elif self.compiler_obj.find_library_file(lib_dirs + ['/usr/lib/termcap'], 'termcap'): @@ -1070,19 +1099,15 @@ # Curses support, requiring the System V version of curses, often # provided by the ncurses library. panel_library = 'panel' - if (self.compiler_obj.find_library_file(lib_dirs, 'ncursesw')): - curses_libs = ['ncursesw'] - # Bug 1464056: If _curses.so links with ncursesw, - # _curses_panel.so must link with panelw. - panel_library = 'panelw' - exts.append( Extension('_curses', ['_cursesmodule.c'], - libraries = curses_libs) ) - elif (self.compiler_obj.find_library_file(lib_dirs, 'ncurses')): - curses_libs = ['ncurses'] + if curses_library.startswith('ncurses'): + if curses_library == 'ncursesw': + # Bug 1464056: If _curses.so links with ncursesw, + # _curses_panel.so must link with panelw. + panel_library = 'panelw' + curses_libs = [curses_library] exts.append( Extension('_curses', ['_cursesmodule.c'], libraries = curses_libs) ) - elif (self.compiler_obj.find_library_file(lib_dirs, 'curses') - and platform != 'darwin'): + elif curses_library == 'curses' and platform != 'darwin': # OSX has an old Berkeley curses, not good enough for # the _curses module. if (self.compiler_obj.find_library_file(lib_dirs, 'terminfo')): From python-checkins at python.org Tue Jun 8 16:00:52 2010 From: python-checkins at python.org (stefan.krah) Date: Tue, 8 Jun 2010 16:00:52 +0200 (CEST) Subject: [Python-checkins] r81831 - python/branches/py3k/Misc/NEWS Message-ID: <20100608140052.84B3BEEB01@mail.python.org> Author: stefan.krah Date: Tue Jun 8 16:00:52 2010 New Revision: 81831 Log: Add note for r81830. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Jun 8 16:00:52 2010 @@ -1259,6 +1259,10 @@ Extension Modules ----------------- +- Issue #7384: If the system readline library is linked against ncurses, + the curses module must be linked against ncurses as well. Otherwise it + is not safe to load both the readline and curses modules in an application. + - Issue #2810: Fix cases where the Windows registry API returns ERROR_MORE_DATA, requiring a re-try in order to get the complete result. From python-checkins at python.org Tue Jun 8 16:41:45 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 8 Jun 2010 16:41:45 +0200 (CEST) Subject: [Python-checkins] r81832 - python/branches/py3k/Lib/test/test_sundry.py Message-ID: <20100608144145.B02DAEE983@mail.python.org> Author: r.david.murray Date: Tue Jun 8 16:41:45 2010 New Revision: 81832 Log: Now that sunau has some tests, remove it from test_sundry. Modified: python/branches/py3k/Lib/test/test_sundry.py Modified: python/branches/py3k/Lib/test/test_sundry.py ============================================================================== --- python/branches/py3k/Lib/test/test_sundry.py (original) +++ python/branches/py3k/Lib/test/test_sundry.py Tue Jun 8 16:41:45 2010 @@ -60,7 +60,6 @@ import rlcompleter import sched import sndhdr - import sunau import symbol import tabnanny import timeit From python-checkins at python.org Tue Jun 8 16:43:46 2010 From: python-checkins at python.org (r.david.murray) Date: Tue, 8 Jun 2010 16:43:46 +0200 (CEST) Subject: [Python-checkins] r81833 - in python/branches/release31-maint: Lib/test/test_sundry.py Message-ID: <20100608144346.43067EE983@mail.python.org> Author: r.david.murray Date: Tue Jun 8 16:43:46 2010 New Revision: 81833 Log: Merged revisions 81832 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81832 | r.david.murray | 2010-06-08 10:41:45 -0400 (Tue, 08 Jun 2010) | 2 lines Now that sunau has some tests, remove it from test_sundry. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_sundry.py Modified: python/branches/release31-maint/Lib/test/test_sundry.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_sundry.py (original) +++ python/branches/release31-maint/Lib/test/test_sundry.py Tue Jun 8 16:43:46 2010 @@ -62,7 +62,6 @@ import rlcompleter import sched import sndhdr - import sunau import symbol import tabnanny import timeit From python-checkins at python.org Tue Jun 8 16:53:29 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 16:53:29 +0200 (CEST) Subject: [Python-checkins] r81834 - python/trunk/Misc/NEWS Message-ID: <20100608145329.4B9B1F855@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 16:53:29 2010 New Revision: 81834 Log: kill extra word Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Jun 8 16:53:29 2010 @@ -12,8 +12,8 @@ Core and Builtins ----------------- -- In the unicode/str.format(), raise a ValueError when either indexes to - arguments are too large. +- In the unicode/str.format(), raise a ValueError when indexes to arguments are + too large. Library ------- From python-checkins at python.org Tue Jun 8 16:57:22 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 16:57:22 +0200 (CEST) Subject: [Python-checkins] r81835 - in python/branches/py3k: Misc/NEWS Message-ID: <20100608145722.97EDEF134@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 16:57:22 2010 New Revision: 81835 Log: Merged revisions 81834 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81834 | benjamin.peterson | 2010-06-08 09:53:29 -0500 (Tue, 08 Jun 2010) | 1 line kill extra word ........ 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 Tue Jun 8 16:57:22 2010 @@ -15,8 +15,8 @@ - Issue #8837: Remove "O?" format of PyArg_Parse*() functions. The format is no used anymore and it was never documented. -- In the str.format(), raise a ValueError when either indexes to arguments are - too large. +- In the str.format(), raise a ValueError when indexes to arguments are too + large. - Issue #2844: Make int('42', n) consistently raise ValueError for invalid integers n (including n = -909). From python-checkins at python.org Tue Jun 8 16:58:25 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 16:58:25 +0200 (CEST) Subject: [Python-checkins] r81836 - in python/branches/release26-maint: Misc/NEWS Message-ID: <20100608145825.D98C8EEB23@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 16:58:25 2010 New Revision: 81836 Log: Merged revisions 81834 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81834 | benjamin.peterson | 2010-06-08 09:53:29 -0500 (Tue, 08 Jun 2010) | 1 line kill extra word ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Tue Jun 8 16:58:25 2010 @@ -18,8 +18,8 @@ when turned into an exception: in this case the exception simply gets ignored. -- In the unicode/str.format(), raise a ValueError when either indexes to - arguments are too large. +- In the unicode/str.format(), raise a ValueError when indexes to arguments are + too large. - Issue #3798: Write sys.exit() message to sys.stderr to use stderr encoding and error handler, instead of writing to the C stderr file in utf-8 From python-checkins at python.org Tue Jun 8 17:12:17 2010 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 8 Jun 2010 17:12:17 +0200 (CEST) Subject: [Python-checkins] r81837 - in python/branches/release31-maint: Lib/test/test_unicode.py Misc/NEWS Objects/stringlib/string_format.h Message-ID: <20100608151217.722ADEEB8B@mail.python.org> Author: benjamin.peterson Date: Tue Jun 8 17:12:17 2010 New Revision: 81837 Log: Merged revisions 81823,81835 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81823 | benjamin.peterson | 2010-06-07 17:31:26 -0500 (Mon, 07 Jun 2010) | 9 lines Merged revisions 81820 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81820 | benjamin.peterson | 2010-06-07 17:23:23 -0500 (Mon, 07 Jun 2010) | 1 line correctly overflow when indexes are too large ........ ................ r81835 | benjamin.peterson | 2010-06-08 09:57:22 -0500 (Tue, 08 Jun 2010) | 9 lines Merged revisions 81834 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81834 | benjamin.peterson | 2010-06-08 09:53:29 -0500 (Tue, 08 Jun 2010) | 1 line kill extra word ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_unicode.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Objects/stringlib/string_format.h Modified: python/branches/release31-maint/Lib/test/test_unicode.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_unicode.py (original) +++ python/branches/release31-maint/Lib/test/test_unicode.py Tue Jun 8 17:12:17 2010 @@ -687,6 +687,9 @@ self.assertRaises(IndexError, "{:}".format) self.assertRaises(IndexError, "{:s}".format) self.assertRaises(IndexError, "{}".format) + big = "23098475029384702983476098230754973209482573" + self.assertRaises(ValueError, ("{" + big + "}").format) + self.assertRaises(ValueError, ("{[" + big + "]}").format, [0]) # issue 6089 self.assertRaises(ValueError, "{0[0]x}".format, [None]) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Tue Jun 8 17:12:17 2010 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- In the str.format(), raise a ValueError when indexes to arguments are too + large. + - Issue #8766: Initialize _warnings module before importing the first module. Fix a crash if an empty directory called "encodings" exists in sys.path. Modified: python/branches/release31-maint/Objects/stringlib/string_format.h ============================================================================== --- python/branches/release31-maint/Objects/stringlib/string_format.h (original) +++ python/branches/release31-maint/Objects/stringlib/string_format.h Tue Jun 8 17:12:17 2010 @@ -373,6 +373,8 @@ if (_FieldNameIterator_item(self, name) == 0) return 0; *name_idx = get_integer(name); + if (*name_idx == -1 && PyErr_Occurred()) + return 0; break; default: /* Invalid character follows ']' */ @@ -429,6 +431,8 @@ /* see if "first" is an integer, in which case it's used as an index */ *first_idx = get_integer(first); + if (*first_idx == -1 && PyErr_Occurred()) + return 0; field_name_is_empty = first->ptr >= first->end; From python-checkins at python.org Tue Jun 8 19:06:48 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Tue, 8 Jun 2010 19:06:48 +0200 (CEST) Subject: [Python-checkins] r81838 - python/branches/py3k/Misc/maintainers.rst Message-ID: <20100608170648.A9046EE983@mail.python.org> Author: alexander.belopolsky Date: Tue Jun 8 19:06:48 2010 New Revision: 81838 Log: Added myself as a maintainer of time and datetime modules. 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 Tue Jun 8 19:06:48 2010 @@ -80,7 +80,7 @@ csv ctypes theller curses andrew.kuchling -datetime +datetime alexander.belopolsky dbm decimal facundobatista, rhettinger, mark.dickinson difflib tim_one @@ -207,7 +207,7 @@ test textwrap threading -time +time alexander.belopolsky timeit tkinter gpolo token georg.brandl From python-checkins at python.org Tue Jun 8 19:15:33 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Tue, 8 Jun 2010 19:15:33 +0200 (CEST) Subject: [Python-checkins] r81839 - in python/branches/release31-maint: Misc/maintainers.rst Message-ID: <20100608171533.B021FEEA33@mail.python.org> Author: alexander.belopolsky Date: Tue Jun 8 19:15:33 2010 New Revision: 81839 Log: Merged revisions 81838 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81838 | alexander.belopolsky | 2010-06-08 13:06:48 -0400 (Tue, 08 Jun 2010) | 1 line Added myself as a maintainer of time and datetime modules. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Misc/maintainers.rst Modified: python/branches/release31-maint/Misc/maintainers.rst ============================================================================== --- python/branches/release31-maint/Misc/maintainers.rst (original) +++ python/branches/release31-maint/Misc/maintainers.rst Tue Jun 8 19:15:33 2010 @@ -80,7 +80,7 @@ csv ctypes theller curses andrew.kuchling -datetime +datetime alexander.belopolsky dbm decimal facundobatista, rhettinger, mark.dickinson difflib tim_one @@ -207,7 +207,7 @@ test textwrap threading -time +time alexander.belopolsky timeit tkinter gpolo token georg.brandl From python-checkins at python.org Tue Jun 8 20:59:20 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Tue, 8 Jun 2010 20:59:20 +0200 (CEST) Subject: [Python-checkins] r81840 - in python/branches/py3k: Doc/library/datetime.rst Message-ID: <20100608185920.7DA6AEE98B@mail.python.org> Author: alexander.belopolsky Date: Tue Jun 8 20:59:20 2010 New Revision: 81840 Log: Merged revisions 81489 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81489 | georg.brandl | 2010-05-23 17:29:29 -0400 (Sun, 23 May 2010) | 1 line #1436346: make it more obvious that timetuple[7] is yday. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/datetime.rst Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Tue Jun 8 20:59:20 2010 @@ -480,7 +480,9 @@ Return a :class:`time.struct_time` such as returned by :func:`time.localtime`. The hours, minutes and seconds are 0, and the DST flag is -1. ``d.timetuple()`` is equivalent to ``time.struct_time((d.year, d.month, d.day, 0, 0, 0, - d.weekday(), d.toordinal() - date(d.year, 1, 1).toordinal() + 1, -1))`` + d.weekday(), yday, -1))``, where ``yday = d.toordinal() - date(d.year, 1, + 1).toordinal() + 1`` is the day number within the current year starting with + ``1`` for January 1st. .. method:: date.toordinal() @@ -944,12 +946,13 @@ Return a :class:`time.struct_time` such as returned by :func:`time.localtime`. ``d.timetuple()`` is equivalent to ``time.struct_time((d.year, d.month, d.day, - d.hour, d.minute, d.second, d.weekday(), d.toordinal() - date(d.year, 1, - 1).toordinal() + 1, dst))`` The :attr:`tm_isdst` flag of the result is set - according to the :meth:`dst` method: :attr:`tzinfo` is ``None`` or :meth:`dst` - returns ``None``, :attr:`tm_isdst` is set to ``-1``; else if :meth:`dst` - returns a non-zero value, :attr:`tm_isdst` is set to ``1``; else ``tm_isdst`` is - set to ``0``. + d.hour, d.minute, d.second, d.weekday(), yday, dst))``, where ``yday = + d.toordinal() - date(d.year, 1, 1).toordinal() + 1`` is the day number within + the current year starting with ``1`` for January 1st. The :attr:`tm_isdst` flag + of the result is set according to the :meth:`dst` method: :attr:`tzinfo` is + ``None`` or :meth:`dst`` returns ``None``, :attr:`tm_isdst` is set to ``-1``; + else if :meth:`dst` returns a non-zero value, :attr:`tm_isdst` is set to ``1``; + else ``tm_isdst`` is set to ``0``. .. method:: datetime.utctimetuple() From python-checkins at python.org Tue Jun 8 22:41:16 2010 From: python-checkins at python.org (tarek.ziade) Date: Tue, 08 Jun 2010 22:41:16 +0200 Subject: [Python-checkins] distutils2: added an __all__ attribute to versions, and made some members private Message-ID: tarek.ziade pushed 0e9228d9bbda to distutils2: http://hg.python.org/distutils2/rev/0e9228d9bbda changeset: 198:0e9228d9bbda tag: tip user: Tarek Ziade date: Tue Jun 08 22:41:06 2010 +0200 summary: added an __all__ attribute to versions, and made some members private files: src/distutils2/version.py diff --git a/src/distutils2/version.py b/src/distutils2/version.py --- a/src/distutils2/version.py +++ b/src/distutils2/version.py @@ -3,6 +3,10 @@ from distutils2.errors import IrrationalVersionError, HugeMajorVersionNumError +__all__ = ['NormalizedVersion', 'suggest_normalized_version', + 'VersionPredicate', 'is_valid_version', 'is_valid_versions', + 'is_valid_predicate'] + # A marker used in the second and third parts of the `parts` tuple, for # versions that don't have those segments, to sort properly. An example # of versions in sort order ('highest' last): @@ -18,9 +22,9 @@ # | # 'dev' < 'f' ----------------------------------------------/ # Other letters would do, but 'f' for 'final' is kind of nice. -FINAL_MARKER = ('f',) +_FINAL_MARKER = ('f',) -VERSION_RE = re.compile(r''' +_VERSION_RE = re.compile(r''' ^ (?P\d+\.\d+) # minimum 'N.N' (?P(?:\.\d+)*) # any number of extra '.N' segments @@ -70,13 +74,13 @@ self._parse(s, error_on_huge_major_num) @classmethod - def from_parts(cls, version, prerelease=FINAL_MARKER, - devpost=FINAL_MARKER): + def from_parts(cls, version, prerelease=_FINAL_MARKER, + devpost=_FINAL_MARKER): return cls(cls.parts_to_str((version, prerelease, devpost))) def _parse(self, s, error_on_huge_major_num=True): """Parses a string version into parts.""" - match = VERSION_RE.search(s) + match = _VERSION_RE.search(s) if not match: raise IrrationalVersionError(s) @@ -98,7 +102,7 @@ pad_zeros_length=1) parts.append(tuple(block)) else: - parts.append(FINAL_MARKER) + parts.append(_FINAL_MARKER) # postdev if groups.get('postdev'): @@ -106,14 +110,14 @@ dev = groups.get('dev') postdev = [] if post is not None: - postdev.extend([FINAL_MARKER[0], 'post', int(post)]) + postdev.extend([_FINAL_MARKER[0], 'post', int(post)]) if dev is None: - postdev.append(FINAL_MARKER[0]) + postdev.append(_FINAL_MARKER[0]) if dev is not None: postdev.extend(['dev', int(dev)]) parts.append(tuple(postdev)) else: - parts.append(FINAL_MARKER) + parts.append(_FINAL_MARKER) self.parts = tuple(parts) if error_on_huge_major_num and self.parts[0][0] > 1980: raise HugeMajorVersionNumError("huge major version number, %r, " @@ -154,10 +158,10 @@ # XXX This doesn't check for invalid tuples main, prerel, postdev = parts s = '.'.join(str(v) for v in main) - if prerel is not FINAL_MARKER: + if prerel is not _FINAL_MARKER: s += prerel[0] s += '.'.join(str(v) for v in prerel[1:]) - if postdev and postdev is not FINAL_MARKER: + if postdev and postdev is not _FINAL_MARKER: if postdev[0] == 'f': postdev = postdev[1:] i = 0 @@ -364,7 +368,7 @@ return False return True -class Versions(VersionPredicate): +class _Versions(VersionPredicate): def __init__(self, predicate): predicate = predicate.strip() match = _PLAIN_VERSIONS.match(predicate) @@ -375,7 +379,7 @@ self.predicates = [_split_predicate(pred.strip()) for pred in predicates.split(',')] -class Version(VersionPredicate): +class _Version(VersionPredicate): def __init__(self, predicate): predicate = predicate.strip() match = _PLAIN_VERSIONS.match(predicate) @@ -394,7 +398,7 @@ def is_valid_versions(predicate): try: - Versions(predicate) + _Versions(predicate) except (ValueError, IrrationalVersionError): return False else: @@ -402,7 +406,7 @@ def is_valid_version(predicate): try: - Version(predicate) + _Version(predicate) except (ValueError, IrrationalVersionError): return False else: -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Tue Jun 8 22:46:00 2010 From: python-checkins at python.org (victor.stinner) Date: Tue, 8 Jun 2010 22:46:00 +0200 (CEST) Subject: [Python-checkins] r81841 - python/branches/py3k/Python/sysmodule.c Message-ID: <20100608204600.30E90EEA44@mail.python.org> Author: victor.stinner Date: Tue Jun 8 22:46:00 2010 New Revision: 81841 Log: sys_pyfile_write() does nothing if file is NULL mywrite() falls back to the C file object if sys_pyfile_write() returns an error. This patch fixes a segfault is Py_FatalError() is called in an early stage of Python initialization. Modified: python/branches/py3k/Python/sysmodule.c Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Tue Jun 8 22:46:00 2010 @@ -1839,6 +1839,9 @@ PyObject *unicode = NULL, *writer = NULL, *args = NULL, *result = NULL; int err; + if (file == NULL) + return -1; + unicode = PyUnicode_FromString(text); if (unicode == NULL) goto error; From python-checkins at python.org Tue Jun 8 22:50:09 2010 From: python-checkins at python.org (victor.stinner) Date: Tue, 8 Jun 2010 22:50:09 +0200 (CEST) Subject: [Python-checkins] r81842 - in python/branches/release31-maint: Python/sysmodule.c Message-ID: <20100608205009.26350EEA15@mail.python.org> Author: victor.stinner Date: Tue Jun 8 22:50:09 2010 New Revision: 81842 Log: Merged revisions 81841 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81841 | victor.stinner | 2010-06-08 22:46:00 +0200 (mar., 08 juin 2010) | 6 lines sys_pyfile_write() does nothing if file is NULL mywrite() falls back to the C file object if sys_pyfile_write() returns an error. This patch fixes a segfault is Py_FatalError() is called in an early stage of Python initialization. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Python/sysmodule.c Modified: python/branches/release31-maint/Python/sysmodule.c ============================================================================== --- python/branches/release31-maint/Python/sysmodule.c (original) +++ python/branches/release31-maint/Python/sysmodule.c Tue Jun 8 22:50:09 2010 @@ -1670,6 +1670,9 @@ PyObject *unicode = NULL, *writer = NULL, *args = NULL, *result = NULL; int err; + if (file == NULL) + return -1; + unicode = PyUnicode_FromString(text); if (unicode == NULL) goto error; From python-checkins at python.org Tue Jun 8 22:57:52 2010 From: python-checkins at python.org (brian.curtin) Date: Tue, 8 Jun 2010 22:57:52 +0200 (CEST) Subject: [Python-checkins] r81843 - python/branches/py3k/PC/winreg.c Message-ID: <20100608205752.CE580F6C4@mail.python.org> Author: brian.curtin Date: Tue Jun 8 22:57:52 2010 New Revision: 81843 Log: Fix a compile warning missed during porting (wchar_t/char) and move a variable declaration outside of a loop. #2810 was when this first went in. Modified: python/branches/py3k/PC/winreg.c Modified: python/branches/py3k/PC/winreg.c ============================================================================== --- python/branches/py3k/PC/winreg.c (original) +++ python/branches/py3k/PC/winreg.c Tue Jun 8 22:57:52 2010 @@ -1129,6 +1129,7 @@ int index; long rc; wchar_t *retValueBuf; + wchar_t *tmpBuf; BYTE *retDataBuf; DWORD retValueSize, bufValueSize; DWORD retDataSize, bufDataSize; @@ -1161,7 +1162,6 @@ } while (1) { - wchar_t *tmp; Py_BEGIN_ALLOW_THREADS rc = RegEnumValueW(hKey, index, @@ -1177,13 +1177,13 @@ break; bufDataSize *= 2; - tmp = (char *)PyMem_Realloc(retDataBuf, bufDataSize); - if (tmp == NULL) { + tmpBuf = (wchar_t *)PyMem_Realloc(retDataBuf, bufDataSize); + if (tmpBuf == NULL) { PyErr_NoMemory(); retVal = NULL; goto fail; } - retDataBuf = tmp; + retDataBuf = tmpBuf; retDataSize = bufDataSize; retValueSize = bufValueSize; } From python-checkins at python.org Tue Jun 8 23:00:13 2010 From: python-checkins at python.org (victor.stinner) Date: Tue, 8 Jun 2010 23:00:13 +0200 (CEST) Subject: [Python-checkins] r81844 - python/branches/py3k/Python/pythonrun.c Message-ID: <20100608210013.9E4A7EE9AE@mail.python.org> Author: victor.stinner Date: Tue Jun 8 23:00:13 2010 New Revision: 81844 Log: Py_FatalError(): don't sys sys.last_xxx variables Call PyErr_PrintEx(0) instead of PyErr_Print() to avoid a crash if Py_FatalError() is called in an early stage of Python initialization (if PySys is not yet initialized). Modified: python/branches/py3k/Python/pythonrun.c Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Tue Jun 8 23:00:13 2010 @@ -2055,7 +2055,7 @@ fprintf(stderr, "Fatal Python error: %s\n", msg); fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { - PyErr_Print(); + PyErr_PrintEx(0); } #ifdef MS_WINDOWS { From python-checkins at python.org Tue Jun 8 23:00:35 2010 From: python-checkins at python.org (brian.curtin) Date: Tue, 8 Jun 2010 23:00:35 +0200 (CEST) Subject: [Python-checkins] r81845 - in python/branches/release31-maint: PC/winreg.c Message-ID: <20100608210035.352FBEE9BC@mail.python.org> Author: brian.curtin Date: Tue Jun 8 23:00:35 2010 New Revision: 81845 Log: Merged revisions 81843 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81843 | brian.curtin | 2010-06-08 15:57:52 -0500 (Tue, 08 Jun 2010) | 3 lines Fix a compile warning missed during porting (wchar_t/char) and move a variable declaration outside of a loop. #2810 was when this first went in. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/PC/winreg.c Modified: python/branches/release31-maint/PC/winreg.c ============================================================================== --- python/branches/release31-maint/PC/winreg.c (original) +++ python/branches/release31-maint/PC/winreg.c Tue Jun 8 23:00:35 2010 @@ -1036,6 +1036,7 @@ int index; long rc; wchar_t *retValueBuf; + wchar_t *tmpBuf; BYTE *retDataBuf; DWORD retValueSize, bufValueSize; DWORD retDataSize, bufDataSize; @@ -1068,7 +1069,6 @@ } while (1) { - wchar_t *tmp; Py_BEGIN_ALLOW_THREADS rc = RegEnumValueW(hKey, index, @@ -1084,13 +1084,13 @@ break; bufDataSize *= 2; - tmp = (char *)PyMem_Realloc(retDataBuf, bufDataSize); - if (tmp == NULL) { + tmpBuf = (wchar_t *)PyMem_Realloc(retDataBuf, bufDataSize); + if (tmpBuf == NULL) { PyErr_NoMemory(); retVal = NULL; goto fail; } - retDataBuf = tmp; + retDataBuf = tmpBuf; retDataSize = bufDataSize; retValueSize = bufValueSize; } From python-checkins at python.org Tue Jun 8 23:05:20 2010 From: python-checkins at python.org (victor.stinner) Date: Tue, 8 Jun 2010 23:05:20 +0200 (CEST) Subject: [Python-checkins] r81846 - in python/branches/release31-maint: Python/pythonrun.c Message-ID: <20100608210520.BA7C8EEA5E@mail.python.org> Author: victor.stinner Date: Tue Jun 8 23:05:20 2010 New Revision: 81846 Log: Merged revisions 81844 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81844 | victor.stinner | 2010-06-08 23:00:13 +0200 (mar., 08 juin 2010) | 6 lines Py_FatalError(): don't sys sys.last_xxx variables Call PyErr_PrintEx(0) instead of PyErr_Print() to avoid a crash if Py_FatalError() is called in an early stage of Python initialization (if PySys is not yet initialized). ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Python/pythonrun.c Modified: python/branches/release31-maint/Python/pythonrun.c ============================================================================== --- python/branches/release31-maint/Python/pythonrun.c (original) +++ python/branches/release31-maint/Python/pythonrun.c Tue Jun 8 23:05:20 2010 @@ -2024,7 +2024,7 @@ fprintf(stderr, "Fatal Python error: %s\n", msg); fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { - PyErr_Print(); + PyErr_PrintEx(0); } #ifdef MS_WINDOWS { From python-checkins at python.org Tue Jun 8 23:15:06 2010 From: python-checkins at python.org (brian.curtin) Date: Tue, 8 Jun 2010 23:15:06 +0200 (CEST) Subject: [Python-checkins] r81847 - python/trunk/PC/_winreg.c Message-ID: <20100608211506.CD32CEEA61@mail.python.org> Author: brian.curtin Date: Tue Jun 8 23:15:06 2010 New Revision: 81847 Log: Move a variable declration outside of a loop to match what was done in r81843 for py3k. Modified: python/trunk/PC/_winreg.c Modified: python/trunk/PC/_winreg.c ============================================================================== --- python/trunk/PC/_winreg.c (original) +++ python/trunk/PC/_winreg.c Tue Jun 8 23:15:06 2010 @@ -1187,6 +1187,7 @@ long rc; char *retValueBuf; char *retDataBuf; + char *tmpBuf; DWORD retValueSize, bufValueSize; DWORD retDataSize, bufDataSize; DWORD typ; @@ -1218,7 +1219,6 @@ } while (1) { - char *tmp; Py_BEGIN_ALLOW_THREADS rc = RegEnumValue(hKey, index, @@ -1234,13 +1234,13 @@ break; bufDataSize *= 2; - tmp = (char *)PyMem_Realloc(retDataBuf, bufDataSize); - if (tmp == NULL) { + tmpBuf = (char *)PyMem_Realloc(retDataBuf, bufDataSize); + if (tmpBuf == NULL) { PyErr_NoMemory(); retVal = NULL; goto fail; } - retDataBuf = tmp; + retDataBuf = tmpBuf; retDataSize = bufDataSize; retValueSize = bufValueSize; } From python-checkins at python.org Tue Jun 8 23:17:16 2010 From: python-checkins at python.org (brian.curtin) Date: Tue, 8 Jun 2010 23:17:16 +0200 (CEST) Subject: [Python-checkins] r81848 - in python/branches/release26-maint: PC/_winreg.c Message-ID: <20100608211716.EBEF2ED0F@mail.python.org> Author: brian.curtin Date: Tue Jun 8 23:17:16 2010 New Revision: 81848 Log: Merged revisions 81847 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81847 | brian.curtin | 2010-06-08 16:15:06 -0500 (Tue, 08 Jun 2010) | 3 lines Move a variable declration outside of a loop to match what was done in r81843 for py3k. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/PC/_winreg.c Modified: python/branches/release26-maint/PC/_winreg.c ============================================================================== --- python/branches/release26-maint/PC/_winreg.c (original) +++ python/branches/release26-maint/PC/_winreg.c Tue Jun 8 23:17:16 2010 @@ -1105,6 +1105,7 @@ long rc; char *retValueBuf; char *retDataBuf; + char *tmpBuf; DWORD retValueSize, bufValueSize; DWORD retDataSize, bufDataSize; DWORD typ; @@ -1136,7 +1137,6 @@ } while (1) { - char *tmp; Py_BEGIN_ALLOW_THREADS rc = RegEnumValue(hKey, index, @@ -1152,13 +1152,13 @@ break; bufDataSize *= 2; - tmp = (char *)PyMem_Realloc(retDataBuf, bufDataSize); - if (tmp == NULL) { + tmpBuf = (char *)PyMem_Realloc(retDataBuf, bufDataSize); + if (tmpBuf == NULL) { PyErr_NoMemory(); retVal = NULL; goto fail; } - retDataBuf = tmp; + retDataBuf = tmpBuf; retDataSize = bufDataSize; retValueSize = bufValueSize; } From python-checkins at python.org Tue Jun 8 23:45:51 2010 From: python-checkins at python.org (victor.stinner) Date: Tue, 8 Jun 2010 23:45:51 +0200 (CEST) Subject: [Python-checkins] r81849 - python/branches/py3k/Python/getargs.c Message-ID: <20100608214551.444A7EEA85@mail.python.org> Author: victor.stinner Date: Tue Jun 8 23:45:51 2010 New Revision: 81849 Log: PyArg_Parse*("Z#") raises an error for unknown type instead of ignoring the error and leave the pointer to the string and the size unchanged (not initialized). Fix also the type in the error message of "Z", "Z#" and "Y" formats. Modified: python/branches/py3k/Python/getargs.c Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Tue Jun 8 23:45:51 2010 @@ -1051,6 +1051,8 @@ *p = PyUnicode_AS_UNICODE(arg); STORE_SIZE(PyUnicode_GET_SIZE(arg)); } + else + return converterr("str or None", arg, msgbuf, bufsize); format++; } else { Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); @@ -1060,8 +1062,7 @@ else if (PyUnicode_Check(arg)) *p = PyUnicode_AS_UNICODE(arg); else - return converterr("string or None", - arg, msgbuf, bufsize); + return converterr("str or None", arg, msgbuf, bufsize); } break; } @@ -1258,7 +1259,7 @@ if (PyByteArray_Check(arg)) *p = arg; else - return converterr("buffer", arg, msgbuf, bufsize); + return converterr("bytearray", arg, msgbuf, bufsize); break; } From python-checkins at python.org Tue Jun 8 23:46:32 2010 From: python-checkins at python.org (victor.stinner) Date: Tue, 8 Jun 2010 23:46:32 +0200 (CEST) Subject: [Python-checkins] r81850 - in python/branches/release31-maint: Python/getargs.c Message-ID: <20100608214632.52824EEB05@mail.python.org> Author: victor.stinner Date: Tue Jun 8 23:46:32 2010 New Revision: 81850 Log: Merged revisions 81849 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81849 | victor.stinner | 2010-06-08 23:45:51 +0200 (mar., 08 juin 2010) | 7 lines PyArg_Parse*("Z#") raises an error for unknown type instead of ignoring the error and leave the pointer to the string and the size unchanged (not initialized). Fix also the type in the error message of "Z", "Z#" and "Y" formats. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Python/getargs.c Modified: python/branches/release31-maint/Python/getargs.c ============================================================================== --- python/branches/release31-maint/Python/getargs.c (original) +++ python/branches/release31-maint/Python/getargs.c Tue Jun 8 23:46:32 2010 @@ -1048,6 +1048,8 @@ *p = PyUnicode_AS_UNICODE(arg); STORE_SIZE(PyUnicode_GET_SIZE(arg)); } + else + return converterr("str or None", arg, msgbuf, bufsize); format++; } else { Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); @@ -1057,8 +1059,7 @@ else if (PyUnicode_Check(arg)) *p = PyUnicode_AS_UNICODE(arg); else - return converterr("string or None", - arg, msgbuf, bufsize); + return converterr("str or None", arg, msgbuf, bufsize); } break; } @@ -1253,7 +1254,7 @@ if (PyByteArray_Check(arg)) *p = arg; else - return converterr("buffer", arg, msgbuf, bufsize); + return converterr("bytearray", arg, msgbuf, bufsize); break; } From python-checkins at python.org Wed Jun 9 00:27:07 2010 From: python-checkins at python.org (brian.curtin) Date: Wed, 9 Jun 2010 00:27:07 +0200 (CEST) Subject: [Python-checkins] r81851 - python/branches/py3k/Doc/c-api/buffer.rst Message-ID: <20100608222707.6E3EEEEB14@mail.python.org> Author: brian.curtin Date: Wed Jun 9 00:27:07 2010 New Revision: 81851 Log: Fix #8946. Extra PyObject* parameter documented which doesn't exist. Modified: 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 Wed Jun 9 00:27:07 2010 @@ -249,10 +249,10 @@ +------------------------------+---------------------------------------------------+ -.. cfunction:: void PyBuffer_Release(PyObject *obj, Py_buffer *view) +.. cfunction:: void PyBuffer_Release(Py_buffer *view) - Release the buffer *view* over *obj*. This should be called when the buffer - is no longer being used as it may free memory from it. + Release the buffer *view*. This should be called when the buffer is no + longer being used as it may free memory from it. .. cfunction:: Py_ssize_t PyBuffer_SizeFromFormat(const char *) From python-checkins at python.org Wed Jun 9 00:30:34 2010 From: python-checkins at python.org (brian.curtin) Date: Wed, 9 Jun 2010 00:30:34 +0200 (CEST) Subject: [Python-checkins] r81852 - in python/branches/release31-maint: Doc/c-api/buffer.rst Message-ID: <20100608223034.EDD7AEEB17@mail.python.org> Author: brian.curtin Date: Wed Jun 9 00:30:34 2010 New Revision: 81852 Log: Merged revisions 81851 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81851 | brian.curtin | 2010-06-08 17:27:07 -0500 (Tue, 08 Jun 2010) | 2 lines Fix #8946. Extra PyObject* parameter documented which doesn't exist. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/c-api/buffer.rst Modified: python/branches/release31-maint/Doc/c-api/buffer.rst ============================================================================== --- python/branches/release31-maint/Doc/c-api/buffer.rst (original) +++ python/branches/release31-maint/Doc/c-api/buffer.rst Wed Jun 9 00:30:34 2010 @@ -249,10 +249,10 @@ +------------------------------+---------------------------------------------------+ -.. cfunction:: void PyBuffer_Release(PyObject *obj, Py_buffer *view) +.. cfunction:: void PyBuffer_Release(Py_buffer *view) - Release the buffer *view* over *obj*. This should be called when the buffer - is no longer being used as it may free memory from it. + Release the buffer *view*. This should be called when the buffer is no + longer being used as it may free memory from it. .. cfunction:: Py_ssize_t PyBuffer_SizeFromFormat(const char *) From python-checkins at python.org Wed Jun 9 00:44:52 2010 From: python-checkins at python.org (michael.foord) Date: Wed, 9 Jun 2010 00:44:52 +0200 (CEST) Subject: [Python-checkins] r81853 - in python/trunk/Lib/unittest: case.py suite.py test/test_runner.py test/test_setups.py Message-ID: <20100608224452.928AAEEB06@mail.python.org> Author: michael.foord Date: Wed Jun 9 00:44:52 2010 New Revision: 81853 Log: Issue 8948. cleanup functions are not run by unittest.TestCase.debug(), plus class and module teardowns are not run by unittest.TestSuite.debug(). Modified: python/trunk/Lib/unittest/case.py python/trunk/Lib/unittest/suite.py python/trunk/Lib/unittest/test/test_runner.py python/trunk/Lib/unittest/test/test_setups.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Wed Jun 9 00:44:52 2010 @@ -380,6 +380,9 @@ self.setUp() getattr(self, self._testMethodName)() self.tearDown() + while self._cleanups: + function, args, kwargs = self._cleanups.pop(-1) + function(*args, **kwargs) def skipTest(self, reason): """Skip this test.""" Modified: python/trunk/Lib/unittest/suite.py ============================================================================== --- python/trunk/Lib/unittest/suite.py (original) +++ python/trunk/Lib/unittest/suite.py Wed Jun 9 00:44:52 2010 @@ -87,9 +87,16 @@ self._handleModuleTearDown(result) return result + def debug(self): + """Run the tests without collecting errors in a TestResult""" + debug = _DebugResult() + self._wrapped_run(debug, True) + self._tearDownPreviousClass(None, debug) + self._handleModuleTearDown(debug) + ################################ # private methods - def _wrapped_run(self, result): + def _wrapped_run(self, result, debug=False): for test in self: if result.shouldStop: break @@ -106,8 +113,10 @@ if hasattr(test, '_wrapped_run'): test._wrapped_run(result) - else: + elif not debug: test(result) + else: + test.debug() def _handleClassSetUp(self, test, result): previousClass = getattr(result, '_previousTestClass', None) @@ -131,6 +140,8 @@ try: setUpClass() except Exception as e: + if isinstance(result, _DebugResult): + raise currentClass._classSetupFailed = True className = util.strclass(currentClass) errorName = 'setUpClass (%s)' % className @@ -163,6 +174,8 @@ try: setUpModule() except Exception, e: + if isinstance(result, _DebugResult): + raise result._moduleSetUpFailed = True errorName = 'setUpModule (%s)' % currentModule self._addClassOrModuleLevelException(result, e, errorName) @@ -192,6 +205,8 @@ try: tearDownModule() except Exception as e: + if isinstance(result, _DebugResult): + raise errorName = 'tearDownModule (%s)' % previousModule self._addClassOrModuleLevelException(result, e, errorName) @@ -212,6 +227,8 @@ try: tearDownClass() except Exception, e: + if isinstance(result, _DebugResult): + raise className = util.strclass(previousClass) errorName = 'tearDownClass (%s)' % className self._addClassOrModuleLevelException(result, e, errorName) @@ -262,3 +279,10 @@ except TypeError: return True return False + + +class _DebugResult(object): + "Used by the TestSuite to hold previous class when running in debug." + _previousTestClass = None + _moduleSetUpFailed = False + shouldStop = False Modified: python/trunk/Lib/unittest/test/test_runner.py ============================================================================== --- python/trunk/Lib/unittest/test/test_runner.py (original) +++ python/trunk/Lib/unittest/test/test_runner.py Wed Jun 9 00:44:52 2010 @@ -111,6 +111,31 @@ test.run(result) self.assertEqual(ordering, ['setUp', 'cleanup1']) + def testTestCaseDebugExecutesCleanups(self): + ordering = [] + + class TestableTest(unittest.TestCase): + def setUp(self): + ordering.append('setUp') + self.addCleanup(cleanup1) + + def testNothing(self): + ordering.append('test') + + def tearDown(self): + ordering.append('tearDown') + + test = TestableTest('testNothing') + + def cleanup1(): + ordering.append('cleanup1') + test.addCleanup(cleanup2) + def cleanup2(): + ordering.append('cleanup2') + + test.debug() + self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2']) + class Test_TextTestRunner(unittest.TestCase): """Tests for TextTestRunner.""" Modified: python/trunk/Lib/unittest/test/test_setups.py ============================================================================== --- python/trunk/Lib/unittest/test/test_setups.py (original) +++ python/trunk/Lib/unittest/test/test_setups.py Wed Jun 9 00:44:52 2010 @@ -439,6 +439,68 @@ skipped = result.skipped[0][0] self.assertEqual(str(skipped), 'setUpModule (Module)') + def test_suite_debug_executes_setups_and_teardowns(self): + ordering = [] + + class Module(object): + @staticmethod + def setUpModule(): + ordering.append('setUpModule') + @staticmethod + def tearDownModule(): + ordering.append('tearDownModule') + + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + @classmethod + def tearDownClass(cls): + ordering.append('tearDownClass') + def test_something(self): + ordering.append('test_something') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + suite.debug() + expectedOrder = ['setUpModule', 'setUpClass', 'test_something', 'tearDownClass', 'tearDownModule'] + self.assertEqual(ordering, expectedOrder) + + def test_suite_debug_propagates_exceptions(self): + class Module(object): + @staticmethod + def setUpModule(): + if phase == 0: + raise Exception('setUpModule') + @staticmethod + def tearDownModule(): + if phase == 1: + raise Exception('tearDownModule') + + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + if phase == 2: + raise Exception('setUpClass') + @classmethod + def tearDownClass(cls): + if phase == 3: + raise Exception('tearDownClass') + def test_something(self): + if phase == 4: + raise Exception('test_something') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + + messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something') + for phase, msg in enumerate(messages): + with self.assertRaisesRegexp(Exception, msg): + suite.debug() if __name__ == '__main__': unittest.main() From python-checkins at python.org Wed Jun 9 00:54:20 2010 From: python-checkins at python.org (victor.stinner) Date: Wed, 9 Jun 2010 00:54:20 +0200 (CEST) Subject: [Python-checkins] r81854 - in python/branches/py3k: Doc/c-api/arg.rst Doc/whatsnew/3.2.rst Lib/test/test_codecs.py Misc/NEWS Modules/_codecsmodule.c Python/getargs.c Message-ID: <20100608225420.2B756EEB66@mail.python.org> Author: victor.stinner Date: Wed Jun 9 00:54:19 2010 New Revision: 81854 Log: Issue #8838, #8339: Remove codecs.charbuffer_encode() and "t#" parsing format Remove last references to the "char buffer" of the buffer protocol from Python3. Modified: python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k/Doc/whatsnew/3.2.rst python/branches/py3k/Lib/test/test_codecs.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_codecsmodule.c python/branches/py3k/Python/getargs.c Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Wed Jun 9 00:54:19 2010 @@ -150,13 +150,6 @@ any conversion. Raises :exc:`TypeError` if the object is not a Unicode object. The C variable may also be declared as :ctype:`PyObject\*`. -``t#`` (:class:`bytes`, :class:`bytearray` or read-only character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-only buffer - interface. The :ctype:`char\*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. - ``w`` (:class:`bytearray` or read-write character buffer) [char \*] Similar to ``s``, but accepts any object which implements the read-write buffer interface. The caller must determine the length of the buffer by other means, Modified: python/branches/py3k/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.2.rst Wed Jun 9 00:54:19 2010 @@ -173,4 +173,7 @@ * bytearray objects cannot be used anymore as filenames: convert them to bytes +* "t#" format of PyArg_Parse*() functions has been removed: use "s#" or "s*" + instead + * Stub Modified: python/branches/py3k/Lib/test/test_codecs.py ============================================================================== --- python/branches/py3k/Lib/test/test_codecs.py (original) +++ python/branches/py3k/Lib/test/test_codecs.py Wed Jun 9 00:54:19 2010 @@ -72,7 +72,6 @@ # check that there's nothing left in the buffers self.assertEqual(r.read(), "") self.assertEqual(r.bytebuffer, b"") - self.assertEqual(r.charbuffer, "") # do the check again, this time using a incremental decoder d = codecs.getincrementaldecoder(self.encoding)() @@ -628,18 +627,6 @@ self.assertRaises(TypeError, codecs.readbuffer_encode) self.assertRaises(TypeError, codecs.readbuffer_encode, 42) -class CharBufferTest(unittest.TestCase): - - def test_string(self): - self.assertEqual(codecs.charbuffer_encode(b"spam"), (b"spam", 4)) - - def test_empty(self): - self.assertEqual(codecs.charbuffer_encode(b""), (b"", 0)) - - def test_bad_args(self): - self.assertRaises(TypeError, codecs.charbuffer_encode) - self.assertRaises(TypeError, codecs.charbuffer_encode, 42) - class UTF8SigTest(ReadTest): encoding = "utf-8-sig" @@ -1663,7 +1650,6 @@ UTF7Test, UTF16ExTest, ReadBufferTest, - CharBufferTest, RecodingTest, PunycodeTest, UnicodeInternalTest, Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Jun 9 00:54:19 2010 @@ -12,6 +12,13 @@ Core and Builtins ----------------- +- Issue #8838: Remove codecs.charbuffer_encode() function. The buffer protocol + doesn't support "char buffer" anymore in Python3. + +- Issue #8339: Remove "t#" format of PyArg_Parse*() functions, use "s#" or "s*" + instead. codecs.charbuffer_encode() now accepts modifiable buffer objects + like bytearray. + - Issue #8837: Remove "O?" format of PyArg_Parse*() functions. The format is no used anymore and it was never documented. Modified: python/branches/py3k/Modules/_codecsmodule.c ============================================================================== --- python/branches/py3k/Modules/_codecsmodule.c (original) +++ python/branches/py3k/Modules/_codecsmodule.c Wed Jun 9 00:54:19 2010 @@ -639,21 +639,6 @@ } static PyObject * -charbuffer_encode(PyObject *self, - PyObject *args) -{ - const char *data; - Py_ssize_t size; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "t#|z:charbuffer_encode", - &data, &size, &errors)) - return NULL; - - return codec_tuple(PyBytes_FromStringAndSize(data, size), size); -} - -static PyObject * unicode_internal_encode(PyObject *self, PyObject *args) { @@ -1116,7 +1101,6 @@ {"charmap_decode", charmap_decode, METH_VARARGS}, {"charmap_build", charmap_build, METH_VARARGS}, {"readbuffer_encode", readbuffer_encode, METH_VARARGS}, - {"charbuffer_encode", charbuffer_encode, METH_VARARGS}, #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) {"mbcs_encode", mbcs_encode, METH_VARARGS}, {"mbcs_decode", mbcs_decode, METH_VARARGS}, Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Wed Jun 9 00:54:19 2010 @@ -864,7 +864,7 @@ break; } - /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w', 't' codes all + /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all need to be cleaned up! */ case 's': {/* text string */ @@ -1362,45 +1362,6 @@ break; } - /*TEO: This can be eliminated --- here only for backward - compatibility */ - case 't': { /* 8-bit character buffer, read-only access */ - char **p = va_arg(*p_va, char **); - PyBufferProcs *pb = arg->ob_type->tp_as_buffer; - Py_ssize_t count; - Py_buffer view; - - if (*format++ != '#') - return converterr( - "invalid use of 't' format character", - arg, msgbuf, bufsize); - if (pb == NULL || pb->bf_getbuffer == NULL) - return converterr( - "bytes or read-only character buffer", - arg, msgbuf, bufsize); - - if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0) - return converterr("string or single-segment read-only buffer", - arg, msgbuf, bufsize); - - count = view.len; - *p = view.buf; - if (pb->bf_releasebuffer) - return converterr( - "string or pinned buffer", - arg, msgbuf, bufsize); - - PyBuffer_Release(&view); - - if (count < 0) - return converterr("(unspecified)", arg, msgbuf, bufsize); - { - FETCH_SIZE; - STORE_SIZE(count); - } - break; - } - default: return converterr("impossible", arg, msgbuf, bufsize); From python-checkins at python.org Wed Jun 9 00:54:54 2010 From: python-checkins at python.org (victor.stinner) Date: Wed, 9 Jun 2010 00:54:54 +0200 (CEST) Subject: [Python-checkins] r81855 - python/branches/release31-maint Message-ID: <20100608225454.81F6EEEB06@mail.python.org> Author: victor.stinner Date: Wed Jun 9 00:54:54 2010 New Revision: 81855 Log: Blocked revisions 81854 via svnmerge ........ r81854 | victor.stinner | 2010-06-09 00:54:19 +0200 (mer., 09 juin 2010) | 5 lines Issue #8838, #8339: Remove codecs.charbuffer_encode() and "t#" parsing format Remove last references to the "char buffer" of the buffer protocol from Python3. ........ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Wed Jun 9 01:26:30 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 9 Jun 2010 01:26:30 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81844): sum=0 Message-ID: <20100608232630.769E817758@ns6635.ovh.net> py3k results for svn r81844 (hg cset 82076fd6b505) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogS3fSvc', '-x'] From python-checkins at python.org Wed Jun 9 10:13:43 2010 From: python-checkins at python.org (kristjan.jonsson) Date: Wed, 9 Jun 2010 10:13:43 +0200 (CEST) Subject: [Python-checkins] r81856 - in python/branches/py3k: Doc/library/xml.dom.minidom.rst Lib/test/test_minidom.py Lib/xml/dom/minidom.py Message-ID: <20100609081343.31899EEBD4@mail.python.org> Author: kristjan.jonsson Date: Wed Jun 9 10:13:42 2010 New Revision: 81856 Log: http://bugs.python.org/issue8832 Issue minidom.unlink with a context manager Modified: python/branches/py3k/Doc/library/xml.dom.minidom.rst python/branches/py3k/Lib/test/test_minidom.py python/branches/py3k/Lib/xml/dom/minidom.py Modified: python/branches/py3k/Doc/library/xml.dom.minidom.rst ============================================================================== --- python/branches/py3k/Doc/library/xml.dom.minidom.rst (original) +++ python/branches/py3k/Doc/library/xml.dom.minidom.rst Wed Jun 9 10:13:42 2010 @@ -114,6 +114,13 @@ to be called on the :class:`Document` object, but may be called on child nodes to discard children of that node. + You can avoid calling this method explicitly by using the :keyword:`with` + statement. The following code will automatically unlink *dom* when the + :keyword:`with` block is exited:: + + with xml.dom.minidom.parse(datasource) as dom: + ... # Work with dom. + .. method:: Node.writexml(writer, indent="", addindent="", newl="", encoding="") Modified: python/branches/py3k/Lib/test/test_minidom.py ============================================================================== --- python/branches/py3k/Lib/test/test_minidom.py (original) +++ python/branches/py3k/Lib/test/test_minidom.py Wed Jun 9 10:13:42 2010 @@ -228,7 +228,14 @@ def testUnlink(self): dom = parse(tstfile) + self.assertTrue(dom.childNodes) dom.unlink() + self.assertFalse(dom.childNodes) + + def testContext(self): + with parse(tstfile) as dom: + self.assertTrue(dom.childNodes) + self.assertFalse(dom.childNodes) def testElement(self): dom = Document() Modified: python/branches/py3k/Lib/xml/dom/minidom.py ============================================================================== --- python/branches/py3k/Lib/xml/dom/minidom.py (original) +++ python/branches/py3k/Lib/xml/dom/minidom.py Wed Jun 9 10:13:42 2010 @@ -268,6 +268,14 @@ self.previousSibling = None self.nextSibling = None + # A Node is its own context manager, to ensure that an unlink() call occurs. + # This is similar to how a file object works. + def __enter__(self): + return self + + def __exit__(self, et, ev, tb): + self.unlink() + defproperty(Node, "firstChild", doc="First child node, or None.") defproperty(Node, "lastChild", doc="Last child node, or None.") defproperty(Node, "localName", doc="Namespace-local name of this node.") From python-checkins at python.org Wed Jun 9 10:56:28 2010 From: python-checkins at python.org (stefan.krah) Date: Wed, 9 Jun 2010 10:56:28 +0200 (CEST) Subject: [Python-checkins] r81857 - python/branches/py3k/Lib/test/test_capi.py Message-ID: <20100609085628.2D9F6EEC03@mail.python.org> Author: stefan.krah Date: Wed Jun 9 10:56:28 2010 New Revision: 81857 Log: Issue #8932: Skip required when compiled --without-threads. Modified: python/branches/py3k/Lib/test/test_capi.py Modified: python/branches/py3k/Lib/test/test_capi.py ============================================================================== --- python/branches/py3k/Lib/test/test_capi.py (original) +++ python/branches/py3k/Lib/test/test_capi.py Wed Jun 9 10:56:28 2010 @@ -36,6 +36,7 @@ self.assertEqual(testfunction.attribute, "test") self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test") + @unittest.skipUnless(threading, 'Threading required for this test.') def test_no_FatalError_infinite_loop(self): p = subprocess.Popen([sys.executable, "-c", 'import _testcapi;' From python-checkins at python.org Wed Jun 9 11:04:59 2010 From: python-checkins at python.org (stefan.krah) Date: Wed, 9 Jun 2010 11:04:59 +0200 (CEST) Subject: [Python-checkins] r81858 - python/branches/release31-maint Message-ID: <20100609090459.17E0CEEADC@mail.python.org> Author: stefan.krah Date: Wed Jun 9 11:04:58 2010 New Revision: 81858 Log: Blocked revisions 81857 via svnmerge ........ r81857 | stefan.krah | 2010-06-09 10:56:28 +0200 (Wed, 09 Jun 2010) | 3 lines Issue #8932: Skip required when compiled --without-threads. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Wed Jun 9 14:29:56 2010 From: python-checkins at python.org (michael.foord) Date: Wed, 9 Jun 2010 14:29:56 +0200 (CEST) Subject: [Python-checkins] r81859 - python/trunk/Lib/unittest/case.py Message-ID: <20100609122956.6814DEEA85@mail.python.org> Author: michael.foord Date: Wed Jun 9 14:29:56 2010 New Revision: 81859 Log: Typo correction. Modified: python/trunk/Lib/unittest/case.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Wed Jun 9 14:29:56 2010 @@ -160,7 +160,7 @@ longMessage = False - # This attribute sets the maximum length of a diff in failure messsages + # This attribute sets the maximum length of a diff in failure messages # by assert methods using difflib. It is looked up as an instance attribute # so can be configured by individual tests if required. From python-checkins at python.org Wed Jun 9 18:24:00 2010 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 9 Jun 2010 18:24:00 +0200 (CEST) Subject: [Python-checkins] r81860 - in python/trunk: Modules/_codecsmodule.c Objects/bytearrayobject.c Objects/stringobject.c Message-ID: <20100609162400.E3AC8EEC48@mail.python.org> Author: antoine.pitrou Date: Wed Jun 9 18:24:00 2010 New Revision: 81860 Log: Issue #8930: fix some C code indentation Modified: python/trunk/Modules/_codecsmodule.c python/trunk/Objects/bytearrayobject.c python/trunk/Objects/stringobject.c Modified: python/trunk/Modules/_codecsmodule.c ============================================================================== --- python/trunk/Modules/_codecsmodule.c (original) +++ python/trunk/Modules/_codecsmodule.c Wed Jun 9 18:24:00 2010 @@ -176,28 +176,28 @@ escape_encode(PyObject *self, PyObject *args) { - PyObject *str; - const char *errors = NULL; - char *buf; - Py_ssize_t consumed, len; - - if (!PyArg_ParseTuple(args, "S|z:escape_encode", - &str, &errors)) - return NULL; - - consumed = PyString_GET_SIZE(str); - str = PyString_Repr(str, 0); - if (!str) - return NULL; - - /* The string will be quoted. Unquote, similar to unicode-escape. */ - buf = PyString_AS_STRING (str); - len = PyString_GET_SIZE (str); - memmove(buf, buf+1, len-2); - if (_PyString_Resize(&str, len-2) < 0) - return NULL; + PyObject *str; + const char *errors = NULL; + char *buf; + Py_ssize_t consumed, len; + + if (!PyArg_ParseTuple(args, "S|z:escape_encode", + &str, &errors)) + return NULL; + + consumed = PyString_GET_SIZE(str); + str = PyString_Repr(str, 0); + if (!str) + return NULL; - return codec_tuple(str, consumed); + /* The string will be quoted. Unquote, similar to unicode-escape. */ + buf = PyString_AS_STRING (str); + len = PyString_GET_SIZE (str); + memmove(buf, buf+1, len-2); + if (_PyString_Resize(&str, len-2) < 0) + return NULL; + + return codec_tuple(str, consumed); } #ifdef Py_USING_UNICODE @@ -233,7 +233,7 @@ utf_7_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -246,7 +246,7 @@ decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -256,7 +256,7 @@ utf_8_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -269,7 +269,7 @@ decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -279,7 +279,7 @@ utf_16_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -292,7 +292,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -302,7 +302,7 @@ utf_16_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -316,7 +316,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -326,7 +326,7 @@ utf_16_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -340,7 +340,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -358,7 +358,7 @@ utf_16_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -371,7 +371,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -383,7 +383,7 @@ utf_32_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -396,7 +396,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -406,7 +406,7 @@ utf_32_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -419,7 +419,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -429,7 +429,7 @@ utf_32_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -442,7 +442,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -460,7 +460,7 @@ utf_32_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -473,7 +473,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -485,7 +485,7 @@ unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; PyObject *unicode; @@ -493,68 +493,68 @@ &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * raw_unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; - PyObject *unicode; + PyObject *unicode; if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * latin_1_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "s*|z:latin_1_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * ascii_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "s*|z:ascii_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * charmap_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; PyObject *mapping = NULL; @@ -564,9 +564,9 @@ if (mapping == Py_None) mapping = NULL; - unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) @@ -575,7 +575,7 @@ mbcs_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -588,7 +588,7 @@ decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); Modified: python/trunk/Objects/bytearrayobject.c ============================================================================== --- python/trunk/Objects/bytearrayobject.c (original) +++ python/trunk/Objects/bytearrayobject.c Wed Jun 9 18:24:00 2010 @@ -106,24 +106,24 @@ static int bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) { - int ret; - void *ptr; - if (view == NULL) { - obj->ob_exports++; - return 0; - } - ptr = (void *) PyByteArray_AS_STRING(obj); - ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); - if (ret >= 0) { - obj->ob_exports++; - } - return ret; + int ret; + void *ptr; + if (view == NULL) { + obj->ob_exports++; + return 0; + } + ptr = (void *) PyByteArray_AS_STRING(obj); + ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); + if (ret >= 0) { + obj->ob_exports++; + } + return ret; } static void bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) { - obj->ob_exports--; + obj->ob_exports--; } static Py_ssize_t @@ -1718,43 +1718,43 @@ char from_c, char to_c, Py_ssize_t maxcount) { - char *self_s, *result_s, *start, *end, *next; - Py_ssize_t self_len; - PyByteArrayObject *result; + char *self_s, *result_s, *start, *end, *next; + Py_ssize_t self_len; + PyByteArrayObject *result; - /* The result string will be the same size */ - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); + /* The result string will be the same size */ + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); - next = findchar(self_s, self_len, from_c); + next = findchar(self_s, self_len, from_c); - if (next == NULL) { - /* No matches; return the original bytes */ - return return_self(self); - } + if (next == NULL) { + /* No matches; return the original bytes */ + return return_self(self); + } - /* Need to make a new bytes */ - result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - Py_MEMCPY(result_s, self_s, self_len); + /* Need to make a new bytes */ + result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); + if (result == NULL) + return NULL; + result_s = PyByteArray_AS_STRING(result); + Py_MEMCPY(result_s, self_s, self_len); - /* change everything in-place, starting with this one */ - start = result_s + (next-self_s); - *start = to_c; - start++; - end = result_s + self_len; - - while (--maxcount > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - *next = to_c; - start = next+1; - } + /* change everything in-place, starting with this one */ + start = result_s + (next-self_s); + *start = to_c; + start++; + end = result_s + self_len; - return result; + while (--maxcount > 0) { + next = findchar(start, end-start, from_c); + if (next == NULL) + break; + *next = to_c; + start = next+1; + } + + return result; } /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ Modified: python/trunk/Objects/stringobject.c ============================================================================== --- python/trunk/Objects/stringobject.c (original) +++ python/trunk/Objects/stringobject.c Wed Jun 9 18:24:00 2010 @@ -426,7 +426,7 @@ str = PyString_FromStringAndSize(s, size); if (str == NULL) - return NULL; + return NULL; v = PyString_AsDecodedString(str, encoding, errors); Py_DECREF(str); return v; @@ -439,23 +439,23 @@ PyObject *v; if (!PyString_Check(str)) { - PyErr_BadArgument(); - goto onError; + PyErr_BadArgument(); + goto onError; } if (encoding == NULL) { #ifdef Py_USING_UNICODE - encoding = PyUnicode_GetDefaultEncoding(); + encoding = PyUnicode_GetDefaultEncoding(); #else - PyErr_SetString(PyExc_ValueError, "no encoding specified"); - goto onError; + PyErr_SetString(PyExc_ValueError, "no encoding specified"); + goto onError; #endif } /* Decode via the codec registry */ v = PyCodec_Decode(str, encoding, errors); if (v == NULL) - goto onError; + goto onError; return v; @@ -471,24 +471,24 @@ v = PyString_AsDecodedObject(str, encoding, errors); if (v == NULL) - goto onError; + goto onError; #ifdef Py_USING_UNICODE /* Convert Unicode to a string using the default encoding */ if (PyUnicode_Check(v)) { - PyObject *temp = v; - v = PyUnicode_AsEncodedString(v, NULL, NULL); - Py_DECREF(temp); - if (v == NULL) - goto onError; + PyObject *temp = v; + v = PyUnicode_AsEncodedString(v, NULL, NULL); + Py_DECREF(temp); + if (v == NULL) + goto onError; } #endif if (!PyString_Check(v)) { - PyErr_Format(PyExc_TypeError, - "decoder did not return a string object (type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - goto onError; + PyErr_Format(PyExc_TypeError, + "decoder did not return a string object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + goto onError; } return v; @@ -506,7 +506,7 @@ str = PyString_FromStringAndSize(s, size); if (str == NULL) - return NULL; + return NULL; v = PyString_AsEncodedString(str, encoding, errors); Py_DECREF(str); return v; @@ -519,23 +519,23 @@ PyObject *v; if (!PyString_Check(str)) { - PyErr_BadArgument(); - goto onError; + PyErr_BadArgument(); + goto onError; } if (encoding == NULL) { #ifdef Py_USING_UNICODE - encoding = PyUnicode_GetDefaultEncoding(); + encoding = PyUnicode_GetDefaultEncoding(); #else - PyErr_SetString(PyExc_ValueError, "no encoding specified"); - goto onError; + PyErr_SetString(PyExc_ValueError, "no encoding specified"); + goto onError; #endif } /* Encode via the codec registry */ v = PyCodec_Encode(str, encoding, errors); if (v == NULL) - goto onError; + goto onError; return v; @@ -551,24 +551,24 @@ v = PyString_AsEncodedObject(str, encoding, errors); if (v == NULL) - goto onError; + goto onError; #ifdef Py_USING_UNICODE /* Convert Unicode to a string using the default encoding */ if (PyUnicode_Check(v)) { - PyObject *temp = v; - v = PyUnicode_AsEncodedString(v, NULL, NULL); - Py_DECREF(temp); - if (v == NULL) - goto onError; + PyObject *temp = v; + v = PyUnicode_AsEncodedString(v, NULL, NULL); + Py_DECREF(temp); + if (v == NULL) + goto onError; } #endif if (!PyString_Check(v)) { - PyErr_Format(PyExc_TypeError, - "encoder did not return a string object (type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - goto onError; + PyErr_Format(PyExc_TypeError, + "encoder did not return a string object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + goto onError; } return v; @@ -3002,17 +3002,17 @@ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode", kwlist, &encoding, &errors)) - return NULL; + return NULL; v = PyString_AsEncodedObject((PyObject *)self, encoding, errors); if (v == NULL) - goto onError; + goto onError; if (!PyString_Check(v) && !PyUnicode_Check(v)) { - PyErr_Format(PyExc_TypeError, - "encoder did not return a string/unicode object " - "(type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; + PyErr_Format(PyExc_TypeError, + "encoder did not return a string/unicode object " + "(type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; } return v; @@ -3041,17 +3041,17 @@ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) - return NULL; + return NULL; v = PyString_AsDecodedObject((PyObject *)self, encoding, errors); if (v == NULL) - goto onError; + goto onError; if (!PyString_Check(v) && !PyUnicode_Check(v)) { - PyErr_Format(PyExc_TypeError, - "decoder did not return a string/unicode object " - "(type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; + PyErr_Format(PyExc_TypeError, + "decoder did not return a string/unicode object " + "(type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; } return v; @@ -3076,7 +3076,7 @@ int tabsize = 8; if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize)) - return NULL; + return NULL; /* First pass: determine size of output string */ i = 0; /* chars up to and including most recent \n or \r */ @@ -3085,31 +3085,31 @@ for (p = PyString_AS_STRING(self); p < e; p++) if (*p == '\t') { if (tabsize > 0) { - incr = tabsize - (j % tabsize); - if (j > PY_SSIZE_T_MAX - incr) - goto overflow1; - j += incr; + incr = tabsize - (j % tabsize); + if (j > PY_SSIZE_T_MAX - incr) + goto overflow1; + j += incr; } } else { if (j > PY_SSIZE_T_MAX - 1) - goto overflow1; + goto overflow1; j++; if (*p == '\n' || *p == '\r') { - if (i > PY_SSIZE_T_MAX - j) - goto overflow1; - i += j; - j = 0; + if (i > PY_SSIZE_T_MAX - j) + goto overflow1; + i += j; + j = 0; } } if (i > PY_SSIZE_T_MAX - j) - goto overflow1; + goto overflow1; /* Second pass: create output string and fill it */ u = PyString_FromStringAndSize(NULL, i + j); if (!u) - return NULL; + return NULL; j = 0; /* same as in first pass */ q = PyString_AS_STRING(u); /* next output char */ @@ -3118,22 +3118,22 @@ for (p = PyString_AS_STRING(self); p < e; p++) if (*p == '\t') { if (tabsize > 0) { - i = tabsize - (j % tabsize); - j += i; - while (i--) { - if (q >= qe) - goto overflow2; - *q++ = ' '; - } + i = tabsize - (j % tabsize); + j += i; + while (i--) { + if (q >= qe) + goto overflow2; + *q++ = ' '; + } } } else { if (q >= qe) - goto overflow2; + goto overflow2; *q++ = *p; j++; if (*p == '\n' || *p == '\r') - j = 0; + j = 0; } return u; @@ -3151,26 +3151,26 @@ PyObject *u; if (left < 0) - left = 0; + left = 0; if (right < 0) - right = 0; + right = 0; if (left == 0 && right == 0 && PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + Py_INCREF(self); + return (PyObject *)self; } u = PyString_FromStringAndSize(NULL, left + PyString_GET_SIZE(self) + right); if (u) { - if (left) - memset(PyString_AS_STRING(u), fill, left); - Py_MEMCPY(PyString_AS_STRING(u) + left, - PyString_AS_STRING(self), - PyString_GET_SIZE(self)); - if (right) - memset(PyString_AS_STRING(u) + left + PyString_GET_SIZE(self), - fill, right); + if (left) + memset(PyString_AS_STRING(u), fill, left); + Py_MEMCPY(PyString_AS_STRING(u) + left, + PyString_AS_STRING(self), + PyString_GET_SIZE(self)); + if (right) + memset(PyString_AS_STRING(u) + left + PyString_GET_SIZE(self), + fill, right); } return u; @@ -3189,11 +3189,11 @@ char fillchar = ' '; if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar)) - return NULL; + return NULL; if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*) self; + Py_INCREF(self); + return (PyObject*) self; } return pad(self, 0, width - PyString_GET_SIZE(self), fillchar); @@ -3213,11 +3213,11 @@ char fillchar = ' '; if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar)) - return NULL; + return NULL; if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*) self; + Py_INCREF(self); + return (PyObject*) self; } return pad(self, width - PyString_GET_SIZE(self), 0, fillchar); @@ -3238,11 +3238,11 @@ char fillchar = ' '; if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar)) - return NULL; + return NULL; if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*) self; + Py_INCREF(self); + return (PyObject*) self; } marg = width - PyString_GET_SIZE(self); @@ -3266,18 +3266,18 @@ Py_ssize_t width; if (!PyArg_ParseTuple(args, "n:zfill", &width)) - return NULL; + return NULL; if (PyString_GET_SIZE(self) >= width) { - if (PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*) self; - } - else - return PyString_FromStringAndSize( - PyString_AS_STRING(self), - PyString_GET_SIZE(self) - ); + if (PyString_CheckExact(self)) { + Py_INCREF(self); + return (PyObject*) self; + } + else + return PyString_FromStringAndSize( + PyString_AS_STRING(self), + PyString_GET_SIZE(self) + ); } fill = width - PyString_GET_SIZE(self); @@ -3285,13 +3285,13 @@ s = pad(self, fill, 0, '0'); if (s == NULL) - return NULL; + return NULL; p = PyString_AS_STRING(s); if (p[fill] == '+' || p[fill] == '-') { - /* move sign to beginning of string */ - p[0] = p[fill]; - p[fill] = '0'; + /* move sign to beginning of string */ + p[0] = p[fill]; + p[fill] = '0'; } return (PyObject*) s; @@ -3307,22 +3307,22 @@ string_isspace(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1 && - isspace(*p)) - return PyBool_FromLong(1); + isspace(*p)) + return PyBool_FromLong(1); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); for (; p < e; p++) { - if (!isspace(*p)) - return PyBool_FromLong(0); + if (!isspace(*p)) + return PyBool_FromLong(0); } return PyBool_FromLong(1); } @@ -3338,22 +3338,22 @@ string_isalpha(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1 && - isalpha(*p)) - return PyBool_FromLong(1); + isalpha(*p)) + return PyBool_FromLong(1); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); for (; p < e; p++) { - if (!isalpha(*p)) - return PyBool_FromLong(0); + if (!isalpha(*p)) + return PyBool_FromLong(0); } return PyBool_FromLong(1); } @@ -3369,22 +3369,22 @@ string_isalnum(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1 && - isalnum(*p)) - return PyBool_FromLong(1); + isalnum(*p)) + return PyBool_FromLong(1); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); for (; p < e; p++) { - if (!isalnum(*p)) - return PyBool_FromLong(0); + if (!isalnum(*p)) + return PyBool_FromLong(0); } return PyBool_FromLong(1); } @@ -3400,22 +3400,22 @@ string_isdigit(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1 && - isdigit(*p)) - return PyBool_FromLong(1); + isdigit(*p)) + return PyBool_FromLong(1); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); for (; p < e; p++) { - if (!isdigit(*p)) - return PyBool_FromLong(0); + if (!isdigit(*p)) + return PyBool_FromLong(0); } return PyBool_FromLong(1); } @@ -3431,25 +3431,25 @@ string_islower(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; int cased; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1) - return PyBool_FromLong(islower(*p) != 0); + return PyBool_FromLong(islower(*p) != 0); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); cased = 0; for (; p < e; p++) { - if (isupper(*p)) - return PyBool_FromLong(0); - else if (!cased && islower(*p)) - cased = 1; + if (isupper(*p)) + return PyBool_FromLong(0); + else if (!cased && islower(*p)) + cased = 1; } return PyBool_FromLong(cased); } @@ -3465,25 +3465,25 @@ string_isupper(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; int cased; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1) - return PyBool_FromLong(isupper(*p) != 0); + return PyBool_FromLong(isupper(*p) != 0); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); cased = 0; for (; p < e; p++) { - if (islower(*p)) - return PyBool_FromLong(0); - else if (!cased && isupper(*p)) - cased = 1; + if (islower(*p)) + return PyBool_FromLong(0); + else if (!cased && isupper(*p)) + cased = 1; } return PyBool_FromLong(cased); } @@ -3501,38 +3501,38 @@ string_istitle(PyStringObject *self, PyObject *uncased) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; int cased, previous_is_cased; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1) - return PyBool_FromLong(isupper(*p) != 0); + return PyBool_FromLong(isupper(*p) != 0); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); cased = 0; previous_is_cased = 0; for (; p < e; p++) { - register const unsigned char ch = *p; + register const unsigned char ch = *p; - if (isupper(ch)) { - if (previous_is_cased) - return PyBool_FromLong(0); - previous_is_cased = 1; - cased = 1; - } - else if (islower(ch)) { - if (!previous_is_cased) - return PyBool_FromLong(0); - previous_is_cased = 1; - cased = 1; - } - else - previous_is_cased = 0; + if (isupper(ch)) { + if (previous_is_cased) + return PyBool_FromLong(0); + previous_is_cased = 1; + cased = 1; + } + else if (islower(ch)) { + if (!previous_is_cased) + return PyBool_FromLong(0); + previous_is_cased = 1; + cased = 1; + } + else + previous_is_cased = 0; } return PyBool_FromLong(cased); } @@ -3551,11 +3551,11 @@ int keepends = 0; if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) - return NULL; + return NULL; return stringlib_splitlines( - (PyObject*) self, PyString_AS_STRING(self), PyString_GET_SIZE(self), - keepends + (PyObject*) self, PyString_AS_STRING(self), PyString_GET_SIZE(self), + keepends ); } @@ -3594,15 +3594,15 @@ /* If 2.x, convert format_spec to the same type as value */ /* This is to allow things like u''.format('') */ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec)) - goto done; + goto done; if (!(PyString_Check(format_spec) || PyUnicode_Check(format_spec))) { - PyErr_Format(PyExc_TypeError, "__format__ arg must be str " - "or unicode, not %s", Py_TYPE(format_spec)->tp_name); - goto done; + PyErr_Format(PyExc_TypeError, "__format__ arg must be str " + "or unicode, not %s", Py_TYPE(format_spec)->tp_name); + goto done; } tmp = PyObject_Str(format_spec); if (tmp == NULL) - goto done; + goto done; format_spec = tmp; result = _PyBytes_FormatAdvanced(self, From python-checkins at python.org Wed Jun 9 18:31:23 2010 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 9 Jun 2010 18:31:23 +0200 (CEST) Subject: [Python-checkins] r81861 - in python/branches/release26-maint: Modules/_codecsmodule.c Objects/bytearrayobject.c Objects/stringobject.c Message-ID: <20100609163123.C161BEEC6E@mail.python.org> Author: antoine.pitrou Date: Wed Jun 9 18:31:23 2010 New Revision: 81861 Log: Merged revisions 81860 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81860 | antoine.pitrou | 2010-06-09 18:24:00 +0200 (mer., 09 juin 2010) | 3 lines Issue #8930: fix some C code indentation ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Modules/_codecsmodule.c python/branches/release26-maint/Objects/bytearrayobject.c python/branches/release26-maint/Objects/stringobject.c Modified: python/branches/release26-maint/Modules/_codecsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/_codecsmodule.c (original) +++ python/branches/release26-maint/Modules/_codecsmodule.c Wed Jun 9 18:31:23 2010 @@ -176,27 +176,27 @@ escape_encode(PyObject *self, PyObject *args) { - PyObject *str; - const char *errors = NULL; - char *buf; - Py_ssize_t len; - - if (!PyArg_ParseTuple(args, "O!|z:escape_encode", - &PyString_Type, &str, &errors)) - return NULL; - - str = PyString_Repr(str, 0); - if (!str) - return NULL; - - /* The string will be quoted. Unquote, similar to unicode-escape. */ - buf = PyString_AS_STRING (str); - len = PyString_GET_SIZE (str); - memmove(buf, buf+1, len-2); - if (_PyString_Resize(&str, len-2) < 0) - return NULL; + PyObject *str; + const char *errors = NULL; + char *buf; + Py_ssize_t len; + + if (!PyArg_ParseTuple(args, "O!|z:escape_encode", + &PyString_Type, &str, &errors)) + return NULL; - return codec_tuple(str, PyString_Size(str)); + str = PyString_Repr(str, 0); + if (!str) + return NULL; + + /* The string will be quoted. Unquote, similar to unicode-escape. */ + buf = PyString_AS_STRING (str); + len = PyString_GET_SIZE (str); + memmove(buf, buf+1, len-2); + if (_PyString_Resize(&str, len-2) < 0) + return NULL; + + return codec_tuple(str, PyString_Size(str)); } #ifdef Py_USING_UNICODE @@ -232,7 +232,7 @@ utf_7_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -245,7 +245,7 @@ decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -255,7 +255,7 @@ utf_8_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -268,7 +268,7 @@ decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -278,7 +278,7 @@ utf_16_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -291,7 +291,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -301,7 +301,7 @@ utf_16_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -315,7 +315,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -325,7 +325,7 @@ utf_16_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -339,7 +339,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -357,7 +357,7 @@ utf_16_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -370,7 +370,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -382,7 +382,7 @@ utf_32_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -395,7 +395,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -405,7 +405,7 @@ utf_32_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -418,7 +418,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -428,7 +428,7 @@ utf_32_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -441,7 +441,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -459,7 +459,7 @@ utf_32_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -472,7 +472,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -484,7 +484,7 @@ unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; PyObject *unicode; @@ -492,68 +492,68 @@ &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * raw_unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; - PyObject *unicode; + PyObject *unicode; if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * latin_1_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "s*|z:latin_1_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * ascii_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "s*|z:ascii_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * charmap_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; PyObject *mapping = NULL; @@ -563,9 +563,9 @@ if (mapping == Py_None) mapping = NULL; - unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) @@ -574,7 +574,7 @@ mbcs_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -587,7 +587,7 @@ decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); Modified: python/branches/release26-maint/Objects/bytearrayobject.c ============================================================================== --- python/branches/release26-maint/Objects/bytearrayobject.c (original) +++ python/branches/release26-maint/Objects/bytearrayobject.c Wed Jun 9 18:31:23 2010 @@ -114,24 +114,24 @@ static int bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) { - int ret; - void *ptr; - if (view == NULL) { - obj->ob_exports++; - return 0; - } - ptr = (void *) PyByteArray_AS_STRING(obj); - ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); - if (ret >= 0) { - obj->ob_exports++; - } - return ret; + int ret; + void *ptr; + if (view == NULL) { + obj->ob_exports++; + return 0; + } + ptr = (void *) PyByteArray_AS_STRING(obj); + ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); + if (ret >= 0) { + obj->ob_exports++; + } + return ret; } static void bytes_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) { - obj->ob_exports--; + obj->ob_exports--; } static Py_ssize_t @@ -1809,43 +1809,43 @@ char from_c, char to_c, Py_ssize_t maxcount) { - char *self_s, *result_s, *start, *end, *next; - Py_ssize_t self_len; - PyByteArrayObject *result; + char *self_s, *result_s, *start, *end, *next; + Py_ssize_t self_len; + PyByteArrayObject *result; - /* The result string will be the same size */ - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); + /* The result string will be the same size */ + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); - next = findchar(self_s, self_len, from_c); + next = findchar(self_s, self_len, from_c); - if (next == NULL) { - /* No matches; return the original bytes */ - return return_self(self); - } + if (next == NULL) { + /* No matches; return the original bytes */ + return return_self(self); + } - /* Need to make a new bytes */ - result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - Py_MEMCPY(result_s, self_s, self_len); + /* Need to make a new bytes */ + result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); + if (result == NULL) + return NULL; + result_s = PyByteArray_AS_STRING(result); + Py_MEMCPY(result_s, self_s, self_len); - /* change everything in-place, starting with this one */ - start = result_s + (next-self_s); - *start = to_c; - start++; - end = result_s + self_len; - - while (--maxcount > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - *next = to_c; - start = next+1; - } + /* change everything in-place, starting with this one */ + start = result_s + (next-self_s); + *start = to_c; + start++; + end = result_s + self_len; - return result; + while (--maxcount > 0) { + next = findchar(start, end-start, from_c); + if (next == NULL) + break; + *next = to_c; + start = next+1; + } + + return result; } /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ Modified: python/branches/release26-maint/Objects/stringobject.c ============================================================================== --- python/branches/release26-maint/Objects/stringobject.c (original) +++ python/branches/release26-maint/Objects/stringobject.c Wed Jun 9 18:31:23 2010 @@ -369,7 +369,7 @@ str = PyString_FromStringAndSize(s, size); if (str == NULL) - return NULL; + return NULL; v = PyString_AsDecodedString(str, encoding, errors); Py_DECREF(str); return v; @@ -382,23 +382,23 @@ PyObject *v; if (!PyString_Check(str)) { - PyErr_BadArgument(); - goto onError; + PyErr_BadArgument(); + goto onError; } if (encoding == NULL) { #ifdef Py_USING_UNICODE - encoding = PyUnicode_GetDefaultEncoding(); + encoding = PyUnicode_GetDefaultEncoding(); #else - PyErr_SetString(PyExc_ValueError, "no encoding specified"); - goto onError; + PyErr_SetString(PyExc_ValueError, "no encoding specified"); + goto onError; #endif } /* Decode via the codec registry */ v = PyCodec_Decode(str, encoding, errors); if (v == NULL) - goto onError; + goto onError; return v; @@ -414,24 +414,24 @@ v = PyString_AsDecodedObject(str, encoding, errors); if (v == NULL) - goto onError; + goto onError; #ifdef Py_USING_UNICODE /* Convert Unicode to a string using the default encoding */ if (PyUnicode_Check(v)) { - PyObject *temp = v; - v = PyUnicode_AsEncodedString(v, NULL, NULL); - Py_DECREF(temp); - if (v == NULL) - goto onError; + PyObject *temp = v; + v = PyUnicode_AsEncodedString(v, NULL, NULL); + Py_DECREF(temp); + if (v == NULL) + goto onError; } #endif if (!PyString_Check(v)) { - PyErr_Format(PyExc_TypeError, - "decoder did not return a string object (type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - goto onError; + PyErr_Format(PyExc_TypeError, + "decoder did not return a string object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + goto onError; } return v; @@ -449,7 +449,7 @@ str = PyString_FromStringAndSize(s, size); if (str == NULL) - return NULL; + return NULL; v = PyString_AsEncodedString(str, encoding, errors); Py_DECREF(str); return v; @@ -462,23 +462,23 @@ PyObject *v; if (!PyString_Check(str)) { - PyErr_BadArgument(); - goto onError; + PyErr_BadArgument(); + goto onError; } if (encoding == NULL) { #ifdef Py_USING_UNICODE - encoding = PyUnicode_GetDefaultEncoding(); + encoding = PyUnicode_GetDefaultEncoding(); #else - PyErr_SetString(PyExc_ValueError, "no encoding specified"); - goto onError; + PyErr_SetString(PyExc_ValueError, "no encoding specified"); + goto onError; #endif } /* Encode via the codec registry */ v = PyCodec_Encode(str, encoding, errors); if (v == NULL) - goto onError; + goto onError; return v; @@ -494,24 +494,24 @@ v = PyString_AsEncodedObject(str, encoding, errors); if (v == NULL) - goto onError; + goto onError; #ifdef Py_USING_UNICODE /* Convert Unicode to a string using the default encoding */ if (PyUnicode_Check(v)) { - PyObject *temp = v; - v = PyUnicode_AsEncodedString(v, NULL, NULL); - Py_DECREF(temp); - if (v == NULL) - goto onError; + PyObject *temp = v; + v = PyUnicode_AsEncodedString(v, NULL, NULL); + Py_DECREF(temp); + if (v == NULL) + goto onError; } #endif if (!PyString_Check(v)) { - PyErr_Format(PyExc_TypeError, - "encoder did not return a string object (type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - goto onError; + PyErr_Format(PyExc_TypeError, + "encoder did not return a string object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + goto onError; } return v; @@ -3331,17 +3331,17 @@ PyObject *v; if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors)) - return NULL; + return NULL; v = PyString_AsEncodedObject((PyObject *)self, encoding, errors); if (v == NULL) - goto onError; + goto onError; if (!PyString_Check(v) && !PyUnicode_Check(v)) { - PyErr_Format(PyExc_TypeError, - "encoder did not return a string/unicode object " - "(type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; + PyErr_Format(PyExc_TypeError, + "encoder did not return a string/unicode object " + "(type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; } return v; @@ -3368,17 +3368,17 @@ PyObject *v; if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors)) - return NULL; + return NULL; v = PyString_AsDecodedObject((PyObject *)self, encoding, errors); if (v == NULL) - goto onError; + goto onError; if (!PyString_Check(v) && !PyUnicode_Check(v)) { - PyErr_Format(PyExc_TypeError, - "decoder did not return a string/unicode object " - "(type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; + PyErr_Format(PyExc_TypeError, + "decoder did not return a string/unicode object " + "(type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; } return v; @@ -3403,7 +3403,7 @@ int tabsize = 8; if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize)) - return NULL; + return NULL; /* First pass: determine size of output string */ i = 0; /* chars up to and including most recent \n or \r */ @@ -3412,31 +3412,31 @@ for (p = PyString_AS_STRING(self); p < e; p++) if (*p == '\t') { if (tabsize > 0) { - incr = tabsize - (j % tabsize); - if (j > PY_SSIZE_T_MAX - incr) - goto overflow1; - j += incr; + incr = tabsize - (j % tabsize); + if (j > PY_SSIZE_T_MAX - incr) + goto overflow1; + j += incr; } } else { if (j > PY_SSIZE_T_MAX - 1) - goto overflow1; + goto overflow1; j++; if (*p == '\n' || *p == '\r') { - if (i > PY_SSIZE_T_MAX - j) - goto overflow1; - i += j; - j = 0; + if (i > PY_SSIZE_T_MAX - j) + goto overflow1; + i += j; + j = 0; } } if (i > PY_SSIZE_T_MAX - j) - goto overflow1; + goto overflow1; /* Second pass: create output string and fill it */ u = PyString_FromStringAndSize(NULL, i + j); if (!u) - return NULL; + return NULL; j = 0; /* same as in first pass */ q = PyString_AS_STRING(u); /* next output char */ @@ -3445,22 +3445,22 @@ for (p = PyString_AS_STRING(self); p < e; p++) if (*p == '\t') { if (tabsize > 0) { - i = tabsize - (j % tabsize); - j += i; - while (i--) { - if (q >= qe) - goto overflow2; - *q++ = ' '; - } + i = tabsize - (j % tabsize); + j += i; + while (i--) { + if (q >= qe) + goto overflow2; + *q++ = ' '; + } } } else { if (q >= qe) - goto overflow2; + goto overflow2; *q++ = *p; j++; if (*p == '\n' || *p == '\r') - j = 0; + j = 0; } return u; @@ -3478,26 +3478,26 @@ PyObject *u; if (left < 0) - left = 0; + left = 0; if (right < 0) - right = 0; + right = 0; if (left == 0 && right == 0 && PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + Py_INCREF(self); + return (PyObject *)self; } u = PyString_FromStringAndSize(NULL, left + PyString_GET_SIZE(self) + right); if (u) { - if (left) - memset(PyString_AS_STRING(u), fill, left); - Py_MEMCPY(PyString_AS_STRING(u) + left, - PyString_AS_STRING(self), - PyString_GET_SIZE(self)); - if (right) - memset(PyString_AS_STRING(u) + left + PyString_GET_SIZE(self), - fill, right); + if (left) + memset(PyString_AS_STRING(u), fill, left); + Py_MEMCPY(PyString_AS_STRING(u) + left, + PyString_AS_STRING(self), + PyString_GET_SIZE(self)); + if (right) + memset(PyString_AS_STRING(u) + left + PyString_GET_SIZE(self), + fill, right); } return u; @@ -3516,11 +3516,11 @@ char fillchar = ' '; if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar)) - return NULL; + return NULL; if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*) self; + Py_INCREF(self); + return (PyObject*) self; } return pad(self, 0, width - PyString_GET_SIZE(self), fillchar); @@ -3540,11 +3540,11 @@ char fillchar = ' '; if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar)) - return NULL; + return NULL; if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*) self; + Py_INCREF(self); + return (PyObject*) self; } return pad(self, width - PyString_GET_SIZE(self), 0, fillchar); @@ -3565,11 +3565,11 @@ char fillchar = ' '; if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar)) - return NULL; + return NULL; if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*) self; + Py_INCREF(self); + return (PyObject*) self; } marg = width - PyString_GET_SIZE(self); @@ -3593,18 +3593,18 @@ Py_ssize_t width; if (!PyArg_ParseTuple(args, "n:zfill", &width)) - return NULL; + return NULL; if (PyString_GET_SIZE(self) >= width) { - if (PyString_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*) self; - } - else - return PyString_FromStringAndSize( - PyString_AS_STRING(self), - PyString_GET_SIZE(self) - ); + if (PyString_CheckExact(self)) { + Py_INCREF(self); + return (PyObject*) self; + } + else + return PyString_FromStringAndSize( + PyString_AS_STRING(self), + PyString_GET_SIZE(self) + ); } fill = width - PyString_GET_SIZE(self); @@ -3612,13 +3612,13 @@ s = pad(self, fill, 0, '0'); if (s == NULL) - return NULL; + return NULL; p = PyString_AS_STRING(s); if (p[fill] == '+' || p[fill] == '-') { - /* move sign to beginning of string */ - p[0] = p[fill]; - p[fill] = '0'; + /* move sign to beginning of string */ + p[0] = p[fill]; + p[fill] = '0'; } return (PyObject*) s; @@ -3634,22 +3634,22 @@ string_isspace(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1 && - isspace(*p)) - return PyBool_FromLong(1); + isspace(*p)) + return PyBool_FromLong(1); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); for (; p < e; p++) { - if (!isspace(*p)) - return PyBool_FromLong(0); + if (!isspace(*p)) + return PyBool_FromLong(0); } return PyBool_FromLong(1); } @@ -3665,22 +3665,22 @@ string_isalpha(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1 && - isalpha(*p)) - return PyBool_FromLong(1); + isalpha(*p)) + return PyBool_FromLong(1); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); for (; p < e; p++) { - if (!isalpha(*p)) - return PyBool_FromLong(0); + if (!isalpha(*p)) + return PyBool_FromLong(0); } return PyBool_FromLong(1); } @@ -3696,22 +3696,22 @@ string_isalnum(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1 && - isalnum(*p)) - return PyBool_FromLong(1); + isalnum(*p)) + return PyBool_FromLong(1); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); for (; p < e; p++) { - if (!isalnum(*p)) - return PyBool_FromLong(0); + if (!isalnum(*p)) + return PyBool_FromLong(0); } return PyBool_FromLong(1); } @@ -3727,22 +3727,22 @@ string_isdigit(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1 && - isdigit(*p)) - return PyBool_FromLong(1); + isdigit(*p)) + return PyBool_FromLong(1); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); for (; p < e; p++) { - if (!isdigit(*p)) - return PyBool_FromLong(0); + if (!isdigit(*p)) + return PyBool_FromLong(0); } return PyBool_FromLong(1); } @@ -3758,25 +3758,25 @@ string_islower(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; int cased; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1) - return PyBool_FromLong(islower(*p) != 0); + return PyBool_FromLong(islower(*p) != 0); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); cased = 0; for (; p < e; p++) { - if (isupper(*p)) - return PyBool_FromLong(0); - else if (!cased && islower(*p)) - cased = 1; + if (isupper(*p)) + return PyBool_FromLong(0); + else if (!cased && islower(*p)) + cased = 1; } return PyBool_FromLong(cased); } @@ -3792,25 +3792,25 @@ string_isupper(PyStringObject *self) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; int cased; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1) - return PyBool_FromLong(isupper(*p) != 0); + return PyBool_FromLong(isupper(*p) != 0); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); cased = 0; for (; p < e; p++) { - if (islower(*p)) - return PyBool_FromLong(0); - else if (!cased && isupper(*p)) - cased = 1; + if (islower(*p)) + return PyBool_FromLong(0); + else if (!cased && isupper(*p)) + cased = 1; } return PyBool_FromLong(cased); } @@ -3828,38 +3828,38 @@ string_istitle(PyStringObject *self, PyObject *uncased) { register const unsigned char *p - = (unsigned char *) PyString_AS_STRING(self); + = (unsigned char *) PyString_AS_STRING(self); register const unsigned char *e; int cased, previous_is_cased; /* Shortcut for single character strings */ if (PyString_GET_SIZE(self) == 1) - return PyBool_FromLong(isupper(*p) != 0); + return PyBool_FromLong(isupper(*p) != 0); /* Special case for empty strings */ if (PyString_GET_SIZE(self) == 0) - return PyBool_FromLong(0); + return PyBool_FromLong(0); e = p + PyString_GET_SIZE(self); cased = 0; previous_is_cased = 0; for (; p < e; p++) { - register const unsigned char ch = *p; + register const unsigned char ch = *p; - if (isupper(ch)) { - if (previous_is_cased) - return PyBool_FromLong(0); - previous_is_cased = 1; - cased = 1; - } - else if (islower(ch)) { - if (!previous_is_cased) - return PyBool_FromLong(0); - previous_is_cased = 1; - cased = 1; - } - else - previous_is_cased = 0; + if (isupper(ch)) { + if (previous_is_cased) + return PyBool_FromLong(0); + previous_is_cased = 1; + cased = 1; + } + else if (islower(ch)) { + if (!previous_is_cased) + return PyBool_FromLong(0); + previous_is_cased = 1; + cased = 1; + } + else + previous_is_cased = 0; } return PyBool_FromLong(cased); } @@ -3884,7 +3884,7 @@ char *data; if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) - return NULL; + return NULL; data = PyString_AS_STRING(self); len = PyString_GET_SIZE(self); @@ -3899,31 +3899,31 @@ list = PyList_New(0); if (!list) - goto onError; + goto onError; for (i = j = 0; i < len; ) { - Py_ssize_t eol; + Py_ssize_t eol; - /* Find a line and append it */ - while (i < len && data[i] != '\n' && data[i] != '\r') - i++; + /* Find a line and append it */ + while (i < len && data[i] != '\n' && data[i] != '\r') + i++; - /* Skip the line break reading CRLF as one line break */ - eol = i; - if (i < len) { - if (data[i] == '\r' && i + 1 < len && - data[i+1] == '\n') - i += 2; - else - i++; - if (keepends) + /* Skip the line break reading CRLF as one line break */ eol = i; - } - SPLIT_APPEND(data, j, eol); - j = i; + if (i < len) { + if (data[i] == '\r' && i + 1 < len && + data[i+1] == '\n') + i += 2; + else + i++; + if (keepends) + eol = i; + } + SPLIT_APPEND(data, j, eol); + j = i; } if (j < len) { - SPLIT_APPEND(data, j, len); + SPLIT_APPEND(data, j, len); } return list; @@ -3973,15 +3973,15 @@ /* If 2.x, convert format_spec to the same type as value */ /* This is to allow things like u''.format('') */ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec)) - goto done; + goto done; if (!(PyString_Check(format_spec) || PyUnicode_Check(format_spec))) { - PyErr_Format(PyExc_TypeError, "__format__ arg must be str " - "or unicode, not %s", Py_TYPE(format_spec)->tp_name); - goto done; + PyErr_Format(PyExc_TypeError, "__format__ arg must be str " + "or unicode, not %s", Py_TYPE(format_spec)->tp_name); + goto done; } tmp = PyObject_Str(format_spec); if (tmp == NULL) - goto done; + goto done; format_spec = tmp; result = _PyBytes_FormatAdvanced(self, From python-checkins at python.org Wed Jun 9 18:38:56 2010 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 9 Jun 2010 18:38:56 +0200 (CEST) Subject: [Python-checkins] r81862 - in python/branches/py3k: Modules/_codecsmodule.c Objects/bytearrayobject.c Objects/bytesobject.c Message-ID: <20100609163856.271EAEEB7A@mail.python.org> Author: antoine.pitrou Date: Wed Jun 9 18:38:55 2010 New Revision: 81862 Log: Merged revisions 81860 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81860 | antoine.pitrou | 2010-06-09 18:24:00 +0200 (mer., 09 juin 2010) | 3 lines Issue #8930: fix some C code indentation ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_codecsmodule.c python/branches/py3k/Objects/bytearrayobject.c python/branches/py3k/Objects/bytesobject.c Modified: python/branches/py3k/Modules/_codecsmodule.c ============================================================================== --- python/branches/py3k/Modules/_codecsmodule.c (original) +++ python/branches/py3k/Modules/_codecsmodule.c Wed Jun 9 18:38:55 2010 @@ -162,62 +162,62 @@ escape_encode(PyObject *self, PyObject *args) { - static const char *hexdigits = "0123456789abcdef"; - PyObject *str; - Py_ssize_t size; - Py_ssize_t newsize; - const char *errors = NULL; - PyObject *v; - - if (!PyArg_ParseTuple(args, "O!|z:escape_encode", - &PyBytes_Type, &str, &errors)) - return NULL; - - size = PyBytes_GET_SIZE(str); - newsize = 4*size; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { - PyErr_SetString(PyExc_OverflowError, - "string is too large to encode"); - return NULL; - } - v = PyBytes_FromStringAndSize(NULL, newsize); + static const char *hexdigits = "0123456789abcdef"; + PyObject *str; + Py_ssize_t size; + Py_ssize_t newsize; + const char *errors = NULL; + PyObject *v; + + if (!PyArg_ParseTuple(args, "O!|z:escape_encode", + &PyBytes_Type, &str, &errors)) + return NULL; - if (v == NULL) { - return NULL; + size = PyBytes_GET_SIZE(str); + newsize = 4*size; + if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { + PyErr_SetString(PyExc_OverflowError, + "string is too large to encode"); + return NULL; + } + v = PyBytes_FromStringAndSize(NULL, newsize); + + if (v == NULL) { + return NULL; + } + else { + register Py_ssize_t i; + register char c; + register char *p = PyBytes_AS_STRING(v); + + for (i = 0; i < size; i++) { + /* There's at least enough room for a hex escape */ + assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); + c = PyBytes_AS_STRING(str)[i]; + if (c == '\'' || c == '\\') + *p++ = '\\', *p++ = c; + else if (c == '\t') + *p++ = '\\', *p++ = 't'; + else if (c == '\n') + *p++ = '\\', *p++ = 'n'; + else if (c == '\r') + *p++ = '\\', *p++ = 'r'; + else if (c < ' ' || c >= 0x7f) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = hexdigits[(c & 0xf0) >> 4]; + *p++ = hexdigits[c & 0xf]; + } + else + *p++ = c; } - else { - register Py_ssize_t i; - register char c; - register char *p = PyBytes_AS_STRING(v); - - for (i = 0; i < size; i++) { - /* There's at least enough room for a hex escape */ - assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); - c = PyBytes_AS_STRING(str)[i]; - if (c == '\'' || c == '\\') - *p++ = '\\', *p++ = c; - else if (c == '\t') - *p++ = '\\', *p++ = 't'; - else if (c == '\n') - *p++ = '\\', *p++ = 'n'; - else if (c == '\r') - *p++ = '\\', *p++ = 'r'; - else if (c < ' ' || c >= 0x7f) { - *p++ = '\\'; - *p++ = 'x'; - *p++ = hexdigits[(c & 0xf0) >> 4]; - *p++ = hexdigits[c & 0xf]; - } - else - *p++ = c; - } - *p = '\0'; - if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { - return NULL; - } + *p = '\0'; + if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { + return NULL; } + } - return codec_tuple(v, size); + return codec_tuple(v, size); } /* --- Decoder ------------------------------------------------------------ */ @@ -252,7 +252,7 @@ utf_7_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -265,7 +265,7 @@ decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -275,7 +275,7 @@ utf_8_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -288,7 +288,7 @@ decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -298,7 +298,7 @@ utf_16_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -311,7 +311,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -321,7 +321,7 @@ utf_16_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -335,7 +335,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -345,7 +345,7 @@ utf_16_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -359,7 +359,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -377,7 +377,7 @@ utf_16_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -390,7 +390,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -402,7 +402,7 @@ utf_32_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -415,7 +415,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -425,7 +425,7 @@ utf_32_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -438,7 +438,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -448,7 +448,7 @@ utf_32_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -461,7 +461,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -479,7 +479,7 @@ utf_32_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -492,7 +492,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -504,7 +504,7 @@ unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; PyObject *unicode; @@ -512,68 +512,68 @@ &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * raw_unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; - PyObject *unicode; + PyObject *unicode; if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * latin_1_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:latin_1_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * ascii_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:ascii_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * charmap_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; PyObject *mapping = NULL; @@ -583,9 +583,9 @@ if (mapping == Py_None) mapping = NULL; - unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) @@ -594,7 +594,7 @@ mbcs_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -607,7 +607,7 @@ decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); Modified: python/branches/py3k/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k/Objects/bytearrayobject.c (original) +++ python/branches/py3k/Objects/bytearrayobject.c Wed Jun 9 18:38:55 2010 @@ -1650,43 +1650,43 @@ char from_c, char to_c, Py_ssize_t maxcount) { - char *self_s, *result_s, *start, *end, *next; - Py_ssize_t self_len; - PyByteArrayObject *result; - - /* The result string will be the same size */ - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); - - next = findchar(self_s, self_len, from_c); - - if (next == NULL) { - /* No matches; return the original bytes */ - return return_self(self); - } + char *self_s, *result_s, *start, *end, *next; + Py_ssize_t self_len; + PyByteArrayObject *result; - /* Need to make a new bytes */ - result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - Py_MEMCPY(result_s, self_s, self_len); + /* The result string will be the same size */ + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); - /* change everything in-place, starting with this one */ - start = result_s + (next-self_s); - *start = to_c; - start++; - end = result_s + self_len; - - while (--maxcount > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - *next = to_c; - start = next+1; - } + next = findchar(self_s, self_len, from_c); + + if (next == NULL) { + /* No matches; return the original bytes */ + return return_self(self); + } + + /* Need to make a new bytes */ + result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); + if (result == NULL) + return NULL; + result_s = PyByteArray_AS_STRING(result); + Py_MEMCPY(result_s, self_s, self_len); + + /* change everything in-place, starting with this one */ + start = result_s + (next-self_s); + *start = to_c; + start++; + end = result_s + self_len; - return result; + while (--maxcount > 0) { + next = findchar(start, end-start, from_c); + if (next == NULL) + break; + *next = to_c; + start = next+1; + } + + return result; } /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Wed Jun 9 18:38:55 2010 @@ -14,10 +14,10 @@ if (buffer == NULL || buffer->bf_getbuffer == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't support the buffer API", + Py_TYPE(obj)->tp_name); + return -1; } if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) @@ -776,19 +776,19 @@ { Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) { - Py_buffer varg; - int pos; - PyErr_Clear(); - if (_getbuffer(arg, &varg) < 0) - return -1; - pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), - varg.buf, varg.len, 0); - PyBuffer_Release(&varg); - return pos >= 0; + Py_buffer varg; + int pos; + PyErr_Clear(); + if (_getbuffer(arg, &varg) < 0) + return -1; + pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), + varg.buf, varg.len, 0); + PyBuffer_Release(&varg); + return pos >= 0; } if (ival < 0 || ival >= 256) { - PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); - return -1; + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return -1; } return memchr(PyBytes_AS_STRING(self), ival, Py_SIZE(self)) != NULL; @@ -2345,12 +2345,12 @@ int keepends = 0; if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) - return NULL; + return NULL; return stringlib_splitlines( - (PyObject*) self, PyBytes_AS_STRING(self), - PyBytes_GET_SIZE(self), keepends - ); + (PyObject*) self, PyBytes_AS_STRING(self), + PyBytes_GET_SIZE(self), keepends + ); } From python-checkins at python.org Wed Jun 9 18:58:36 2010 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 9 Jun 2010 18:58:36 +0200 (CEST) Subject: [Python-checkins] r81863 - in python/branches/release31-maint: Modules/_codecsmodule.c Objects/bytearrayobject.c Objects/bytesobject.c Message-ID: <20100609165836.0EE0FEEC82@mail.python.org> Author: antoine.pitrou Date: Wed Jun 9 18:58:35 2010 New Revision: 81863 Log: Merged revisions 81862 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81862 | antoine.pitrou | 2010-06-09 18:38:55 +0200 (mer., 09 juin 2010) | 9 lines Merged revisions 81860 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81860 | antoine.pitrou | 2010-06-09 18:24:00 +0200 (mer., 09 juin 2010) | 3 lines Issue #8930: fix some C code indentation ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Modules/_codecsmodule.c python/branches/release31-maint/Objects/bytearrayobject.c python/branches/release31-maint/Objects/bytesobject.c Modified: python/branches/release31-maint/Modules/_codecsmodule.c ============================================================================== --- python/branches/release31-maint/Modules/_codecsmodule.c (original) +++ python/branches/release31-maint/Modules/_codecsmodule.c Wed Jun 9 18:58:35 2010 @@ -162,62 +162,62 @@ escape_encode(PyObject *self, PyObject *args) { - static const char *hexdigits = "0123456789abcdef"; - PyObject *str; - Py_ssize_t size; - Py_ssize_t newsize; - const char *errors = NULL; - PyObject *v; - - if (!PyArg_ParseTuple(args, "O!|z:escape_encode", - &PyBytes_Type, &str, &errors)) - return NULL; - - size = PyBytes_GET_SIZE(str); - newsize = 4*size; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { - PyErr_SetString(PyExc_OverflowError, - "string is too large to encode"); - return NULL; - } - v = PyBytes_FromStringAndSize(NULL, newsize); + static const char *hexdigits = "0123456789abcdef"; + PyObject *str; + Py_ssize_t size; + Py_ssize_t newsize; + const char *errors = NULL; + PyObject *v; + + if (!PyArg_ParseTuple(args, "O!|z:escape_encode", + &PyBytes_Type, &str, &errors)) + return NULL; - if (v == NULL) { - return NULL; + size = PyBytes_GET_SIZE(str); + newsize = 4*size; + if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { + PyErr_SetString(PyExc_OverflowError, + "string is too large to encode"); + return NULL; + } + v = PyBytes_FromStringAndSize(NULL, newsize); + + if (v == NULL) { + return NULL; + } + else { + register Py_ssize_t i; + register char c; + register char *p = PyBytes_AS_STRING(v); + + for (i = 0; i < size; i++) { + /* There's at least enough room for a hex escape */ + assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); + c = PyBytes_AS_STRING(str)[i]; + if (c == '\'' || c == '\\') + *p++ = '\\', *p++ = c; + else if (c == '\t') + *p++ = '\\', *p++ = 't'; + else if (c == '\n') + *p++ = '\\', *p++ = 'n'; + else if (c == '\r') + *p++ = '\\', *p++ = 'r'; + else if (c < ' ' || c >= 0x7f) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = hexdigits[(c & 0xf0) >> 4]; + *p++ = hexdigits[c & 0xf]; + } + else + *p++ = c; } - else { - register Py_ssize_t i; - register char c; - register char *p = PyBytes_AS_STRING(v); - - for (i = 0; i < size; i++) { - /* There's at least enough room for a hex escape */ - assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); - c = PyBytes_AS_STRING(str)[i]; - if (c == '\'' || c == '\\') - *p++ = '\\', *p++ = c; - else if (c == '\t') - *p++ = '\\', *p++ = 't'; - else if (c == '\n') - *p++ = '\\', *p++ = 'n'; - else if (c == '\r') - *p++ = '\\', *p++ = 'r'; - else if (c < ' ' || c >= 0x7f) { - *p++ = '\\'; - *p++ = 'x'; - *p++ = hexdigits[(c & 0xf0) >> 4]; - *p++ = hexdigits[c & 0xf]; - } - else - *p++ = c; - } - *p = '\0'; - if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { - return NULL; - } + *p = '\0'; + if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { + return NULL; } + } - return codec_tuple(v, PyBytes_Size(v)); + return codec_tuple(v, PyBytes_Size(v)); } /* --- Decoder ------------------------------------------------------------ */ @@ -252,7 +252,7 @@ utf_7_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -265,7 +265,7 @@ decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -275,7 +275,7 @@ utf_8_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -288,7 +288,7 @@ decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -298,7 +298,7 @@ utf_16_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -311,7 +311,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -321,7 +321,7 @@ utf_16_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -335,7 +335,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -345,7 +345,7 @@ utf_16_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -359,7 +359,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -377,7 +377,7 @@ utf_16_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -390,7 +390,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -402,7 +402,7 @@ utf_32_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -415,7 +415,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -425,7 +425,7 @@ utf_32_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -438,7 +438,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -448,7 +448,7 @@ utf_32_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -461,7 +461,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -479,7 +479,7 @@ utf_32_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -492,7 +492,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -504,7 +504,7 @@ unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; PyObject *unicode; @@ -512,68 +512,68 @@ &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * raw_unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; - PyObject *unicode; + PyObject *unicode; if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * latin_1_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:latin_1_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * ascii_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:ascii_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * charmap_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; PyObject *mapping = NULL; @@ -583,9 +583,9 @@ if (mapping == Py_None) mapping = NULL; - unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) @@ -594,7 +594,7 @@ mbcs_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -607,7 +607,7 @@ decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); Modified: python/branches/release31-maint/Objects/bytearrayobject.c ============================================================================== --- python/branches/release31-maint/Objects/bytearrayobject.c (original) +++ python/branches/release31-maint/Objects/bytearrayobject.c Wed Jun 9 18:58:35 2010 @@ -1756,43 +1756,43 @@ char from_c, char to_c, Py_ssize_t maxcount) { - char *self_s, *result_s, *start, *end, *next; - Py_ssize_t self_len; - PyByteArrayObject *result; - - /* The result string will be the same size */ - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); - - next = findchar(self_s, self_len, from_c); - - if (next == NULL) { - /* No matches; return the original bytes */ - return return_self(self); - } + char *self_s, *result_s, *start, *end, *next; + Py_ssize_t self_len; + PyByteArrayObject *result; - /* Need to make a new bytes */ - result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - Py_MEMCPY(result_s, self_s, self_len); + /* The result string will be the same size */ + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); - /* change everything in-place, starting with this one */ - start = result_s + (next-self_s); - *start = to_c; - start++; - end = result_s + self_len; - - while (--maxcount > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - *next = to_c; - start = next+1; - } + next = findchar(self_s, self_len, from_c); + + if (next == NULL) { + /* No matches; return the original bytes */ + return return_self(self); + } + + /* Need to make a new bytes */ + result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); + if (result == NULL) + return NULL; + result_s = PyByteArray_AS_STRING(result); + Py_MEMCPY(result_s, self_s, self_len); + + /* change everything in-place, starting with this one */ + start = result_s + (next-self_s); + *start = to_c; + start++; + end = result_s + self_len; - return result; + while (--maxcount > 0) { + next = findchar(start, end-start, from_c); + if (next == NULL) + break; + *next = to_c; + start = next+1; + } + + return result; } /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ Modified: python/branches/release31-maint/Objects/bytesobject.c ============================================================================== --- python/branches/release31-maint/Objects/bytesobject.c (original) +++ python/branches/release31-maint/Objects/bytesobject.c Wed Jun 9 18:58:35 2010 @@ -14,10 +14,10 @@ if (buffer == NULL || buffer->bf_getbuffer == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't support the buffer API", + Py_TYPE(obj)->tp_name); + return -1; } if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) @@ -790,19 +790,19 @@ { Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) { - Py_buffer varg; - int pos; - PyErr_Clear(); - if (_getbuffer(arg, &varg) < 0) - return -1; - pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), - varg.buf, varg.len, 0); - PyBuffer_Release(&varg); - return pos >= 0; + Py_buffer varg; + int pos; + PyErr_Clear(); + if (_getbuffer(arg, &varg) < 0) + return -1; + pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), + varg.buf, varg.len, 0); + PyBuffer_Release(&varg); + return pos >= 0; } if (ival < 0 || ival >= 256) { - PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); - return -1; + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return -1; } return memchr(PyBytes_AS_STRING(self), ival, Py_SIZE(self)) != NULL; From python-checkins at python.org Wed Jun 9 19:08:11 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Wed, 9 Jun 2010 19:08:11 +0200 (CEST) Subject: [Python-checkins] r81864 - python/trunk/Doc/library/datetime.rst Message-ID: <20100609170811.57E6AEEC74@mail.python.org> Author: alexander.belopolsky Date: Wed Jun 9 19:08:11 2010 New Revision: 81864 Log: Fixed markup of tm_isdst attribute. Modified: python/trunk/Doc/library/datetime.rst Modified: python/trunk/Doc/library/datetime.rst ============================================================================== --- python/trunk/Doc/library/datetime.rst (original) +++ python/trunk/Doc/library/datetime.rst Wed Jun 9 19:08:11 2010 @@ -928,7 +928,7 @@ of the result is set according to the :meth:`dst` method: :attr:`tzinfo` is ``None`` or :meth:`dst`` returns ``None``, :attr:`tm_isdst` is set to ``-1``; else if :meth:`dst` returns a non-zero value, :attr:`tm_isdst` is set to ``1``; - else ``tm_isdst`` is set to ``0``. + else :attr:`tm_isdst` is set to ``0``. .. method:: datetime.utctimetuple() From python-checkins at python.org Wed Jun 9 19:11:01 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Wed, 9 Jun 2010 19:11:01 +0200 (CEST) Subject: [Python-checkins] r81865 - in python/branches/py3k: Doc/library/datetime.rst Message-ID: <20100609171101.28EDFEEC7C@mail.python.org> Author: alexander.belopolsky Date: Wed Jun 9 19:11:01 2010 New Revision: 81865 Log: Merged revisions 81864 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81864 | alexander.belopolsky | 2010-06-09 13:08:11 -0400 (Wed, 09 Jun 2010) | 1 line Fixed markup of tm_isdst attribute. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/datetime.rst Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Wed Jun 9 19:11:01 2010 @@ -952,7 +952,7 @@ of the result is set according to the :meth:`dst` method: :attr:`tzinfo` is ``None`` or :meth:`dst`` returns ``None``, :attr:`tm_isdst` is set to ``-1``; else if :meth:`dst` returns a non-zero value, :attr:`tm_isdst` is set to ``1``; - else ``tm_isdst`` is set to ``0``. + else :attr:`tm_isdst` is set to ``0``. .. method:: datetime.utctimetuple() From python-checkins at python.org Wed Jun 9 19:55:28 2010 From: python-checkins at python.org (philip.jenvey) Date: Wed, 9 Jun 2010 19:55:28 +0200 (CEST) Subject: [Python-checkins] r81866 - in python/branches/release26-maint: Lib/test/test_codecs.py Misc/NEWS Modules/_codecsmodule.c Message-ID: <20100609175528.E94F6EEC51@mail.python.org> Author: philip.jenvey Date: Wed Jun 9 19:55:28 2010 New Revision: 81866 Log: Merged revisions 79779 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r79779 | philip.jenvey | 2010-04-04 19:51:51 -0700 (Sun, 04 Apr 2010) | 2 lines fix escape_encode to return the correct consumed size ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_codecs.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/_codecsmodule.c Modified: python/branches/release26-maint/Lib/test/test_codecs.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_codecs.py (original) +++ python/branches/release26-maint/Lib/test/test_codecs.py Wed Jun 9 19:55:28 2010 @@ -829,6 +829,9 @@ "UnicodeInternalTest") self.assertEquals((u"ab", 12), ignored) + encoder = codecs.getencoder("string-escape") + self.assertEquals(encoder(r'\x00')[1], 4) + # From http://www.gnu.org/software/libidn/draft-josefsson-idn-test-vectors.html nameprep_tests = [ # 3.1 Map to nothing. Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Jun 9 19:55:28 2010 @@ -67,6 +67,8 @@ Library ------- +- Fix codecs.escape_encode to return the correct consumed size. + - Issue #6470: Drop UNC prefix in FixTk. - Issue #8833: tarfile created hard link entries with a size field != 0 by Modified: python/branches/release26-maint/Modules/_codecsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/_codecsmodule.c (original) +++ python/branches/release26-maint/Modules/_codecsmodule.c Wed Jun 9 19:55:28 2010 @@ -179,12 +179,13 @@ PyObject *str; const char *errors = NULL; char *buf; - Py_ssize_t len; + Py_ssize_t consumed, len; - if (!PyArg_ParseTuple(args, "O!|z:escape_encode", - &PyString_Type, &str, &errors)) + if (!PyArg_ParseTuple(args, "S|z:escape_encode", + &str, &errors)) return NULL; + consumed = PyString_GET_SIZE(str); str = PyString_Repr(str, 0); if (!str) return NULL; @@ -196,7 +197,7 @@ if (_PyString_Resize(&str, len-2) < 0) return NULL; - return codec_tuple(str, PyString_Size(str)); + return codec_tuple(str, consumed); } #ifdef Py_USING_UNICODE From python-checkins at python.org Wed Jun 9 19:56:11 2010 From: python-checkins at python.org (philip.jenvey) Date: Wed, 9 Jun 2010 19:56:11 +0200 (CEST) Subject: [Python-checkins] r81867 - in python/branches/release31-maint: Lib/test/test_codecs.py Misc/NEWS Modules/_codecsmodule.c Message-ID: <20100609175611.70C89EEBC0@mail.python.org> Author: philip.jenvey Date: Wed Jun 9 19:56:11 2010 New Revision: 81867 Log: Merged revisions 79780 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r79780 | philip.jenvey | 2010-04-04 20:05:24 -0700 (Sun, 04 Apr 2010) | 9 lines Merged revisions 79779 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r79779 | philip.jenvey | 2010-04-04 19:51:51 -0700 (Sun, 04 Apr 2010) | 2 lines fix escape_encode to return the correct consumed size ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_codecs.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/_codecsmodule.c Modified: python/branches/release31-maint/Lib/test/test_codecs.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_codecs.py (original) +++ python/branches/release31-maint/Lib/test/test_codecs.py Wed Jun 9 19:56:11 2010 @@ -915,6 +915,8 @@ self.assertEquals(encoder("a")[1], 1) self.assertEquals(encoder("\xe9\u0142")[1], 2) + self.assertEquals(codecs.escape_encode(br'\x00')[1], 4) + # From http://www.gnu.org/software/libidn/draft-josefsson-idn-test-vectors.html nameprep_tests = [ # 3.1 Map to nothing. Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Wed Jun 9 19:56:11 2010 @@ -57,6 +57,8 @@ Library ------- +- Fix codecs.escape_encode to return the correct consumed size. + - Issue #8897: Fix sunau module, use bytes to write the header. Patch written by Thomas Jollans. Modified: python/branches/release31-maint/Modules/_codecsmodule.c ============================================================================== --- python/branches/release31-maint/Modules/_codecsmodule.c (original) +++ python/branches/release31-maint/Modules/_codecsmodule.c Wed Jun 9 19:56:11 2010 @@ -217,7 +217,7 @@ } } - return codec_tuple(v, PyBytes_Size(v)); + return codec_tuple(v, size); } /* --- Decoder ------------------------------------------------------------ */ From python-checkins at python.org Wed Jun 9 21:45:05 2010 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 9 Jun 2010 21:45:05 +0200 (CEST) Subject: [Python-checkins] r81868 - in python/trunk: Parser/asdl_c.py Python/Python-ast.c Message-ID: <20100609194505.1DFEFEEA1F@mail.python.org> Author: benjamin.peterson Date: Wed Jun 9 21:45:04 2010 New Revision: 81868 Log: fix code formatting Modified: python/trunk/Parser/asdl_c.py python/trunk/Python/Python-ast.c Modified: python/trunk/Parser/asdl_c.py ============================================================================== --- python/trunk/Parser/asdl_c.py (original) +++ python/trunk/Parser/asdl_c.py Wed Jun 9 21:45:04 2010 @@ -733,8 +733,9 @@ { int i, result; PyObject *s, *l = PyTuple_New(num_fields); - if (!l) return 0; - for(i = 0; i < num_fields; i++) { + if (!l) + return 0; + for (i = 0; i < num_fields; i++) { s = PyString_FromString(attrs[i]); if (!s) { Py_DECREF(l); Modified: python/trunk/Python/Python-ast.c ============================================================================== --- python/trunk/Python/Python-ast.c (original) +++ python/trunk/Python/Python-ast.c Wed Jun 9 21:45:04 2010 @@ -527,8 +527,9 @@ { int i, result; PyObject *s, *l = PyTuple_New(num_fields); - if (!l) return 0; - for(i = 0; i < num_fields; i++) { + if (!l) + return 0; + for (i = 0; i < num_fields; i++) { s = PyString_FromString(attrs[i]); if (!s) { Py_DECREF(l); From solipsis at pitrou.net Thu Jun 10 01:23:42 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 10 Jun 2010 01:23:42 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81865): sum=0 Message-ID: <20100609232342.7A1BA1771C@ns6635.ovh.net> py3k results for svn r81865 (hg cset 60bd3c2dbfb4) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogQOb7jB', '-x'] From python-checkins at python.org Thu Jun 10 14:00:56 2010 From: python-checkins at python.org (victor.stinner) Date: Thu, 10 Jun 2010 14:00:56 +0200 (CEST) Subject: [Python-checkins] r81869 - in python/branches/py3k: Misc/NEWS Objects/unicodeobject.c Message-ID: <20100610120056.41171E498@mail.python.org> Author: victor.stinner Date: Thu Jun 10 14:00:55 2010 New Revision: 81869 Log: Issue #8922: Normalize the encoding name in PyUnicode_AsEncodedString() to enable shortcuts for upper case encoding name. Add also a shortcut for "iso-8859-1" in PyUnicode_AsEncodedString() and PyUnicode_Decode(). Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 10 14:00:55 2010 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #8922: Normalize the encoding name in PyUnicode_AsEncodedString() to + enable shortcuts for upper case encoding name. Add also a shortcut for + "iso-8859-1" in PyUnicode_AsEncodedString() and PyUnicode_Decode(). + - Issue #8838: Remove codecs.charbuffer_encode() function. The buffer protocol doesn't support "char buffer" anymore in Python3. Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Thu Jun 10 14:00:55 2010 @@ -1293,25 +1293,21 @@ return NULL; } -PyObject *PyUnicode_Decode(const char *s, - Py_ssize_t size, - const char *encoding, - const char *errors) +/* Convert encoding to lower case and replace '_' with '-' in order to + catch e.g. UTF_8. Truncate the string if it is longer than lower_len-1 + characters. */ +static void normalize_encoding(const char *encoding, + char *lower, + size_t lower_len) { - PyObject *buffer = NULL, *unicode; - Py_buffer info; - char lower[20]; /* Enough for any encoding name we recognize */ - char *l; const char *e; + char *l; + char *l_end; - if (encoding == NULL) - encoding = PyUnicode_GetDefaultEncoding(); - - /* Convert encoding to lower case and replace '_' with '-' in order to - catch e.g. UTF_8 */ e = encoding; l = lower; - while (*e && l < &lower[(sizeof lower) - 2]) { + l_end = &lower[lower_len - 1]; + while (*e && l < l_end) { if (ISUPPER(*e)) { *l++ = TOLOWER(*e++); } @@ -1324,8 +1320,22 @@ } } *l = '\0'; +} + +PyObject *PyUnicode_Decode(const char *s, + Py_ssize_t size, + const char *encoding, + const char *errors) +{ + PyObject *buffer = NULL, *unicode; + Py_buffer info; + char lower[11]; /* Enough for any encoding shortcut */ + + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ + normalize_encoding(encoding, lower, sizeof(lower)); if (strcmp(lower, "utf-8") == 0) return PyUnicode_DecodeUTF8(s, size, errors); else if ((strcmp(lower, "latin-1") == 0) || @@ -1478,6 +1488,7 @@ const char *errors) { PyObject *v; + char lower[11]; /* Enough for any encoding shortcut */ if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); @@ -1488,21 +1499,23 @@ encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - if (strcmp(encoding, "utf-8") == 0) + normalize_encoding(encoding, lower, sizeof(lower)); + if (strcmp(lower, "utf-8") == 0) return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), errors); - else if (strcmp(encoding, "latin-1") == 0) + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(encoding, "mbcs") == 0) + else if (strcmp(lower, "mbcs") == 0) return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), errors); #endif - else if (strcmp(encoding, "ascii") == 0) + else if (strcmp(lower, "ascii") == 0) return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), errors); From python-checkins at python.org Thu Jun 10 14:01:27 2010 From: python-checkins at python.org (victor.stinner) Date: Thu, 10 Jun 2010 14:01:27 +0200 (CEST) Subject: [Python-checkins] r81870 - python/branches/release31-maint Message-ID: <20100610120127.35C02E498@mail.python.org> Author: victor.stinner Date: Thu Jun 10 14:01:27 2010 New Revision: 81870 Log: Blocked revisions 81869 via svnmerge ........ r81869 | victor.stinner | 2010-06-10 14:00:55 +0200 (jeu., 10 juin 2010) | 4 lines Issue #8922: Normalize the encoding name in PyUnicode_AsEncodedString() to enable shortcuts for upper case encoding name. Add also a shortcut for "iso-8859-1" in PyUnicode_AsEncodedString() and PyUnicode_Decode(). ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Thu Jun 10 15:36:23 2010 From: python-checkins at python.org (victor.stinner) Date: Thu, 10 Jun 2010 15:36:23 +0200 (CEST) Subject: [Python-checkins] r81871 - python/branches/py3k/Objects/unicodeobject.c Message-ID: <20100610133623.A0E31D2E9@mail.python.org> Author: victor.stinner Date: Thu Jun 10 15:36:23 2010 New Revision: 81871 Log: Fix r81869: ISO-8859-15 was seen as an alias to ISO-8859-1 Don't use normalize_encoding() result if it is truncated. Modified: python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Thu Jun 10 15:36:23 2010 @@ -1294,11 +1294,12 @@ } /* Convert encoding to lower case and replace '_' with '-' in order to - catch e.g. UTF_8. Truncate the string if it is longer than lower_len-1 - characters. */ -static void normalize_encoding(const char *encoding, - char *lower, - size_t lower_len) + catch e.g. UTF_8. Return 0 on error (encoding is longer than lower_len-1), + 1 on success. */ +static int +normalize_encoding(const char *encoding, + char *lower, + size_t lower_len) { const char *e; char *l; @@ -1307,7 +1308,9 @@ e = encoding; l = lower; l_end = &lower[lower_len - 1]; - while (*e && l < l_end) { + while (*e) { + if (l == l_end) + return 0; if (ISUPPER(*e)) { *l++ = TOLOWER(*e++); } @@ -1320,6 +1323,7 @@ } } *l = '\0'; + return 1; } PyObject *PyUnicode_Decode(const char *s, @@ -1335,22 +1339,23 @@ encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - normalize_encoding(encoding, lower, sizeof(lower)); - if (strcmp(lower, "utf-8") == 0) - return PyUnicode_DecodeUTF8(s, size, errors); - else if ((strcmp(lower, "latin-1") == 0) || - (strcmp(lower, "iso-8859-1") == 0)) - return PyUnicode_DecodeLatin1(s, size, errors); + if (normalize_encoding(encoding, lower, sizeof(lower))) { + if (strcmp(lower, "utf-8") == 0) + return PyUnicode_DecodeUTF8(s, size, errors); + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) + return PyUnicode_DecodeLatin1(s, size, errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(lower, "mbcs") == 0) - return PyUnicode_DecodeMBCS(s, size, errors); + else if (strcmp(lower, "mbcs") == 0) + return PyUnicode_DecodeMBCS(s, size, errors); #endif - else if (strcmp(lower, "ascii") == 0) - return PyUnicode_DecodeASCII(s, size, errors); - else if (strcmp(lower, "utf-16") == 0) - return PyUnicode_DecodeUTF16(s, size, errors, 0); - else if (strcmp(lower, "utf-32") == 0) - return PyUnicode_DecodeUTF32(s, size, errors, 0); + else if (strcmp(lower, "ascii") == 0) + return PyUnicode_DecodeASCII(s, size, errors); + else if (strcmp(lower, "utf-16") == 0) + return PyUnicode_DecodeUTF16(s, size, errors, 0); + else if (strcmp(lower, "utf-32") == 0) + return PyUnicode_DecodeUTF32(s, size, errors, 0); + } /* Decode via the codec registry */ buffer = NULL; @@ -1499,26 +1504,27 @@ encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - normalize_encoding(encoding, lower, sizeof(lower)); - if (strcmp(lower, "utf-8") == 0) - return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); - else if ((strcmp(lower, "latin-1") == 0) || - (strcmp(lower, "iso-8859-1") == 0)) - return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + if (normalize_encoding(encoding, lower, sizeof(lower))) { + if (strcmp(lower, "utf-8") == 0) + return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) + return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(lower, "mbcs") == 0) - return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + else if (strcmp(lower, "mbcs") == 0) + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #endif - else if (strcmp(lower, "ascii") == 0) - return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + else if (strcmp(lower, "ascii") == 0) + return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + } /* During bootstrap, we may need to find the encodings package, to load the file system encoding, and require the file system encoding in order to load the encodings @@ -1528,7 +1534,7 @@ the encodings module is ASCII-only. XXX could try wcstombs instead, if the file system encoding is the locale's encoding. */ - else if (Py_FileSystemDefaultEncoding && + if (Py_FileSystemDefaultEncoding && strcmp(encoding, Py_FileSystemDefaultEncoding) == 0 && !PyThreadState_GET()->interp->codecs_initialized) return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), From python-checkins at python.org Thu Jun 10 15:38:27 2010 From: python-checkins at python.org (victor.stinner) Date: Thu, 10 Jun 2010 15:38:27 +0200 (CEST) Subject: [Python-checkins] r81872 - python/branches/release31-maint Message-ID: <20100610133827.19367DF1E@mail.python.org> Author: victor.stinner Date: Thu Jun 10 15:38:26 2010 New Revision: 81872 Log: Blocked revisions 81871 via svnmerge ........ r81871 | victor.stinner | 2010-06-10 15:36:23 +0200 (jeu., 10 juin 2010) | 4 lines Fix r81869: ISO-8859-15 was seen as an alias to ISO-8859-1 Don't use normalize_encoding() result if it is truncated. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Thu Jun 10 18:05:10 2010 From: python-checkins at python.org (mark.dickinson) Date: Thu, 10 Jun 2010 18:05:10 +0200 (CEST) Subject: [Python-checkins] r81873 - in python/branches/py3k: Lib/test/test_getargs2.py Misc/NEWS Python/getargs.c Message-ID: <20100610160510.F34EBF004@mail.python.org> Author: mark.dickinson Date: Thu Jun 10 18:05:10 2010 New Revision: 81873 Log: Issue #8950: Make PyArg_Parse* with 'L' code raise for float inputs, instead of warning. This makes it consistent with the other integer codes. Modified: python/branches/py3k/Lib/test/test_getargs2.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/getargs.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 Thu Jun 10 18:05:10 2010 @@ -1,7 +1,6 @@ import unittest from test import support from _testcapi import getargs_keywords -import warnings """ > How about the following counterproposal. This also changes some of @@ -190,21 +189,7 @@ from _testcapi import getargs_L # L returns 'long long', and does range checking (LLONG_MIN # ... LLONG_MAX) - with warnings.catch_warnings(): - warnings.filterwarnings( - "ignore", - category=DeprecationWarning, - message=".*integer argument expected, got float", - module=__name__) - self.assertEqual(3, getargs_L(3.14)) - with warnings.catch_warnings(): - warnings.filterwarnings( - "error", - category=DeprecationWarning, - message=".*integer argument expected, got float", - module="unittest") - self.assertRaises(DeprecationWarning, getargs_L, 3.14) - + self.assertRaises(TypeError, getargs_L, 3.14) self.assertRaises(TypeError, getargs_L, "Hello") self.assertEqual(99, getargs_L(Int())) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 10 18:05:10 2010 @@ -12,6 +12,11 @@ Core and Builtins ----------------- +- Issue #8950: (See also issue #5080). Py_ArgParse*() functions now + raise TypeError instead of giving a DeprecationWarning when a float + is parsed using the 'L' code (for long long). (All other integer + codes already raise TypeError in this case.) + - Issue #8922: Normalize the encoding name in PyUnicode_AsEncodedString() to enable shortcuts for upper case encoding name. Add also a shortcut for "iso-8859-1" in PyUnicode_AsEncodedString() and PyUnicode_Decode(). Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Thu Jun 10 18:05:10 2010 @@ -582,19 +582,6 @@ #define CONV_UNICODE "(unicode conversion error)" -/* explicitly check for float arguments when integers are expected. For now - * signal a warning. Returns true if an exception was raised. */ -static int -float_argument_warning(PyObject *arg) -{ - if (PyFloat_Check(arg) && - PyErr_Warn(PyExc_DeprecationWarning, - "integer argument expected, got float" )) - return 1; - else - return 0; -} - /* Explicitly check for float arguments when integers are expected. Return 1 for error, 0 if ok. */ static int @@ -791,14 +778,13 @@ case 'L': {/* PY_LONG_LONG */ PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * ); PY_LONG_LONG ival; - if (float_argument_warning(arg)) + if (float_argument_error(arg)) return converterr("long", arg, msgbuf, bufsize); ival = PyLong_AsLongLong(arg); - if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) { + if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred()) return converterr("long", arg, msgbuf, bufsize); - } else { + else *p = ival; - } break; } From python-checkins at python.org Thu Jun 10 18:16:08 2010 From: python-checkins at python.org (michael.foord) Date: Thu, 10 Jun 2010 18:16:08 +0200 (CEST) Subject: [Python-checkins] r81874 - in python/branches/py3k: Lib/unittest/case.py Lib/unittest/suite.py Lib/unittest/test/test_runner.py Lib/unittest/test/test_setups.py Message-ID: <20100610161608.621EBEE996@mail.python.org> Author: michael.foord Date: Thu Jun 10 18:16:08 2010 New Revision: 81874 Log: Merged revisions 81853 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81853 | michael.foord | 2010-06-08 23:44:52 +0100 (Tue, 08 Jun 2010) | 1 line Issue 8948. cleanup functions are not run by unittest.TestCase.debug(), plus class and module teardowns are not run by unittest.TestSuite.debug(). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/case.py python/branches/py3k/Lib/unittest/suite.py python/branches/py3k/Lib/unittest/test/test_runner.py python/branches/py3k/Lib/unittest/test/test_setups.py Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Thu Jun 10 18:16:08 2010 @@ -389,6 +389,9 @@ self.setUp() getattr(self, self._testMethodName)() self.tearDown() + while self._cleanups: + function, args, kwargs = self._cleanups.pop(-1) + function(*args, **kwargs) def skipTest(self, reason): """Skip this test.""" Modified: python/branches/py3k/Lib/unittest/suite.py ============================================================================== --- python/branches/py3k/Lib/unittest/suite.py (original) +++ python/branches/py3k/Lib/unittest/suite.py Thu Jun 10 18:16:08 2010 @@ -84,9 +84,16 @@ self._handleModuleTearDown(result) return result + def debug(self): + """Run the tests without collecting errors in a TestResult""" + debug = _DebugResult() + self._wrapped_run(debug, True) + self._tearDownPreviousClass(None, debug) + self._handleModuleTearDown(debug) + ################################ # private methods - def _wrapped_run(self, result): + def _wrapped_run(self, result, debug=False): for test in self: if result.shouldStop: break @@ -103,8 +110,10 @@ if hasattr(test, '_wrapped_run'): test._wrapped_run(result) - else: + elif not debug: test(result) + else: + test.debug() def _handleClassSetUp(self, test, result): previousClass = getattr(result, '_previousTestClass', None) @@ -128,6 +137,8 @@ try: setUpClass() except Exception as e: + if isinstance(result, _DebugResult): + raise currentClass._classSetupFailed = True className = util.strclass(currentClass) errorName = 'setUpClass (%s)' % className @@ -160,6 +171,8 @@ try: setUpModule() except Exception as e: + if isinstance(result, _DebugResult): + raise result._moduleSetUpFailed = True errorName = 'setUpModule (%s)' % currentModule self._addClassOrModuleLevelException(result, e, errorName) @@ -189,6 +202,8 @@ try: tearDownModule() except Exception as e: + if isinstance(result, _DebugResult): + raise errorName = 'tearDownModule (%s)' % previousModule self._addClassOrModuleLevelException(result, e, errorName) @@ -209,6 +224,8 @@ try: tearDownClass() except Exception as e: + if isinstance(result, _DebugResult): + raise className = util.strclass(previousClass) errorName = 'tearDownClass (%s)' % className self._addClassOrModuleLevelException(result, e, errorName) @@ -260,3 +277,10 @@ except TypeError: return True return False + + +class _DebugResult(object): + "Used by the TestSuite to hold previous class when running in debug." + _previousTestClass = None + _moduleSetUpFailed = False + shouldStop = False Modified: python/branches/py3k/Lib/unittest/test/test_runner.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_runner.py (original) +++ python/branches/py3k/Lib/unittest/test/test_runner.py Thu Jun 10 18:16:08 2010 @@ -110,6 +110,31 @@ test.run(result) self.assertEqual(ordering, ['setUp', 'cleanup1']) + def testTestCaseDebugExecutesCleanups(self): + ordering = [] + + class TestableTest(unittest.TestCase): + def setUp(self): + ordering.append('setUp') + self.addCleanup(cleanup1) + + def testNothing(self): + ordering.append('test') + + def tearDown(self): + ordering.append('tearDown') + + test = TestableTest('testNothing') + + def cleanup1(): + ordering.append('cleanup1') + test.addCleanup(cleanup2) + def cleanup2(): + ordering.append('cleanup2') + + test.debug() + self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2']) + class Test_TextTestRunner(unittest.TestCase): """Tests for TextTestRunner.""" Modified: python/branches/py3k/Lib/unittest/test/test_setups.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_setups.py (original) +++ python/branches/py3k/Lib/unittest/test/test_setups.py Thu Jun 10 18:16:08 2010 @@ -438,6 +438,68 @@ skipped = result.skipped[0][0] self.assertEqual(str(skipped), 'setUpModule (Module)') + def test_suite_debug_executes_setups_and_teardowns(self): + ordering = [] + + class Module(object): + @staticmethod + def setUpModule(): + ordering.append('setUpModule') + @staticmethod + def tearDownModule(): + ordering.append('tearDownModule') + + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + @classmethod + def tearDownClass(cls): + ordering.append('tearDownClass') + def test_something(self): + ordering.append('test_something') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + suite.debug() + expectedOrder = ['setUpModule', 'setUpClass', 'test_something', 'tearDownClass', 'tearDownModule'] + self.assertEqual(ordering, expectedOrder) + + def test_suite_debug_propagates_exceptions(self): + class Module(object): + @staticmethod + def setUpModule(): + if phase == 0: + raise Exception('setUpModule') + @staticmethod + def tearDownModule(): + if phase == 1: + raise Exception('tearDownModule') + + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + if phase == 2: + raise Exception('setUpClass') + @classmethod + def tearDownClass(cls): + if phase == 3: + raise Exception('tearDownClass') + def test_something(self): + if phase == 4: + raise Exception('test_something') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + + messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something') + for phase, msg in enumerate(messages): + with self.assertRaisesRegexp(Exception, msg): + suite.debug() if __name__ == '__main__': unittest.main() From python-checkins at python.org Thu Jun 10 18:17:07 2010 From: python-checkins at python.org (michael.foord) Date: Thu, 10 Jun 2010 18:17:07 +0200 (CEST) Subject: [Python-checkins] r81875 - in python/branches/py3k: Lib/unittest/case.py Message-ID: <20100610161707.CCFEAEE989@mail.python.org> Author: michael.foord Date: Thu Jun 10 18:17:07 2010 New Revision: 81875 Log: Merged revisions 81859 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81859 | michael.foord | 2010-06-09 13:29:56 +0100 (Wed, 09 Jun 2010) | 1 line Typo correction. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/case.py Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Thu Jun 10 18:17:07 2010 @@ -172,7 +172,7 @@ longMessage = False - # This attribute sets the maximum length of a diff in failure messsages + # This attribute sets the maximum length of a diff in failure messages # by assert methods using difflib. It is looked up as an instance attribute # so can be configured by individual tests if required. From python-checkins at python.org Thu Jun 10 18:32:00 2010 From: python-checkins at python.org (michael.foord) Date: Thu, 10 Jun 2010 18:32:00 +0200 (CEST) Subject: [Python-checkins] r81876 - python/trunk/Misc/NEWS Message-ID: <20100610163200.D805EC9EA@mail.python.org> Author: michael.foord Date: Thu Jun 10 18:32:00 2010 New Revision: 81876 Log: NEWS update for issue 8948. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Jun 10 18:32:00 2010 @@ -4,8 +4,8 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) -What's New in Python release candidate 2? -========================================= +What's New in Python 2.7 release candidate 2? +============================================= *Release date: XXXX-XX-XX* @@ -18,6 +18,9 @@ Library ------- +- Issue #8948: cleanup functions and class / module setups and teardowns are + now honored in unittest debug methods. + Documentation ------------- From python-checkins at python.org Thu Jun 10 18:33:34 2010 From: python-checkins at python.org (michael.foord) Date: Thu, 10 Jun 2010 18:33:34 +0200 (CEST) Subject: [Python-checkins] r81877 - python/branches/py3k Message-ID: <20100610163334.993BDC9EA@mail.python.org> Author: michael.foord Date: Thu Jun 10 18:33:34 2010 New Revision: 81877 Log: Blocked revisions 81876 via svnmerge ........ r81876 | michael.foord | 2010-06-10 17:32:00 +0100 (Thu, 10 Jun 2010) | 1 line NEWS update for issue 8948. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Jun 10 22:40:21 2010 From: python-checkins at python.org (michael.foord) Date: Thu, 10 Jun 2010 22:40:21 +0200 (CEST) Subject: [Python-checkins] r81878 - in python/trunk/Lib/unittest: suite.py test/test_setups.py Message-ID: <20100610204021.6B9A6CA7D@mail.python.org> Author: michael.foord Date: Thu Jun 10 22:40:21 2010 New Revision: 81878 Log: Fix issue with nested test suites debug method and module setups. (unittest) Modified: python/trunk/Lib/unittest/suite.py python/trunk/Lib/unittest/test/test_setups.py Modified: python/trunk/Lib/unittest/suite.py ============================================================================== --- python/trunk/Lib/unittest/suite.py (original) +++ python/trunk/Lib/unittest/suite.py Thu Jun 10 22:40:21 2010 @@ -112,7 +112,7 @@ continue if hasattr(test, '_wrapped_run'): - test._wrapped_run(result) + test._wrapped_run(result, debug) elif not debug: test(result) else: Modified: python/trunk/Lib/unittest/test/test_setups.py ============================================================================== --- python/trunk/Lib/unittest/test/test_setups.py (original) +++ python/trunk/Lib/unittest/test/test_setups.py Thu Jun 10 22:40:21 2010 @@ -495,7 +495,9 @@ Test.__module__ = 'Module' sys.modules['Module'] = Module - suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + _suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + suite = unittest.TestSuite() + suite.addTest(_suite) messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something') for phase, msg in enumerate(messages): From python-checkins at python.org Thu Jun 10 22:41:54 2010 From: python-checkins at python.org (michael.foord) Date: Thu, 10 Jun 2010 22:41:54 +0200 (CEST) Subject: [Python-checkins] r81879 - in python/branches/py3k: Lib/unittest/suite.py Lib/unittest/test/test_setups.py Message-ID: <20100610204154.BBE65CA7D@mail.python.org> Author: michael.foord Date: Thu Jun 10 22:41:54 2010 New Revision: 81879 Log: Merged revisions 81878 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81878 | michael.foord | 2010-06-10 21:40:21 +0100 (Thu, 10 Jun 2010) | 2 lines Fix issue with nested test suites debug method and module setups. (unittest) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/unittest/suite.py python/branches/py3k/Lib/unittest/test/test_setups.py Modified: python/branches/py3k/Lib/unittest/suite.py ============================================================================== --- python/branches/py3k/Lib/unittest/suite.py (original) +++ python/branches/py3k/Lib/unittest/suite.py Thu Jun 10 22:41:54 2010 @@ -109,7 +109,7 @@ continue if hasattr(test, '_wrapped_run'): - test._wrapped_run(result) + test._wrapped_run(result, debug) elif not debug: test(result) else: Modified: python/branches/py3k/Lib/unittest/test/test_setups.py ============================================================================== --- python/branches/py3k/Lib/unittest/test/test_setups.py (original) +++ python/branches/py3k/Lib/unittest/test/test_setups.py Thu Jun 10 22:41:54 2010 @@ -494,7 +494,9 @@ Test.__module__ = 'Module' sys.modules['Module'] = Module - suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + _suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + suite = unittest.TestSuite() + suite.addTest(_suite) messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something') for phase, msg in enumerate(messages): From solipsis at pitrou.net Fri Jun 11 01:23:24 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 11 Jun 2010 01:23:24 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81879): sum=0 Message-ID: <20100610232324.2EC601770B@ns6635.ovh.net> py3k results for svn r81879 (hg cset d110971d81ce) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogZmVInF', '-x'] From python-checkins at python.org Fri Jun 11 02:14:34 2010 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 11 Jun 2010 02:14:34 +0200 (CEST) Subject: [Python-checkins] r81880 - python/trunk/Demo/embed/Makefile Message-ID: <20100611001434.95C22F67B@mail.python.org> Author: andrew.kuchling Date: Fri Jun 11 02:14:34 2010 New Revision: 81880 Log: Edit comments for current Python; bump version number of Python Modified: python/trunk/Demo/embed/Makefile Modified: python/trunk/Demo/embed/Makefile ============================================================================== --- python/trunk/Demo/embed/Makefile (original) +++ python/trunk/Demo/embed/Makefile Fri Jun 11 02:14:34 2010 @@ -1,5 +1,5 @@ # Makefile for embedded Python use demo. -# (This version tailored for my Red Hat Linux 6.1 setup; +# (This version originally written on Red Hat Linux 6.1; # edit lines marked with XXX.) # XXX The compiler you are using @@ -10,7 +10,7 @@ srcdir= ../.. # Python version -VERSION= 2.6 +VERSION= 2.7 # Compiler flags OPT= -g @@ -21,7 +21,7 @@ # The Python library LIBPYTHON= $(blddir)/libpython$(VERSION).a -# XXX edit LIBS (in particular) to match $(blddir)/Modules/Makefile +# XXX edit LIBS (in particular) to match $(blddir)/Makefile LIBS= -lnsl -ldl -lreadline -ltermcap -lieee -lpthread -lutil LDFLAGS= -Xlinker -export-dynamic SYSLIBS= -lm From python-checkins at python.org Fri Jun 11 02:16:08 2010 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 11 Jun 2010 02:16:08 +0200 (CEST) Subject: [Python-checkins] r81881 - python/trunk/Demo/embed/demo.c Message-ID: <20100611001608.5856CF4D4@mail.python.org> Author: andrew.kuchling Date: Fri Jun 11 02:16:08 2010 New Revision: 81881 Log: #5753: update demo.c to use PySys_SetArgvEx(), and add a comment Modified: python/trunk/Demo/embed/demo.c Modified: python/trunk/Demo/embed/demo.c ============================================================================== --- python/trunk/Demo/embed/demo.c (original) +++ python/trunk/Demo/embed/demo.c Fri Jun 11 02:16:08 2010 @@ -16,10 +16,19 @@ initxyzzy(); /* Define sys.argv. It is up to the application if you - want this; you can also let it undefined (since the Python + want this; you can also leave it undefined (since the Python code is generally not a main program it has no business - touching sys.argv...) */ - PySys_SetArgv(argc, argv); + touching sys.argv...) + + If the third argument is true, sys.path is modified to include + either the directory containing the script named by argv[0], or + the current working directory. This can be risky; if you run + an application embedding Python in a directory controlled by + someone else, attackers could put a Trojan-horse module in the + directory (say, a file named os.py) that your application would + then import and run. + */ + PySys_SetArgvEx(argc, argv, 0); /* Do some application specific code */ printf("Hello, brave new world\n\n"); From python-checkins at python.org Fri Jun 11 02:23:01 2010 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 11 Jun 2010 02:23:01 +0200 (CEST) Subject: [Python-checkins] r81882 - python/trunk/Doc/c-api/intro.rst Message-ID: <20100611002301.91EFBC948@mail.python.org> Author: andrew.kuchling Date: Fri Jun 11 02:23:01 2010 New Revision: 81882 Log: #5753: Suggest PySys_SetArgvEx() instead of PySys_SetArgv() Modified: python/trunk/Doc/c-api/intro.rst Modified: python/trunk/Doc/c-api/intro.rst ============================================================================== --- python/trunk/Doc/c-api/intro.rst (original) +++ python/trunk/Doc/c-api/intro.rst Fri Jun 11 02:23:01 2010 @@ -524,12 +524,12 @@ :mod:`__builtin__`, :mod:`__main__`, :mod:`sys`, and :mod:`exceptions`. It also initializes the module search path (``sys.path``). -.. index:: single: PySys_SetArgv() +.. index:: single: PySys_SetArgvEx() :cfunc:`Py_Initialize` does not set the "script argument list" (``sys.argv``). -If this variable is needed by Python code that will be executed later, it must -be set explicitly with a call to ``PySys_SetArgv(argc, argv)`` subsequent to -the call to :cfunc:`Py_Initialize`. +If this variable is needed by Python code that will be executed later, it must +be set explicitly with a call to ``PySys_SetArgvEx(argc, argv, updatepath)`` +after the call to :cfunc:`Py_Initialize`. On most systems (in particular, on Unix and Windows, although the details are slightly different), :cfunc:`Py_Initialize` calculates the module search path From python-checkins at python.org Fri Jun 11 02:36:33 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 11 Jun 2010 02:36:33 +0200 (CEST) Subject: [Python-checkins] r81883 - python/branches/py3k/Python/pythonrun.c Message-ID: <20100611003633.791BBEE984@mail.python.org> Author: victor.stinner Date: Fri Jun 11 02:36:33 2010 New Revision: 81883 Log: Issue #8965: initfsencoding() doesn't change the encoding on Mac OS X File system encoding have to be hardcoded to "utf-8" on Mac OS X. r81190 introduced a regression: the encoding was changed depending on the locale. Modified: python/branches/py3k/Python/pythonrun.c Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Fri Jun 11 02:36:33 2010 @@ -703,24 +703,26 @@ #if defined(HAVE_LANGINFO_H) && defined(CODESET) char *codeset; - /* On Unix, set the file system encoding according to the - user's preference, if the CODESET names a well-known - Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - codeset = get_codeset(); - if (codeset != NULL) { - Py_FileSystemDefaultEncoding = codeset; - Py_HasFileSystemDefaultEncoding = 0; - return; - } + if (Py_FileSystemDefaultEncoding == NULL) { + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. Also set the encoding of + stdin and stdout if these are terminals. */ + codeset = get_codeset(); + if (codeset != NULL) { + Py_FileSystemDefaultEncoding = codeset; + Py_HasFileSystemDefaultEncoding = 0; + return; + } - PyErr_Clear(); - fprintf(stderr, - "Unable to get the locale encoding: " - "fallback to utf-8\n"); - Py_FileSystemDefaultEncoding = "utf-8"; - Py_HasFileSystemDefaultEncoding = 1; + PyErr_Clear(); + fprintf(stderr, + "Unable to get the locale encoding: " + "fallback to utf-8\n"); + Py_FileSystemDefaultEncoding = "utf-8"; + Py_HasFileSystemDefaultEncoding = 1; + } #endif /* the encoding is mbcs, utf-8 or ascii */ From python-checkins at python.org Fri Jun 11 02:39:31 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 11 Jun 2010 02:39:31 +0200 (CEST) Subject: [Python-checkins] r81884 - python/branches/release31-maint Message-ID: <20100611003931.8B373EE984@mail.python.org> Author: victor.stinner Date: Fri Jun 11 02:39:31 2010 New Revision: 81884 Log: Blocked revisions 81883 via svnmerge ........ r81883 | victor.stinner | 2010-06-11 02:36:33 +0200 (ven., 11 juin 2010) | 5 lines Issue #8965: initfsencoding() doesn't change the encoding on Mac OS X File system encoding have to be hardcoded to "utf-8" on Mac OS X. r81190 introduced a regression: the encoding was changed depending on the locale. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Jun 11 02:41:42 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 11 Jun 2010 02:41:42 +0200 (CEST) Subject: [Python-checkins] r81885 - python/branches/py3k/Lib/test/test_sys.py Message-ID: <20100611004142.0AD24EE984@mail.python.org> Author: victor.stinner Date: Fri Jun 11 02:41:41 2010 New Revision: 81885 Log: test_sys: add a test on the file system encoding for darwin Modified: python/branches/py3k/Lib/test/test_sys.py Modified: python/branches/py3k/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k/Lib/test/test_sys.py (original) +++ python/branches/py3k/Lib/test/test_sys.py Fri Jun 11 02:41:41 2010 @@ -863,6 +863,11 @@ # sys.flags check(sys.flags, size(vh) + self.P * len(sys.flags)) + def test_getfilesystemencoding(self): + fs_encoding = sys.getfilesystemencoding() + if sys.platform == 'darwin': + self.assertEqual(fs_encoding, 'utf-8') + def test_setfilesystemencoding(self): old = sys.getfilesystemencoding() try: From python-checkins at python.org Fri Jun 11 02:42:37 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 11 Jun 2010 02:42:37 +0200 (CEST) Subject: [Python-checkins] r81886 - python/branches/release31-maint Message-ID: <20100611004237.04C9EEE984@mail.python.org> Author: victor.stinner Date: Fri Jun 11 02:42:36 2010 New Revision: 81886 Log: Blocked revisions 81885 via svnmerge ........ r81885 | victor.stinner | 2010-06-11 02:41:41 +0200 (ven., 11 juin 2010) | 2 lines test_sys: add a test on the file system encoding for darwin ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Jun 11 03:07:06 2010 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 11 Jun 2010 03:07:06 +0200 (CEST) Subject: [Python-checkins] r81887 - python/branches/release26-maint/Doc/whatsnew/2.6.rst Message-ID: <20100611010706.40208F15A@mail.python.org> Author: andrew.kuchling Date: Fri Jun 11 03:07:06 2010 New Revision: 81887 Log: #5753: mention PySys_SetArgvEx() in 2.6 What's News Modified: python/branches/release26-maint/Doc/whatsnew/2.6.rst Modified: python/branches/release26-maint/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/release26-maint/Doc/whatsnew/2.6.rst (original) +++ python/branches/release26-maint/Doc/whatsnew/2.6.rst Fri Jun 11 03:07:06 2010 @@ -1788,7 +1788,7 @@ were applied. (Maintained by Josiah Carlson; see :issue:`1736190` for one patch.) -* The :mod:`bsddb` module also has a new maintainer, Jes?s Cea, and the package +* The :mod:`bsddb` module also has a new maintainer, Jes?s Cea Avion, and the package is now available as a standalone package. The web page for the package is `www.jcea.es/programacion/pybsddb.htm `__. @@ -2992,6 +2992,33 @@ architectures (x86, PowerPC), 64-bit (x86-64 and PPC-64), or both. (Contributed by Ronald Oussoren.) +* A new function added in Python 2.6.6, :cfunc:`PySys_SetArgvEx`, sets + the value of ``sys.argv`` and can optionally update ``sys.path`` to + include the directory containing the script named by ``sys.argv[0]`` + depending on the value of an *updatepath* parameter. + + This function was added to close a security hole for applications + that embed Python. The old function, :cfunc:`PySys_SetArgv`, would + always update ``sys.path``, and sometimes it would add the current + directory. This meant that, if you ran an application embedding + Python in a directory controlled by someone else, attackers could + put a Trojan-horse module in the directory (say, a file named + :file:`os.py`) that your application would then import and run. + + If you maintain a C/C++ application that embeds Python, check + whether you're calling :cfunc:`PySys_SetArgv` and carefully consider + whether the application should be using :cfunc:`PySys_SetArgvEx` + with *updatepath* set to false. Note that using this function will + break compatibility with Python versions 2.6.5 and earlier; if you + have to continue working with earlier versions, you can leave + the call to :cfunc:`PySys_SetArgv` alone and call + ``PyRun_SimpleString("sys.path.pop(0)\n")`` afterwards to discard + the first ``sys.path`` component. + + Security issue reported as `CVE-2008-5983 + `_; + discussed in :issue:`5753`, and fixed by Antoine Pitrou. + * The BerkeleyDB module now has a C API object, available as ``bsddb.db.api``. This object can be used by other C extensions that wish to use the :mod:`bsddb` module for their own purposes. @@ -3294,6 +3321,15 @@ scoping rules, also cause warnings because such comparisons are forbidden entirely in 3.0. +For applications that embed Python: + +* The :cfunc:`PySys_SetArgvEx` function was added in Python 2.6.6, + letting applications close a security hole when the existing + :cfunc:`PySys_SetArgv` function was used. Check whether you're + calling :cfunc:`PySys_SetArgv` and carefully consider whether the + application should be using :cfunc:`PySys_SetArgvEx` with + *updatepath* set to false. + .. ====================================================================== From python-checkins at python.org Fri Jun 11 03:54:58 2010 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 11 Jun 2010 03:54:58 +0200 (CEST) Subject: [Python-checkins] r81888 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: <20100611015458.3520BCA1C@mail.python.org> Author: andrew.kuchling Date: Fri Jun 11 03:54:58 2010 New Revision: 81888 Log: Add a few more items Modified: python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Fri Jun 11 03:54:58 2010 @@ -722,6 +722,10 @@ Integer division is also more accurate in its rounding behaviours. (Also implemented by Mark Dickinson; :issue:`1811`.) +* Implicit coercion for complex numbers has been removed; the interpreter + will no longer ever attempt to call a :meth:`__coerce__` method on complex + objects. (Removed by Meador Inge and Mark Dickinson; :issue:`5211`.) + * 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:: @@ -1102,6 +1106,10 @@ statement, has been deprecated, because the :keyword:`with` statement now supports multiple context managers. +* The :mod:`cookielib` module now ignores cookies that have an invalid + version field, one that doesn't contain an integer value. (Fixed by + John J. Lee; :issue:`3924`.) + * The :mod:`copy` module's :func:`~copy.deepcopy` function will now correctly copy bound instance methods. (Implemented by Robert Collins; :issue:`1515`.) @@ -2073,6 +2081,28 @@ :cfunc:`PyOS_ascii_strtod` and :cfunc:`PyOS_ascii_atof` functions are now deprecated. +* New function: :cfunc:`PySys_SetArgvEx` sets the value of + ``sys.argv`` and can optionally update ``sys.path`` to include the + directory containing the script named by ``sys.argv[0]`` depending + on the value of an *updatepath* parameter. + + This function was added to close a security hole for applications + that embed Python. The old function, :cfunc:`PySys_SetArgv`, would + always update ``sys.path``, and sometimes it would add the current + directory. This meant that, if you ran an application embedding + Python in a directory controlled by someone else, attackers could + put a Trojan-horse module in the directory (say, a file named + :file:`os.py`) that your application would then import and run. + + If you maintain a C/C++ application that embeds Python, check + whether you're calling :cfunc:`PySys_SetArgv` and carefully consider + whether the application should be using :cfunc:`PySys_SetArgvEx` + with *updatepath* set to false. + + Security issue reported as `CVE-2008-5983 + `_; + discussed in :issue:`5753`, and fixed by Antoine Pitrou. + * New macros: the Python header files now define the following macros: :cmacro:`Py_ISALNUM`, :cmacro:`Py_ISALPHA`, @@ -2281,6 +2311,10 @@ thread switching latency, and IO processing bandwidth when performing several tasks using a varying number of threads. +* The :file:`Tools/i18n/msgfmt.py` script now understands plural + forms in :file:`.po` files. (Fixed by Martin von L?wis; + :issue:`5464`.) + * When importing a module from a :file:`.pyc` or :file:`.pyo` file with an existing :file:`.py` counterpart, the :attr:`co_filename` attributes of the resulting code objects are overwritten when the @@ -2415,6 +2449,14 @@ :cfunc:`PyOS_ascii_strtod` and :cfunc:`PyOS_ascii_atof` functions, which are now deprecated. +For applications that embed Python: + +* The :cfunc:`PySys_SetArgvEx` function was added, letting + applications close a security hole when the existing + :cfunc:`PySys_SetArgv` function was used. Check whether you're + calling :cfunc:`PySys_SetArgv` and carefully consider whether the + application should be using :cfunc:`PySys_SetArgvEx` with + *updatepath* set to false. .. ====================================================================== From python-checkins at python.org Fri Jun 11 04:21:25 2010 From: python-checkins at python.org (ezio.melotti) Date: Fri, 11 Jun 2010 04:21:25 +0200 (CEST) Subject: [Python-checkins] r81889 - python/trunk/Modules/itertoolsmodule.c Message-ID: <20100611022125.8D0A5EC79@mail.python.org> Author: ezio.melotti Date: Fri Jun 11 04:21:25 2010 New Revision: 81889 Log: Remove extra ] from itertools.count docstring. Modified: python/trunk/Modules/itertoolsmodule.c Modified: python/trunk/Modules/itertoolsmodule.c ============================================================================== --- python/trunk/Modules/itertoolsmodule.c (original) +++ python/trunk/Modules/itertoolsmodule.c Fri Jun 11 04:21:25 2010 @@ -3392,7 +3392,7 @@ }; PyDoc_STRVAR(count_doc, - "count(start=0, step=1]) --> count object\n\ + "count(start=0, step=1) --> count object\n\ \n\ Return a count object whose .next() method returns consecutive values.\n\ Equivalent to:\n\n\ From python-checkins at python.org Fri Jun 11 04:24:59 2010 From: python-checkins at python.org (ezio.melotti) Date: Fri, 11 Jun 2010 04:24:59 +0200 (CEST) Subject: [Python-checkins] r81890 - python/branches/release26-maint Message-ID: <20100611022459.C5AB9EC79@mail.python.org> Author: ezio.melotti Date: Fri Jun 11 04:24:59 2010 New Revision: 81890 Log: Blocked revisions 81889 via svnmerge ........ r81889 | ezio.melotti | 2010-06-11 05:21:25 +0300 (Fri, 11 Jun 2010) | 1 line Remove extra ] from itertools.count docstring. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Jun 11 04:26:43 2010 From: python-checkins at python.org (ezio.melotti) Date: Fri, 11 Jun 2010 04:26:43 +0200 (CEST) Subject: [Python-checkins] r81891 - in python/branches/py3k: Modules/itertoolsmodule.c Message-ID: <20100611022643.189ACED8F@mail.python.org> Author: ezio.melotti Date: Fri Jun 11 04:26:42 2010 New Revision: 81891 Log: Merged revisions 81889 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81889 | ezio.melotti | 2010-06-11 05:21:25 +0300 (Fri, 11 Jun 2010) | 1 line Remove extra ] from itertools.count docstring. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/itertoolsmodule.c Modified: python/branches/py3k/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/itertoolsmodule.c (original) +++ python/branches/py3k/Modules/itertoolsmodule.c Fri Jun 11 04:26:42 2010 @@ -3066,7 +3066,7 @@ }; PyDoc_STRVAR(count_doc, - "count(start=0, step=1]) --> count object\n\ + "count(start=0, step=1) --> count object\n\ \n\ Return a count object whose .__next__() method returns consecutive values.\n\ Equivalent to:\n\n\ From python-checkins at python.org Fri Jun 11 04:28:37 2010 From: python-checkins at python.org (ezio.melotti) Date: Fri, 11 Jun 2010 04:28:37 +0200 (CEST) Subject: [Python-checkins] r81892 - in python/branches/release31-maint: Modules/itertoolsmodule.c Message-ID: <20100611022837.37D53ED8F@mail.python.org> Author: ezio.melotti Date: Fri Jun 11 04:28:37 2010 New Revision: 81892 Log: Merged revisions 81891 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81891 | ezio.melotti | 2010-06-11 05:26:42 +0300 (Fri, 11 Jun 2010) | 9 lines Merged revisions 81889 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81889 | ezio.melotti | 2010-06-11 05:21:25 +0300 (Fri, 11 Jun 2010) | 1 line Remove extra ] from itertools.count docstring. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Modules/itertoolsmodule.c Modified: python/branches/release31-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release31-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release31-maint/Modules/itertoolsmodule.c Fri Jun 11 04:28:37 2010 @@ -3066,7 +3066,7 @@ }; PyDoc_STRVAR(count_doc, - "count(start=0, step=1]) --> count object\n\ + "count(start=0, step=1) --> count object\n\ \n\ Return a count object whose .__next__() method returns consecutive values.\n\ Equivalent to:\n\n\ From python-checkins at python.org Fri Jun 11 12:44:52 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 12:44:52 +0200 (CEST) Subject: [Python-checkins] r81893 - in python/branches/py3k: Doc/library/decimal.rst Lib/decimal.py Lib/test/test_fractions.py Lib/test/test_numeric_tower.py Misc/NEWS Message-ID: <20100611104452.EA206EB03@mail.python.org> Author: mark.dickinson Date: Fri Jun 11 12:44:52 2010 New Revision: 81893 Log: Issue #8118: Comparisons between Decimal objects and other numeric objects (Fraction, float, complex, int) now all function as expected. Modified: python/branches/py3k/Doc/library/decimal.rst python/branches/py3k/Lib/decimal.py python/branches/py3k/Lib/test/test_fractions.py python/branches/py3k/Lib/test/test_numeric_tower.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k/Doc/library/decimal.rst (original) +++ python/branches/py3k/Doc/library/decimal.rst Fri Jun 11 12:44:52 2010 @@ -363,23 +363,17 @@ compared, sorted, and coerced to another type (such as :class:`float` or :class:`int`). - Decimal objects cannot generally be combined with floats in - arithmetic operations: an attempt to add a :class:`Decimal` to a - :class:`float`, for example, will raise a :exc:`TypeError`. - There's one exception to this rule: it's possible to use Python's - comparison operators to compare a :class:`float` instance ``x`` - with a :class:`Decimal` instance ``y``. Without this exception, - comparisons between :class:`Decimal` and :class:`float` instances - would follow the general rules for comparing objects of different - types described in the :ref:`expressions` section of the reference - manual, leading to confusing results. + Decimal objects cannot generally be combined with floats or + instances of :class:`fractions.Fraction` in arithmetic operations: + an attempt to add a :class:`Decimal` to a :class:`float`, for + example, will raise a :exc:`TypeError`. However, it is possible to + use Python's comparison operators to compare a :class:`Decimal` + instance ``x`` with another number ``y``. This avoids confusing results + when doing equality comparisons between numbers of different types. .. versionchanged:: 3.2 - A comparison between a :class:`float` instance ``x`` and a - :class:`Decimal` instance ``y`` now returns a result based on - the values of ``x`` and ``y``. In earlier versions ``x < y`` - returned the same (arbitrary) result for any :class:`Decimal` - instance ``x`` and any :class:`float` instance ``y``. + Mixed-type comparisons between :class:`Decimal` instances and + other numeric types are now fully supported. In addition to the standard numeric properties, decimal floating point objects also have a number of specialized methods: Modified: python/branches/py3k/Lib/decimal.py ============================================================================== --- python/branches/py3k/Lib/decimal.py (original) +++ python/branches/py3k/Lib/decimal.py Fri Jun 11 12:44:52 2010 @@ -862,7 +862,7 @@ # that specified by IEEE 754. def __eq__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other, equality_op=True) if other is NotImplemented: return other if self._check_nans(other, context): @@ -870,7 +870,7 @@ return self._cmp(other) == 0 def __ne__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other, equality_op=True) if other is NotImplemented: return other if self._check_nans(other, context): @@ -879,7 +879,7 @@ def __lt__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -888,7 +888,7 @@ return self._cmp(other) < 0 def __le__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -897,7 +897,7 @@ return self._cmp(other) <= 0 def __gt__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -906,7 +906,7 @@ return self._cmp(other) > 0 def __ge__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -5860,6 +5860,37 @@ raise TypeError("Unable to convert %s to Decimal" % other) return NotImplemented +def _convert_for_comparison(self, other, equality_op=False): + """Given a Decimal instance self and a Python object other, return + an pair (s, o) of Decimal instances such that "s op o" is + equivalent to "self op other" for any of the 6 comparison + operators "op". + + """ + if isinstance(other, Decimal): + return self, other + + # Comparison with a Rational instance (also includes integers): + # self op n/d <=> self*d op n (for n and d integers, d positive). + # A NaN or infinity can be left unchanged without affecting the + # comparison result. + if isinstance(other, _numbers.Rational): + if not self._is_special: + self = _dec_from_triple(self._sign, + str(int(self._int) * other.denominator), + self._exp) + return self, Decimal(other.numerator) + + # Comparisons with float and complex types. == and != comparisons + # with complex numbers should succeed, returning either True or False + # as appropriate. Other comparisons return NotImplemented. + if equality_op and isinstance(other, _numbers.Complex) and other.imag == 0: + other = other.real + if isinstance(other, float): + return self, Decimal.from_float(other) + return NotImplemented, NotImplemented + + ##### Setup Specific Contexts ############################################ # The default context prototype used by Context() Modified: python/branches/py3k/Lib/test/test_fractions.py ============================================================================== --- python/branches/py3k/Lib/test/test_fractions.py (original) +++ python/branches/py3k/Lib/test/test_fractions.py Fri Jun 11 12:44:52 2010 @@ -395,12 +395,11 @@ self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10)) def testMixingWithDecimal(self): - # Decimal refuses mixed comparisons. + # Decimal refuses mixed arithmetic (but not mixed comparisons) self.assertRaisesMessage( TypeError, "unsupported operand type(s) for +: 'Fraction' and 'Decimal'", operator.add, F(3,11), Decimal('3.1415926')) - self.assertNotEquals(F(5, 2), Decimal('2.5')) def testComparisons(self): self.assertTrue(F(1, 2) < F(2, 3)) Modified: python/branches/py3k/Lib/test/test_numeric_tower.py ============================================================================== --- python/branches/py3k/Lib/test/test_numeric_tower.py (original) +++ python/branches/py3k/Lib/test/test_numeric_tower.py Fri Jun 11 12:44:52 2010 @@ -143,9 +143,64 @@ x = {'halibut', HalibutProxy()} self.assertEqual(len(x), 1) +class ComparisonTest(unittest.TestCase): + def test_mixed_comparisons(self): + + # ordered list of distinct test values of various types: + # int, float, Fraction, Decimal + test_values = [ + float('-inf'), + D('-1e999999999'), + -1e308, + F(-22, 7), + -3.14, + -2, + 0.0, + 1e-320, + True, + F('1.2'), + D('1.3'), + float('1.4'), + F(275807, 195025), + D('1.414213562373095048801688724'), + F(114243, 80782), + F(473596569, 84615), + 7e200, + D('infinity'), + ] + for i, first in enumerate(test_values): + for second in test_values[i+1:]: + self.assertLess(first, second) + self.assertLessEqual(first, second) + self.assertGreater(second, first) + self.assertGreaterEqual(second, first) + + def test_complex(self): + # comparisons with complex are special: equality and inequality + # comparisons should always succeed, but order comparisons should + # raise TypeError. + z = 1.0 + 0j + w = -3.14 + 2.7j + + for v in 1, 1.0, F(1), D(1), complex(1): + self.assertEqual(z, v) + self.assertEqual(v, z) + + for v in 2, 2.0, F(2), D(2), complex(2): + self.assertNotEqual(z, v) + self.assertNotEqual(v, z) + self.assertNotEqual(w, v) + self.assertNotEqual(v, w) + + for v in (1, 1.0, F(1), D(1), complex(1), + 2, 2.0, F(2), D(2), complex(2), w): + for op in operator.le, operator.lt, operator.ge, operator.gt: + self.assertRaises(TypeError, op, z, v) + self.assertRaises(TypeError, op, v, z) + def test_main(): - run_unittest(HashTest) + run_unittest(HashTest, ComparisonTest) if __name__ == '__main__': test_main() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 11 12:44:52 2010 @@ -417,6 +417,13 @@ Library ------- +- Issue #8118: Comparisons between Decimal and Fraction objects are + now permitted, returning a result based on the exact numerical + values of the operands. This builds on issue #2531, which allowed + Decimal-to-float comparisons; all comparisons involving numeric + types (bool, int, float, complex, Decimal, Fraction) should now + act as expected. + - Issue #8897: Fix sunau module, use bytes to write the header. Patch written by Thomas Jollans. @@ -714,7 +721,8 @@ - Issue #2531: Comparison operations between floats and Decimal instances now return a result based on the numeric values of the operands; previously they returned an arbitrary result based on - the relative ordering of id(float) and id(Decimal). + the relative ordering of id(float) and id(Decimal). See also + issue #8118, which adds Decimal-to-Fraction comparisons. - Added a subtract() method to collections.Counter(). From python-checkins at python.org Fri Jun 11 12:46:57 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 12:46:57 +0200 (CEST) Subject: [Python-checkins] r81894 - python/branches/py3k/Misc/NEWS Message-ID: <20100611104657.EFF96EEA2@mail.python.org> Author: mark.dickinson Date: Fri Jun 11 12:46:57 2010 New Revision: 81894 Log: Fix issue number typo. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 11 12:46:57 2010 @@ -417,7 +417,7 @@ Library ------- -- Issue #8118: Comparisons between Decimal and Fraction objects are +- Issue #8188: Comparisons between Decimal and Fraction objects are now permitted, returning a result based on the exact numerical values of the operands. This builds on issue #2531, which allowed Decimal-to-float comparisons; all comparisons involving numeric @@ -722,7 +722,7 @@ instances now return a result based on the numeric values of the operands; previously they returned an arbitrary result based on the relative ordering of id(float) and id(Decimal). See also - issue #8118, which adds Decimal-to-Fraction comparisons. + issue #8188, which adds Decimal-to-Fraction comparisons. - Added a subtract() method to collections.Counter(). From python-checkins at python.org Fri Jun 11 12:50:14 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 12:50:14 +0200 (CEST) Subject: [Python-checkins] r81893 - svn:log Message-ID: <20100611105014.90612F037@mail.python.org> Author: mark.dickinson Revision: 81893 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1,2 +1,2 @@ -Issue #8118: Comparisons between Decimal objects and other numeric +Issue #8188: Comparisons between Decimal objects and other numeric objects (Fraction, float, complex, int) now all function as expected. From python-checkins at python.org Fri Jun 11 18:04:59 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 11 Jun 2010 18:04:59 +0200 (CEST) Subject: [Python-checkins] r81895 - in python/branches/py3k: Lib/test/test_struct.py Misc/NEWS Modules/_struct.c Message-ID: <20100611160459.C3BF3F0FC@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 11 18:04:59 2010 New Revision: 81895 Log: Issue #3129: Trailing digits in format string are no longer ignored. Modified: python/branches/py3k/Lib/test/test_struct.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Lib/test/test_struct.py ============================================================================== --- python/branches/py3k/Lib/test/test_struct.py (original) +++ python/branches/py3k/Lib/test/test_struct.py Fri Jun 11 18:04:59 2010 @@ -443,7 +443,7 @@ # Test bogus offset (issue 3694) sb = small_buf - self.assertRaises(TypeError, struct.pack_into, b'1', sb, None) + self.assertRaises(TypeError, struct.pack_into, b'', sb, None) def test_pack_into_fn(self): test_string = b'Reykjavik rocks, eow!' @@ -510,6 +510,32 @@ def test_crasher(self): self.assertRaises(MemoryError, struct.pack, "357913941b", "a") + def test_trailing_counter(self): + store = array.array('b', b' '*100) + + # format lists containing only count spec should result in an error + self.assertRaises(struct.error, struct.pack, '12345') + self.assertRaises(struct.error, struct.unpack, '12345', '') + self.assertRaises(struct.error, struct.pack_into, '12345', store, 0) + self.assertRaises(struct.error, struct.unpack_from, '12345', store, 0) + + # Format lists with trailing count spec should result in an error + self.assertRaises(struct.error, struct.pack, 'c12345', 'x') + self.assertRaises(struct.error, struct.unpack, 'c12345', 'x') + self.assertRaises(struct.error, struct.pack_into, 'c12345', store, 0, + 'x') + self.assertRaises(struct.error, struct.unpack_from, 'c12345', store, + 0) + + # Mixed format tests + self.assertRaises(struct.error, struct.pack, '14s42', 'spam and eggs') + self.assertRaises(struct.error, struct.unpack, '14s42', + 'spam and eggs') + self.assertRaises(struct.error, struct.pack_into, '14s42', store, 0, + 'spam and eggs') + self.assertRaises(struct.error, struct.unpack_from, '14s42', store, 0) + + def test_main(): run_unittest(StructTest) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 11 18:04:59 2010 @@ -1283,6 +1283,10 @@ Extension Modules ----------------- +- Issue #3129: Trailing digits in format string are no longer ignored. + For example, "1" or "ilib123" are now invalid formats and cause + ``struct.error`` to be raised. + - Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Fri Jun 11 18:04:59 2010 @@ -1195,8 +1195,11 @@ } num = x; } - if (c == '\0') - break; + if (c == '\0') { + PyErr_SetString(StructError, + "repeat count given without format specifier"); + return -1; + } } else num = 1; From alexander.belopolsky at gmail.com Fri Jun 11 18:36:46 2010 From: alexander.belopolsky at gmail.com (Alexander Belopolsky) Date: Fri, 11 Jun 2010 12:36:46 -0400 Subject: [Python-checkins] r81895 - in python/branches/py3k: Lib/test/test_struct.py Misc/NEWS Modules/_struct.c In-Reply-To: <20100611160459.C3BF3F0FC@mail.python.org> References: <20100611160459.C3BF3F0FC@mail.python.org> Message-ID: I goofed in log and NEWS entries (no mention of struct module). What's the cvs command to change a log entry? On Fri, Jun 11, 2010 at 12:04 PM, alexander.belopolsky wrote: > Author: alexander.belopolsky > Date: Fri Jun 11 18:04:59 2010 > New Revision: 81895 > > Log: > Issue #3129: Trailing digits in format string are no longer ignored. > > > Modified: > ? python/branches/py3k/Lib/test/test_struct.py > ? python/branches/py3k/Misc/NEWS > ? python/branches/py3k/Modules/_struct.c > > Modified: python/branches/py3k/Lib/test/test_struct.py > ============================================================================== > --- python/branches/py3k/Lib/test/test_struct.py ? ? ? ?(original) > +++ python/branches/py3k/Lib/test/test_struct.py ? ? ? ?Fri Jun 11 18:04:59 2010 > @@ -443,7 +443,7 @@ > > ? ? ? ? # Test bogus offset (issue 3694) > ? ? ? ? sb = small_buf > - ? ? ? ?self.assertRaises(TypeError, struct.pack_into, b'1', sb, None) > + ? ? ? ?self.assertRaises(TypeError, struct.pack_into, b'', sb, None) > > ? ? def test_pack_into_fn(self): > ? ? ? ? test_string = b'Reykjavik rocks, eow!' > @@ -510,6 +510,32 @@ > ? ? ? ? def test_crasher(self): > ? ? ? ? ? ? self.assertRaises(MemoryError, struct.pack, "357913941b", "a") > > + ? ?def test_trailing_counter(self): > + ? ? ? ?store = array.array('b', b' '*100) > + > + ? ? ? ?# format lists containing only count spec should result in an error > + ? ? ? ?self.assertRaises(struct.error, struct.pack, '12345') > + ? ? ? ?self.assertRaises(struct.error, struct.unpack, '12345', '') > + ? ? ? ?self.assertRaises(struct.error, struct.pack_into, '12345', store, 0) > + ? ? ? ?self.assertRaises(struct.error, struct.unpack_from, '12345', store, 0) > + > + ? ? ? ?# Format lists with trailing count spec should result in an error > + ? ? ? ?self.assertRaises(struct.error, struct.pack, 'c12345', 'x') > + ? ? ? ?self.assertRaises(struct.error, struct.unpack, 'c12345', 'x') > + ? ? ? ?self.assertRaises(struct.error, struct.pack_into, 'c12345', store, 0, > + ? ? ? ? ? ? ? ? ? ? ? ? ? 'x') > + ? ? ? ?self.assertRaises(struct.error, struct.unpack_from, 'c12345', store, > + ? ? ? ? ? ? ? ? ? ? ? ? ? 0) > + > + ? ? ? ?# Mixed format tests > + ? ? ? ?self.assertRaises(struct.error, struct.pack, '14s42', 'spam and eggs') > + ? ? ? ?self.assertRaises(struct.error, struct.unpack, '14s42', > + ? ? ? ? ? ? ? ? ? ? ? ? ?'spam and eggs') > + ? ? ? ?self.assertRaises(struct.error, struct.pack_into, '14s42', store, 0, > + ? ? ? ? ? ? ? ? ? ? ? ? ?'spam and eggs') > + ? ? ? ?self.assertRaises(struct.error, struct.unpack_from, '14s42', store, 0) > + > + > > ?def test_main(): > ? ? run_unittest(StructTest) > > Modified: python/branches/py3k/Misc/NEWS > ============================================================================== > --- python/branches/py3k/Misc/NEWS ? ? ?(original) > +++ python/branches/py3k/Misc/NEWS ? ? ?Fri Jun 11 18:04:59 2010 > @@ -1283,6 +1283,10 @@ > ?Extension Modules > ?----------------- > > +- Issue #3129: Trailing digits in format string are no longer ignored. > + ?For example, "1" or "ilib123" are now invalid formats and cause > + ?``struct.error`` to be raised. > + > ?- Issue #7384: If the system readline library is linked against ncurses, > ? the curses module must be linked against ncurses as well. Otherwise it > ? is not safe to load both the readline and curses modules in an application. > > Modified: python/branches/py3k/Modules/_struct.c > ============================================================================== > --- python/branches/py3k/Modules/_struct.c ? ? ?(original) > +++ python/branches/py3k/Modules/_struct.c ? ? ?Fri Jun 11 18:04:59 2010 > @@ -1195,8 +1195,11 @@ > ? ? ? ? ? ? ? ? } > ? ? ? ? ? ? ? ? num = x; > ? ? ? ? ? ? } > - ? ? ? ? ? ?if (c == '\0') > - ? ? ? ? ? ? ? ?break; > + ? ? ? ? ? ?if (c == '\0') { > + ? ? ? ? ? ? ? ?PyErr_SetString(StructError, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"repeat count given without format specifier"); > + ? ? ? ? ? ? ? ?return -1; > + ? ? ? ? ? ?} > ? ? ? ? } > ? ? ? ? else > ? ? ? ? ? ? num = 1; > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > From python-checkins at python.org Fri Jun 11 18:49:20 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 18:49:20 +0200 (CEST) Subject: [Python-checkins] r81896 - python/branches/py3k/Lib/decimal.py Message-ID: <20100611164920.58F66ED9F@mail.python.org> Author: mark.dickinson Date: Fri Jun 11 18:49:20 2010 New Revision: 81896 Log: Fix typo in docstring. Modified: python/branches/py3k/Lib/decimal.py Modified: python/branches/py3k/Lib/decimal.py ============================================================================== --- python/branches/py3k/Lib/decimal.py (original) +++ python/branches/py3k/Lib/decimal.py Fri Jun 11 18:49:20 2010 @@ -5862,7 +5862,7 @@ def _convert_for_comparison(self, other, equality_op=False): """Given a Decimal instance self and a Python object other, return - an pair (s, o) of Decimal instances such that "s op o" is + a pair (s, o) of Decimal instances such that "s op o" is equivalent to "self op other" for any of the 6 comparison operators "op". From python-checkins at python.org Fri Jun 11 18:56:34 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 18:56:34 +0200 (CEST) Subject: [Python-checkins] r81897 - in python/branches/py3k: Lib/test/test_struct.py Modules/_struct.c Message-ID: <20100611165634.8E37AF76A@mail.python.org> Author: mark.dickinson Date: Fri Jun 11 18:56:34 2010 New Revision: 81897 Log: Avoid possible undefined behaviour from signed overflow. Modified: python/branches/py3k/Lib/test/test_struct.py python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Lib/test/test_struct.py ============================================================================== --- python/branches/py3k/Lib/test/test_struct.py (original) +++ python/branches/py3k/Lib/test/test_struct.py Fri Jun 11 18:56:34 2010 @@ -506,6 +506,11 @@ for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']: self.assertTrue(struct.unpack('>?', c)[0]) + def test_count_overflow(self): + hugecount = '{}b'.format(sys.maxsize+1) + self.assertRaises(struct.error, struct.calcsize, hugecount) + + if IS32BIT: def test_crasher(self): self.assertRaises(MemoryError, struct.pack, "357913941b", "a") Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Fri Jun 11 18:56:34 2010 @@ -1186,14 +1186,17 @@ if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { - x = num*10 + (c - '0'); - if (x/10 != num) { + /* overflow-safe version of + if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ + if (num >= PY_SSIZE_T_MAX / 10 && ( + num > PY_SSIZE_T_MAX / 10 || + (c - '0') > PY_SSIZE_T_MAX % 10)) { PyErr_SetString( StructError, "overflow in item count"); return -1; } - num = x; + num = num*10 + (c - '0'); } if (c == '\0') { PyErr_SetString(StructError, From amk at amk.ca Fri Jun 11 19:16:50 2010 From: amk at amk.ca (A.M. Kuchling) Date: Fri, 11 Jun 2010 13:16:50 -0400 Subject: [Python-checkins] r81895 - in python/branches/py3k: Lib/test/test_struct.py Misc/NEWS Modules/_struct.c In-Reply-To: References: <20100611160459.C3BF3F0FC@mail.python.org> Message-ID: <20100611171650.GA5056@amk-desktop.matrixgroup.net> On Fri, Jun 11, 2010 at 12:36:46PM -0400, Alexander Belopolsky wrote: > I goofed in log and NEWS entries (no mention of struct module). > What's the cvs command to change a log entry? >From http://www.python.org/dev/faq/#how-can-i-edit-the-log-message-of-a-committed-revision Use: svn propedit -r --revprop svn:log Replace with the revision number of the commit whose log message you wish to change. --amk From python-checkins at python.org Fri Jun 11 21:05:08 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 21:05:08 +0200 (CEST) Subject: [Python-checkins] r81898 - python/branches/py3k/Modules/_struct.c Message-ID: <20100611190508.34B55EE9CB@mail.python.org> Author: mark.dickinson Date: Fri Jun 11 21:05:08 2010 New Revision: 81898 Log: Fix an incorrect return type. Modified: python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Fri Jun 11 21:05:08 2010 @@ -1145,7 +1145,7 @@ /* Align a size according to a format code */ -static int +static Py_ssize_t align(Py_ssize_t size, char c, const formatdef *e) { if (e->format == c) { From python-checkins at python.org Fri Jun 11 21:22:28 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 11 Jun 2010 21:22:28 +0200 (CEST) Subject: [Python-checkins] r81899 - in python/trunk/Misc: NEWS maintainers.rst Message-ID: <20100611192228.EA749EE98D@mail.python.org> Author: victor.stinner Date: Fri Jun 11 21:22:28 2010 New Revision: 81899 Log: Issue #8362: Add Misc/maintainers.rst: list of module maintainers Added: python/trunk/Misc/maintainers.rst Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Jun 11 21:22:28 2010 @@ -27,6 +27,11 @@ - Issues #8909: Added the size of the bitmap used in the installer created by distutils' bdist_wininst. Patch by Anatoly Techtonik. +Misc +---- + +- Issue #8362: Add maintainers.rst: list of module maintainers + What's New in Python 2.7 Release Candidate 1? ============================================= @@ -70,7 +75,7 @@ - Issue #7079: Fix a possible crash when closing a file object while using it from another thread. Patch by Daniel Stutzbach. -- Issue #8868: Fix that ensures that python scripts have access to the +- Issue #8868: Fix that ensures that python scripts have access to the Window Server again in a framework build on MacOSX 10.5 or earlier. C-API @@ -175,7 +180,7 @@ - Display installer warning that Windows 2000 won't be supported in future releases. -- Issues #1759169, #8864: Drop _XOPEN_SOURCE on Solaris, define it for +- Issues #1759169, #8864: Drop _XOPEN_SOURCE on Solaris, define it for multiprocessing only. Tools/Demos Added: python/trunk/Misc/maintainers.rst ============================================================================== --- (empty file) +++ python/trunk/Misc/maintainers.rst Fri Jun 11 21:22:28 2010 @@ -0,0 +1,300 @@ +Maintainers Index +================= + +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 +in this list by placing the word 'inactive' in parenthesis behind their +tracker id. They are of course free to remove that inactive mark at +any time. + +Committers should update this table as their areas of expertise widen. +New topics may be added to the third table at will. + +The existence of this list is not meant to indicate that these people +*must* be contacted for decisions; it is, rather, a resource to be used +by non-committers to find responsible parties, and by committers who do +not feel qualified to make a decision in a particular context. + +See also `PEP 291`_ and `PEP 360`_ for information about certain modules +with special rules. + +.. _`PEP 291`: http://www.python.org/dev/peps/pep-0291/ +.. _`PEP 360`: http://www.python.org/dev/peps/pep-0360/ + + +================== =========== +Module Maintainers +================== =========== +__builtin__ +__future__ +__main__ gvanrossum +_dummy_thread brett.cannon +_thread +abc +aifc r.david.murray +argparse bethard +array +ast +asynchat josiahcarlson, giampaolo.rodola +asyncore josiahcarlson, giampaolo.rodola +atexit +audioop +base64 +BaseHTTPServer +bdb +binascii +binhex +bisect rhettinger +bz2 +calendar +cgi +CGIHTTPServer +cgitb +chunk +cmath mark.dickinson +cmd +code +codecs lemburg, doerwalter +codeop +collections rhettinger +colorsys +compileall +ConfigParser +contextlib +copy alexandre.vassalotti +copy_reg alexandre.vassalotti +cProfile +crypt +csv +ctypes theller +curses andrew.kuchling +datetime alexander.belopolsky +dbm +decimal facundobatista, rhettinger, mark.dickinson +difflib tim_one +dis +distutils tarek +doctest tim_one (inactive) +dummy_threading brett.cannon +email barry, r.david.murray +encodings lemburg, loewis +errno +exceptions +fcntl +filecmp +fileinput +fnmatch +formatter +fpectl +fractions mark.dickinson, rhettinger +ftplib giampaolo.rodola +functools +gc pitrou +getopt +getpass +gettext loewis +glob +grp +gzip +hashlib +heapq rhettinger +hmac +htmlentitydefs +htmllib +HTMLParser +httplib +idlelib kbk +imaplib +imghdr +imp +importlib brett.cannon +inspect +io pitrou, benjamin.peterson +itertools rhettinger +json bob.ippolito (inactive) +keyword +lib2to3 benjamin.peterson +linecache +locale loewis, lemburg +logging vsajip +macpath +mailbox andrew.kuchling +mailcap +marshal +math mark.dickinson, rhettinger +mimetypes +mmap +modulefinder theller, jvr +msilib loewis +msvcrt +multiprocessing jnoller +netrc +nis +nntplib +numbers +operator +optparse aronacher +os loewis +ossaudiodev +parser +pdb +pickle alexandre.vassalotti, pitrou +pickletools alexandre.vassalotti +pipes +pkgutil +platform lemburg +plistlib +poplib +posix +pprint fdrake +pstats +pty +pwd +py_compile +pybench lemburg, pitrou +pyclbr +pydoc +Queue rhettinger +quopri +random rhettinger +re effbot (inactive), pitrou +readline +reprlib +resource +rlcompleter +runpy ncoghlan +sched +select +shelve +shlex +shutil tarek +signal +SimpleHTTPServer +site +smtpd +smtplib +sndhdr +socket +SocketServer +spwd +sqlite3 ghaering +ssl janssen, pitrou, giampaolo.rodola +stat +string +stringprep +struct mark.dickinson +subprocess astrand (inactive) +sunau +symbol +symtable benjamin.peterson +sys +sysconfig tarek +syslog jafo +tabnanny tim_one +tarfile lars.gustaebel +telnetlib +tempfile +termios +test +textwrap +threading +time alexander.belopolsky +timeit +Tkinter gpolo +token georg.brandl +tokenize +trace +traceback georg.brandl +tty +turtle gregorlingl +types +unicodedata loewis, lemburg, ezio.melotti +unittest michael.foord +urllib orsenthil +uu +uuid +warnings brett.cannon +wave +weakref fdrake +webbrowser georg.brandl +winreg +winsound effbot (inactive) +wsgiref pje +xdrlib +xml loewis +xml.etree effbot (inactive) +xmlrpc loewis +zipfile +zipimport +zlib +================== =========== + + +================== =========== +Tool Maintainers +------------------ ----------- +pybench lemburg + + +================== =========== +Platform Maintainers +------------------ ----------- +AIX +Cygwin jlt63 +FreeBSD +HP-UX +Linux +Mac ronaldoussoren +NetBSD1 +OS2/EMX aimacintyre +Solaris +Windows +================== =========== + + +================== =========== +Interest Area Maintainers +------------------ ----------- +algorithms +ast/compiler ncoghlan, benjamin.peterson, brett.cannon, georg.brandl +autoconf/makefiles +bsd +buildbots +bytecode pitrou +data formats mark.dickinson, georg.brandl +database lemburg +documentation georg.brandl, ezio.melotti +GUI +i18n lemburg +import machinery brett.cannon, ncoghlan +io pitrou, benjamin.peterson +locale lemburg, loewis +mathematics mark.dickinson, eric.smith, lemburg +memory management tim_one, lemburg +networking giampaolo.rodola +packaging tarek, lemburg +py3 transition benjamin.peterson +release management tarek, lemburg, benjamin.peterson, barry, loewis, + gvanrossum, anthonybaxter +str.format eric.smith +time and dates lemburg +testing michael.foord, pitrou, giampaolo.rodola +threads +tracker +unicode lemburg, ezio.melotti, haypo +version control +================== =========== From python-checkins at python.org Fri Jun 11 21:24:20 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 11 Jun 2010 21:24:20 +0200 (CEST) Subject: [Python-checkins] r81900 - python/branches/release26-maint Message-ID: <20100611192420.9A06CEE9D1@mail.python.org> Author: victor.stinner Date: Fri Jun 11 21:24:20 2010 New Revision: 81900 Log: Blocked revisions 81899 via svnmerge ........ r81899 | victor.stinner | 2010-06-11 21:22:28 +0200 (ven., 11 juin 2010) | 2 lines Issue #8362: Add Misc/maintainers.rst: list of module maintainers ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Jun 11 21:24:36 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 11 Jun 2010 21:24:36 +0200 (CEST) Subject: [Python-checkins] r81901 - python/branches/py3k Message-ID: <20100611192436.DD2E9C998@mail.python.org> Author: victor.stinner Date: Fri Jun 11 21:24:36 2010 New Revision: 81901 Log: Blocked revisions 81899 via svnmerge ........ r81899 | victor.stinner | 2010-06-11 21:22:28 +0200 (ven., 11 juin 2010) | 2 lines Issue #8362: Add Misc/maintainers.rst: list of module maintainers ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Fri Jun 11 21:50:30 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 21:50:30 +0200 (CEST) Subject: [Python-checkins] r81902 - in python/branches/py3k: Lib/test/test_struct.py Modules/_struct.c Message-ID: <20100611195030.4A87FEE98C@mail.python.org> Author: mark.dickinson Date: Fri Jun 11 21:50:30 2010 New Revision: 81902 Log: Fix more undefined-behaviour inducing overflow checks in struct module. Modified: python/branches/py3k/Lib/test/test_struct.py python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Lib/test/test_struct.py ============================================================================== --- python/branches/py3k/Lib/test/test_struct.py (original) +++ python/branches/py3k/Lib/test/test_struct.py Fri Jun 11 21:50:30 2010 @@ -510,6 +510,8 @@ hugecount = '{}b'.format(sys.maxsize+1) self.assertRaises(struct.error, struct.calcsize, hugecount) + hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2) + self.assertRaises(struct.error, struct.calcsize, hugecount2) if IS32BIT: def test_crasher(self): Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Fri Jun 11 21:50:30 2010 @@ -1143,16 +1143,19 @@ } -/* Align a size according to a format code */ +/* Align a size according to a format code. Return -1 on overflow. */ static Py_ssize_t align(Py_ssize_t size, char c, const formatdef *e) { + Py_ssize_t extra; + if (e->format == c) { - if (e->alignment) { - size = ((size + e->alignment - 1) - / e->alignment) - * e->alignment; + if (e->alignment && size > 0) { + extra = (e->alignment - 1) - (size - 1) % (e->alignment); + if (extra > PY_SSIZE_T_MAX - size) + return -1; + size += extra; } } return size; @@ -1171,7 +1174,7 @@ const char *s; const char *fmt; char c; - Py_ssize_t size, len, num, itemsize, x; + Py_ssize_t size, len, num, itemsize; fmt = PyBytes_AS_STRING(self->s_format); @@ -1190,12 +1193,8 @@ if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ if (num >= PY_SSIZE_T_MAX / 10 && ( num > PY_SSIZE_T_MAX / 10 || - (c - '0') > PY_SSIZE_T_MAX % 10)) { - PyErr_SetString( - StructError, - "overflow in item count"); - return -1; - } + (c - '0') > PY_SSIZE_T_MAX % 10)) + goto overflow; num = num*10 + (c - '0'); } if (c == '\0') { @@ -1220,13 +1219,13 @@ itemsize = e->size; size = align(size, c, e); - x = num * itemsize; - size += x; - if (x/itemsize != num || size < 0) { - PyErr_SetString(StructError, - "total struct size too long"); - return -1; - } + if (size == -1) + goto overflow; + + /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ + if (num > (PY_SSIZE_T_MAX - size) / itemsize) + goto overflow; + size += num * itemsize; } /* check for overflow */ @@ -1285,6 +1284,11 @@ codes->size = 0; return 0; + + overflow: + PyErr_SetString(StructError, + "total struct size too long"); + return -1; } static PyObject * From python-checkins at python.org Fri Jun 11 22:08:36 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 22:08:36 +0200 (CEST) Subject: [Python-checkins] r81903 - in python/branches/release31-maint: Lib/test/test_struct.py Modules/_struct.c Message-ID: <20100611200836.B831EEE98D@mail.python.org> Author: mark.dickinson Date: Fri Jun 11 22:08:36 2010 New Revision: 81903 Log: Merged revisions 81897-81898,81902 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81897 | mark.dickinson | 2010-06-11 17:56:34 +0100 (Fri, 11 Jun 2010) | 1 line Avoid possible undefined behaviour from signed overflow. ........ r81898 | mark.dickinson | 2010-06-11 20:05:08 +0100 (Fri, 11 Jun 2010) | 1 line Fix an incorrect return type. ........ r81902 | mark.dickinson | 2010-06-11 20:50:30 +0100 (Fri, 11 Jun 2010) | 1 line Fix more undefined-behaviour inducing overflow checks in struct module. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_struct.py python/branches/release31-maint/Modules/_struct.c Modified: python/branches/release31-maint/Lib/test/test_struct.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_struct.py (original) +++ python/branches/release31-maint/Lib/test/test_struct.py Fri Jun 11 22:08:36 2010 @@ -511,6 +511,13 @@ for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']: self.assertTrue(struct.unpack('>?', c)[0]) + def test_count_overflow(self): + hugecount = '{}b'.format(sys.maxsize+1) + self.assertRaises(struct.error, struct.calcsize, hugecount) + + hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2) + self.assertRaises(struct.error, struct.calcsize, hugecount2) + if IS32BIT: def test_crasher(self): self.assertRaises(MemoryError, struct.pack, "357913941b", "a") Modified: python/branches/release31-maint/Modules/_struct.c ============================================================================== --- python/branches/release31-maint/Modules/_struct.c (original) +++ python/branches/release31-maint/Modules/_struct.c Fri Jun 11 22:08:36 2010 @@ -1132,16 +1132,19 @@ } -/* Align a size according to a format code */ +/* Align a size according to a format code. Return -1 on overflow. */ -static int +static Py_ssize_t align(Py_ssize_t size, char c, const formatdef *e) { + Py_ssize_t extra; + if (e->format == c) { - if (e->alignment) { - size = ((size + e->alignment - 1) - / e->alignment) - * e->alignment; + if (e->alignment && size > 0) { + extra = (e->alignment - 1) - (size - 1) % (e->alignment); + if (extra > PY_SSIZE_T_MAX - size) + return -1; + size += extra; } } return size; @@ -1160,7 +1163,7 @@ const char *s; const char *fmt; char c; - Py_ssize_t size, len, num, itemsize, x; + Py_ssize_t size, len, num, itemsize; fmt = PyBytes_AS_STRING(self->s_format); @@ -1175,14 +1178,13 @@ if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { - x = num*10 + (c - '0'); - if (x/10 != num) { - PyErr_SetString( - StructError, - "overflow in item count"); - return -1; - } - num = x; + /* overflow-safe version of + if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ + if (num >= PY_SSIZE_T_MAX / 10 && ( + num > PY_SSIZE_T_MAX / 10 || + (c - '0') > PY_SSIZE_T_MAX % 10)) + goto overflow; + num = num*10 + (c - '0'); } if (c == '\0') break; @@ -1203,13 +1205,13 @@ itemsize = e->size; size = align(size, c, e); - x = num * itemsize; - size += x; - if (x/itemsize != num || size < 0) { - PyErr_SetString(StructError, - "total struct size too long"); - return -1; - } + if (size == -1) + goto overflow; + + /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ + if (num > (PY_SSIZE_T_MAX - size) / itemsize) + goto overflow; + size += num * itemsize; } /* check for overflow */ @@ -1268,6 +1270,11 @@ codes->size = 0; return 0; + + overflow: + PyErr_SetString(StructError, + "total struct size too long"); + return -1; } static PyObject * From python-checkins at python.org Fri Jun 11 22:27:06 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 22:27:06 +0200 (CEST) Subject: [Python-checkins] r81904 - in python/trunk: Lib/test/test_struct.py Modules/_struct.c Message-ID: <20100611202706.22904EE99B@mail.python.org> Author: mark.dickinson Date: Fri Jun 11 22:27:05 2010 New Revision: 81904 Log: Fix possible undefined behaviour from signed overflow in struct module. Backport of revisions 81897, 81898 and 81902 from py3k. Modified: python/trunk/Lib/test/test_struct.py python/trunk/Modules/_struct.c Modified: python/trunk/Lib/test/test_struct.py ============================================================================== --- python/trunk/Lib/test/test_struct.py (original) +++ python/trunk/Lib/test/test_struct.py Fri Jun 11 22:27:05 2010 @@ -526,6 +526,12 @@ def test_crasher(self): self.assertRaises(MemoryError, struct.pack, "357913941c", "a") + def test_count_overflow(self): + hugecount = '{}b'.format(sys.maxsize+1) + self.assertRaises(struct.error, struct.calcsize, hugecount) + + hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2) + self.assertRaises(struct.error, struct.calcsize, hugecount2) def test_main(): run_unittest(StructTest) Modified: python/trunk/Modules/_struct.c ============================================================================== --- python/trunk/Modules/_struct.c (original) +++ python/trunk/Modules/_struct.c Fri Jun 11 22:27:05 2010 @@ -1188,16 +1188,19 @@ } -/* Align a size according to a format code */ +/* Align a size according to a format code. Return -1 on overflow. */ -static int +static Py_ssize_t align(Py_ssize_t size, char c, const formatdef *e) { + Py_ssize_t extra; + if (e->format == c) { - if (e->alignment) { - size = ((size + e->alignment - 1) - / e->alignment) - * e->alignment; + if (e->alignment && size > 0) { + extra = (e->alignment - 1) - (size - 1) % (e->alignment); + if (extra > PY_SSIZE_T_MAX - size) + return -1; + size += extra; } } return size; @@ -1216,7 +1219,7 @@ const char *s; const char *fmt; char c; - Py_ssize_t size, len, num, itemsize, x; + Py_ssize_t size, len, num, itemsize; fmt = PyString_AS_STRING(self->s_format); @@ -1231,14 +1234,13 @@ if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { - x = num*10 + (c - '0'); - if (x/10 != num) { - PyErr_SetString( - StructError, - "overflow in item count"); - return -1; - } - num = x; + /* overflow-safe version of + if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ + if (num >= PY_SSIZE_T_MAX / 10 && ( + num > PY_SSIZE_T_MAX / 10 || + (c - '0') > PY_SSIZE_T_MAX % 10)) + goto overflow; + num = num*10 + (c - '0'); } if (c == '\0') break; @@ -1259,13 +1261,13 @@ itemsize = e->size; size = align(size, c, e); - x = num * itemsize; - size += x; - if (x/itemsize != num || size < 0) { - PyErr_SetString(StructError, - "total struct size too long"); - return -1; - } + if (size == -1) + goto overflow; + + /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ + if (num > (PY_SSIZE_T_MAX - size) / itemsize) + goto overflow; + size += num * itemsize; } /* check for overflow */ @@ -1324,6 +1326,11 @@ codes->size = 0; return 0; + + overflow: + PyErr_SetString(StructError, + "total struct size too long"); + return -1; } static PyObject * From python-checkins at python.org Fri Jun 11 22:29:09 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 11 Jun 2010 22:29:09 +0200 (CEST) Subject: [Python-checkins] r81905 - python/branches/py3k Message-ID: <20100611202909.DDC29EE98C@mail.python.org> Author: mark.dickinson Date: Fri Jun 11 22:29:09 2010 New Revision: 81905 Log: Blocked revisions 81904 via svnmerge ........ r81904 | mark.dickinson | 2010-06-11 21:27:05 +0100 (Fri, 11 Jun 2010) | 4 lines Fix possible undefined behaviour from signed overflow in struct module. Backport of revisions 81897, 81898 and 81902 from py3k. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Fri Jun 11 23:40:37 2010 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 11 Jun 2010 23:40:37 +0200 (CEST) Subject: [Python-checkins] r81906 - python/trunk/Python/symtable.c Message-ID: <20100611214037.D2036EE98D@mail.python.org> Author: benjamin.peterson Date: Fri Jun 11 23:40:37 2010 New Revision: 81906 Log: different spellings are just unacceptable Modified: python/trunk/Python/symtable.c Modified: python/trunk/Python/symtable.c ============================================================================== --- python/trunk/Python/symtable.c (original) +++ python/trunk/Python/symtable.c Fri Jun 11 23:40:37 2010 @@ -1395,7 +1395,7 @@ symtable_visit_alias(struct symtable *st, alias_ty a) { /* Compute store_name, the name actually bound by the import - operation. It is diferent than a->name when a->name is a + operation. It is different than a->name when a->name is a dotted package name (e.g. spam.eggs) */ PyObject *store_name; From python-checkins at python.org Fri Jun 11 23:42:26 2010 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 11 Jun 2010 23:42:26 +0200 (CEST) Subject: [Python-checkins] r81907 - in python/trunk: Lib/test/test_codecs.py Misc/NEWS Objects/unicodeobject.c Message-ID: <20100611214226.4EFCEEE98F@mail.python.org> Author: antoine.pitrou Date: Fri Jun 11 23:42:26 2010 New Revision: 81907 Log: Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). Modified: python/trunk/Lib/test/test_codecs.py python/trunk/Misc/NEWS python/trunk/Objects/unicodeobject.c Modified: python/trunk/Lib/test/test_codecs.py ============================================================================== --- python/trunk/Lib/test/test_codecs.py (original) +++ python/trunk/Lib/test/test_codecs.py Fri Jun 11 23:42:26 2010 @@ -315,6 +315,16 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_decode, "\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded_le = '\xff\xfe\x00\x00' + '\x00\x00\x01\x00' * 1024 + self.assertEqual(u'\U00010000' * 1024, + codecs.utf_32_decode(encoded_le)[0]) + encoded_be = '\x00\x00\xfe\xff' + '\x00\x01\x00\x00' * 1024 + self.assertEqual(u'\U00010000' * 1024, + codecs.utf_32_decode(encoded_be)[0]) + class UTF32LETest(ReadTest): encoding = "utf-32-le" @@ -348,6 +358,13 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_le_decode, "\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = '\x00\x00\x01\x00' * 1024 + self.assertEqual(u'\U00010000' * 1024, + codecs.utf_32_le_decode(encoded)[0]) + class UTF32BETest(ReadTest): encoding = "utf-32-be" @@ -381,6 +398,14 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_be_decode, "\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = '\x00\x01\x00\x00' * 1024 + self.assertEqual(u'\U00010000' * 1024, + codecs.utf_32_be_decode(encoded)[0]) + + class UTF16Test(ReadTest): encoding = "utf-16" Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Jun 11 23:42:26 2010 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash + the interpreter with characters outside the Basic Multilingual Plane + (higher than 0x10000). + - In the unicode/str.format(), raise a ValueError when indexes to arguments are too large. Modified: python/trunk/Objects/unicodeobject.c ============================================================================== --- python/trunk/Objects/unicodeobject.c (original) +++ python/trunk/Objects/unicodeobject.c Fri Jun 11 23:42:26 2010 @@ -2207,11 +2207,11 @@ PyUnicodeObject *unicode; Py_UNICODE *p; #ifndef Py_UNICODE_WIDE - int i, pairs; + int pairs = 0; #else const int pairs = 0; #endif - const unsigned char *q, *e; + const unsigned char *q, *e, *qq; int bo = 0; /* assume native ordering by default */ const char *errmsg = ""; /* Offsets from q for retrieving bytes in the right order. */ @@ -2222,23 +2222,7 @@ #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* On narrow builds we split characters outside the BMP into two - codepoints => count how much extra space we need. */ -#ifndef Py_UNICODE_WIDE - for (i = pairs = 0; i < size/4; i++) - if (((Py_UCS4 *)s)[i] >= 0x10000) - pairs++; -#endif - - /* This might be one to much, because of a BOM */ - unicode = _PyUnicode_New((size+3)/4+pairs); - if (!unicode) - return NULL; - if (size == 0) - return (PyObject *)unicode; - - /* Unpack UTF-32 encoded data */ - p = unicode->str; + q = (unsigned char *)s; e = q + size; @@ -2290,6 +2274,24 @@ iorder[3] = 0; } + /* On narrow builds we split characters outside the BMP into two + codepoints => count how much extra space we need. */ +#ifndef Py_UNICODE_WIDE + for (qq = q; qq < e; qq += 4) + if (qq[iorder[2]] != 0 || qq[iorder[3]] != 0) + pairs++; +#endif + + /* This might be one to much, because of a BOM */ + unicode = _PyUnicode_New((size+3)/4+pairs); + if (!unicode) + return NULL; + if (size == 0) + return (PyObject *)unicode; + + /* Unpack UTF-32 encoded data */ + p = unicode->str; + while (q < e) { Py_UCS4 ch; /* remaining bytes at the end? (size should be divisible by 4) */ From python-checkins at python.org Fri Jun 11 23:46:33 2010 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 11 Jun 2010 23:46:33 +0200 (CEST) Subject: [Python-checkins] r81908 - in python/branches/py3k: Lib/test/test_codecs.py Misc/NEWS Objects/unicodeobject.c Message-ID: <20100611214633.36881EE9CF@mail.python.org> Author: antoine.pitrou Date: Fri Jun 11 23:46:32 2010 New Revision: 81908 Log: Merged revisions 81907 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81907 | antoine.pitrou | 2010-06-11 23:42:26 +0200 (ven., 11 juin 2010) | 5 lines Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_codecs.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Lib/test/test_codecs.py ============================================================================== --- python/branches/py3k/Lib/test/test_codecs.py (original) +++ python/branches/py3k/Lib/test/test_codecs.py Fri Jun 11 23:46:32 2010 @@ -353,6 +353,16 @@ self.check_state_handling_decode(self.encoding, "spamspam", self.spambe) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded_le = b'\xff\xfe\x00\x00' + b'\x00\x00\x01\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_decode(encoded_le)[0]) + encoded_be = b'\x00\x00\xfe\xff' + b'\x00\x01\x00\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_decode(encoded_be)[0]) + class UTF32LETest(ReadTest): encoding = "utf-32-le" @@ -386,6 +396,13 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_le_decode, b"\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = b'\x00\x00\x01\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_le_decode(encoded)[0]) + class UTF32BETest(ReadTest): encoding = "utf-32-be" @@ -419,6 +436,14 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_be_decode, b"\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = b'\x00\x01\x00\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_be_decode(encoded)[0]) + + class UTF16Test(ReadTest): encoding = "utf-16" Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 11 23:46:32 2010 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash + the interpreter with characters outside the Basic Multilingual Plane + (higher than 0x10000). + - Issue #8950: (See also issue #5080). Py_ArgParse*() functions now raise TypeError instead of giving a DeprecationWarning when a float is parsed using the 'L' code (for long long). (All other integer Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Fri Jun 11 23:46:32 2010 @@ -2730,11 +2730,11 @@ PyUnicodeObject *unicode; Py_UNICODE *p; #ifndef Py_UNICODE_WIDE - int i, pairs; + int pairs = 0; #else const int pairs = 0; #endif - const unsigned char *q, *e; + const unsigned char *q, *e, *qq; int bo = 0; /* assume native ordering by default */ const char *errmsg = ""; /* Offsets from q for retrieving bytes in the right order. */ @@ -2745,23 +2745,7 @@ #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* On narrow builds we split characters outside the BMP into two - codepoints => count how much extra space we need. */ -#ifndef Py_UNICODE_WIDE - for (i = pairs = 0; i < size/4; i++) - if (((Py_UCS4 *)s)[i] >= 0x10000) - pairs++; -#endif - - /* This might be one to much, because of a BOM */ - unicode = _PyUnicode_New((size+3)/4+pairs); - if (!unicode) - return NULL; - if (size == 0) - return (PyObject *)unicode; - - /* Unpack UTF-32 encoded data */ - p = unicode->str; + q = (unsigned char *)s; e = q + size; @@ -2813,6 +2797,24 @@ iorder[3] = 0; } + /* On narrow builds we split characters outside the BMP into two + codepoints => count how much extra space we need. */ +#ifndef Py_UNICODE_WIDE + for (qq = q; qq < e; qq += 4) + if (qq[iorder[2]] != 0 || qq[iorder[3]] != 0) + pairs++; +#endif + + /* This might be one to much, because of a BOM */ + unicode = _PyUnicode_New((size+3)/4+pairs); + if (!unicode) + return NULL; + if (size == 0) + return (PyObject *)unicode; + + /* Unpack UTF-32 encoded data */ + p = unicode->str; + while (q < e) { Py_UCS4 ch; /* remaining bytes at the end? (size should be divisible by 4) */ From python-checkins at python.org Fri Jun 11 23:48:02 2010 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 11 Jun 2010 23:48:02 +0200 (CEST) Subject: [Python-checkins] r81909 - in python/branches/release26-maint: Lib/test/test_codecs.py Misc/NEWS Objects/unicodeobject.c Message-ID: <20100611214802.B2C7AEE993@mail.python.org> Author: antoine.pitrou Date: Fri Jun 11 23:48:02 2010 New Revision: 81909 Log: Merged revisions 81907 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81907 | antoine.pitrou | 2010-06-11 23:42:26 +0200 (ven., 11 juin 2010) | 5 lines Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_codecs.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/unicodeobject.c Modified: python/branches/release26-maint/Lib/test/test_codecs.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_codecs.py (original) +++ python/branches/release26-maint/Lib/test/test_codecs.py Fri Jun 11 23:48:02 2010 @@ -315,6 +315,16 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_decode, "\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded_le = '\xff\xfe\x00\x00' + '\x00\x00\x01\x00' * 1024 + self.assertEqual(u'\U00010000' * 1024, + codecs.utf_32_decode(encoded_le)[0]) + encoded_be = '\x00\x00\xfe\xff' + '\x00\x01\x00\x00' * 1024 + self.assertEqual(u'\U00010000' * 1024, + codecs.utf_32_decode(encoded_be)[0]) + class UTF32LETest(ReadTest): encoding = "utf-32-le" @@ -348,6 +358,13 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_le_decode, "\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = '\x00\x00\x01\x00' * 1024 + self.assertEqual(u'\U00010000' * 1024, + codecs.utf_32_le_decode(encoded)[0]) + class UTF32BETest(ReadTest): encoding = "utf-32-be" @@ -381,6 +398,14 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_be_decode, "\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = '\x00\x01\x00\x00' * 1024 + self.assertEqual(u'\U00010000' * 1024, + codecs.utf_32_be_decode(encoded)[0]) + + class UTF16Test(ReadTest): encoding = "utf-16" Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Fri Jun 11 23:48:02 2010 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash + the interpreter with characters outside the Basic Multilingual Plane + (higher than 0x10000). + - Issue #8627: Remove bogus "Overriding __cmp__ blocks inheritance of __hash__ in 3.x" warning. Also fix "XXX undetected error" that arises from the "Overriding __eq__ blocks inheritance ..." warning Modified: python/branches/release26-maint/Objects/unicodeobject.c ============================================================================== --- python/branches/release26-maint/Objects/unicodeobject.c (original) +++ python/branches/release26-maint/Objects/unicodeobject.c Fri Jun 11 23:48:02 2010 @@ -2085,11 +2085,11 @@ PyUnicodeObject *unicode; Py_UNICODE *p; #ifndef Py_UNICODE_WIDE - int i, pairs; + int pairs = 0; #else const int pairs = 0; #endif - const unsigned char *q, *e; + const unsigned char *q, *e, *qq; int bo = 0; /* assume native ordering by default */ const char *errmsg = ""; /* Offsets from q for retrieving bytes in the right order. */ @@ -2100,23 +2100,7 @@ #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* On narrow builds we split characters outside the BMP into two - codepoints => count how much extra space we need. */ -#ifndef Py_UNICODE_WIDE - for (i = pairs = 0; i < size/4; i++) - if (((Py_UCS4 *)s)[i] >= 0x10000) - pairs++; -#endif - - /* This might be one to much, because of a BOM */ - unicode = _PyUnicode_New((size+3)/4+pairs); - if (!unicode) - return NULL; - if (size == 0) - return (PyObject *)unicode; - - /* Unpack UTF-32 encoded data */ - p = unicode->str; + q = (unsigned char *)s; e = q + size; @@ -2168,6 +2152,24 @@ iorder[3] = 0; } + /* On narrow builds we split characters outside the BMP into two + codepoints => count how much extra space we need. */ +#ifndef Py_UNICODE_WIDE + for (qq = q; qq < e; qq += 4) + if (qq[iorder[2]] != 0 || qq[iorder[3]] != 0) + pairs++; +#endif + + /* This might be one to much, because of a BOM */ + unicode = _PyUnicode_New((size+3)/4+pairs); + if (!unicode) + return NULL; + if (size == 0) + return (PyObject *)unicode; + + /* Unpack UTF-32 encoded data */ + p = unicode->str; + while (q < e) { Py_UCS4 ch; /* remaining bytes at the end? (size should be divisible by 4) */ From python-checkins at python.org Fri Jun 11 23:48:35 2010 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 11 Jun 2010 23:48:35 +0200 (CEST) Subject: [Python-checkins] r81910 - in python/branches/release31-maint: Lib/test/test_codecs.py Misc/NEWS Objects/unicodeobject.c Message-ID: <20100611214835.2C158EE9CE@mail.python.org> Author: antoine.pitrou Date: Fri Jun 11 23:48:34 2010 New Revision: 81910 Log: Merged revisions 81908 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81908 | antoine.pitrou | 2010-06-11 23:46:32 +0200 (ven., 11 juin 2010) | 11 lines Merged revisions 81907 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81907 | antoine.pitrou | 2010-06-11 23:42:26 +0200 (ven., 11 juin 2010) | 5 lines Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_codecs.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Objects/unicodeobject.c Modified: python/branches/release31-maint/Lib/test/test_codecs.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_codecs.py (original) +++ python/branches/release31-maint/Lib/test/test_codecs.py Fri Jun 11 23:48:34 2010 @@ -354,6 +354,16 @@ self.check_state_handling_decode(self.encoding, "spamspam", self.spambe) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded_le = b'\xff\xfe\x00\x00' + b'\x00\x00\x01\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_decode(encoded_le)[0]) + encoded_be = b'\x00\x00\xfe\xff' + b'\x00\x01\x00\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_decode(encoded_be)[0]) + class UTF32LETest(ReadTest): encoding = "utf-32-le" @@ -387,6 +397,13 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_le_decode, b"\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = b'\x00\x00\x01\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_le_decode(encoded)[0]) + class UTF32BETest(ReadTest): encoding = "utf-32-be" @@ -420,6 +437,14 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_be_decode, b"\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = b'\x00\x01\x00\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_be_decode(encoded)[0]) + + class UTF16Test(ReadTest): encoding = "utf-16" Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Jun 11 23:48:34 2010 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash + the interpreter with characters outside the Basic Multilingual Plane + (higher than 0x10000). + - In the str.format(), raise a ValueError when indexes to arguments are too large. Modified: python/branches/release31-maint/Objects/unicodeobject.c ============================================================================== --- python/branches/release31-maint/Objects/unicodeobject.c (original) +++ python/branches/release31-maint/Objects/unicodeobject.c Fri Jun 11 23:48:34 2010 @@ -2618,11 +2618,11 @@ PyUnicodeObject *unicode; Py_UNICODE *p; #ifndef Py_UNICODE_WIDE - int i, pairs; + int pairs = 0; #else const int pairs = 0; #endif - const unsigned char *q, *e; + const unsigned char *q, *e, *qq; int bo = 0; /* assume native ordering by default */ const char *errmsg = ""; /* Offsets from q for retrieving bytes in the right order. */ @@ -2633,23 +2633,7 @@ #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* On narrow builds we split characters outside the BMP into two - codepoints => count how much extra space we need. */ -#ifndef Py_UNICODE_WIDE - for (i = pairs = 0; i < size/4; i++) - if (((Py_UCS4 *)s)[i] >= 0x10000) - pairs++; -#endif - - /* This might be one to much, because of a BOM */ - unicode = _PyUnicode_New((size+3)/4+pairs); - if (!unicode) - return NULL; - if (size == 0) - return (PyObject *)unicode; - - /* Unpack UTF-32 encoded data */ - p = unicode->str; + q = (unsigned char *)s; e = q + size; @@ -2701,6 +2685,24 @@ iorder[3] = 0; } + /* On narrow builds we split characters outside the BMP into two + codepoints => count how much extra space we need. */ +#ifndef Py_UNICODE_WIDE + for (qq = q; qq < e; qq += 4) + if (qq[iorder[2]] != 0 || qq[iorder[3]] != 0) + pairs++; +#endif + + /* This might be one to much, because of a BOM */ + unicode = _PyUnicode_New((size+3)/4+pairs); + if (!unicode) + return NULL; + if (size == 0) + return (PyObject *)unicode; + + /* Unpack UTF-32 encoded data */ + p = unicode->str; + while (q < e) { Py_UCS4 ch; /* remaining bytes at the end? (size should be divisible by 4) */ From python-checkins at python.org Fri Jun 11 23:50:30 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 11 Jun 2010 23:50:30 +0200 (CEST) Subject: [Python-checkins] r81911 - in python/branches/py3k: Lib/ctypes/test/test_bytes.py Lib/ctypes/test/test_structures.py Misc/NEWS Modules/_ctypes/cfield.c Message-ID: <20100611215030.9ACC3EE98F@mail.python.org> Author: victor.stinner Date: Fri Jun 11 23:50:30 2010 New Revision: 81911 Log: Issue #8966: If a ctypes structure field is an array of c_char, convert its value to bytes instead of str (as done for c_char and c_char_p). Modified: python/branches/py3k/Lib/ctypes/test/test_bytes.py python/branches/py3k/Lib/ctypes/test/test_structures.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_ctypes/cfield.c Modified: python/branches/py3k/Lib/ctypes/test/test_bytes.py ============================================================================== --- python/branches/py3k/Lib/ctypes/test/test_bytes.py (original) +++ python/branches/py3k/Lib/ctypes/test/test_bytes.py Fri Jun 11 23:50:30 2010 @@ -30,8 +30,8 @@ X("abc") x = X(b"abc") - self.assertEqual(x.a, "abc") - self.assertEqual(type(x.a), str) + self.assertEqual(x.a, b"abc") + self.assertEqual(type(x.a), bytes) def test_struct_W(self): class X(Structure): Modified: python/branches/py3k/Lib/ctypes/test/test_structures.py ============================================================================== --- python/branches/py3k/Lib/ctypes/test/test_structures.py (original) +++ python/branches/py3k/Lib/ctypes/test/test_structures.py Fri Jun 11 23:50:30 2010 @@ -209,9 +209,9 @@ self.assertRaises(TypeError, Person, "Name", "HI") # short enough - self.assertEqual(Person("12345", 5).name, "12345") + self.assertEqual(Person("12345", 5).name, b"12345") # exact fit - self.assertEqual(Person("123456", 5).name, "123456") + self.assertEqual(Person("123456", 5).name, b"123456") # too long self.assertRaises(ValueError, Person, "1234567", 5) @@ -269,9 +269,9 @@ p = Person("Someone", ("1234", "5678"), 5) - self.assertEqual(p.name, "Someone") - self.assertEqual(p.phone.areacode, "1234") - self.assertEqual(p.phone.number, "5678") + self.assertEqual(p.name, b"Someone") + self.assertEqual(p.phone.areacode, b"1234") + self.assertEqual(p.phone.number, b"5678") self.assertEqual(p.age, 5) def test_structures_with_wchar(self): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 11 23:50:30 2010 @@ -421,6 +421,9 @@ Library ------- +- Issue #8966: If a ctypes structure field is an array of c_char, convert its + value to bytes instead of str (as done for c_char and c_char_p). + - Issue #8188: Comparisons between Decimal and Fraction objects are now permitted, returning a result based on the exact numerical values of the operands. This builds on issue #2531, which allowed @@ -1288,7 +1291,7 @@ ----------------- - Issue #3129: Trailing digits in format string are no longer ignored. - For example, "1" or "ilib123" are now invalid formats and cause + For example, "1" or "ilib123" are now invalid formats and cause ``struct.error`` to be raised. - Issue #7384: If the system readline library is linked against ncurses, Modified: python/branches/py3k/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k/Modules/_ctypes/cfield.c Fri Jun 11 23:50:30 2010 @@ -1333,7 +1333,7 @@ break; } - return PyUnicode_FromStringAndSize((char *)ptr, (Py_ssize_t)i); + return PyBytes_FromStringAndSize((char *)ptr, (Py_ssize_t)i); } static PyObject * From python-checkins at python.org Fri Jun 11 23:53:07 2010 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 11 Jun 2010 23:53:07 +0200 (CEST) Subject: [Python-checkins] r81912 - in python/branches/py3k: Python/symtable.c Message-ID: <20100611215307.E7108EE989@mail.python.org> Author: benjamin.peterson Date: Fri Jun 11 23:53:07 2010 New Revision: 81912 Log: Merged revisions 81906 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81906 | benjamin.peterson | 2010-06-11 16:40:37 -0500 (Fri, 11 Jun 2010) | 1 line different spellings are just unacceptable ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Python/symtable.c Modified: python/branches/py3k/Python/symtable.c ============================================================================== --- python/branches/py3k/Python/symtable.c (original) +++ python/branches/py3k/Python/symtable.c Fri Jun 11 23:53:07 2010 @@ -1533,7 +1533,7 @@ symtable_visit_alias(struct symtable *st, alias_ty a) { /* Compute store_name, the name actually bound by the import - operation. It is diferent than a->name when a->name is a + operation. It is different than a->name when a->name is a dotted package name (e.g. spam.eggs) */ PyObject *store_name; From python-checkins at python.org Fri Jun 11 23:53:36 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 11 Jun 2010 23:53:36 +0200 (CEST) Subject: [Python-checkins] r81913 - python/branches/release31-maint Message-ID: <20100611215336.83D95EE9D0@mail.python.org> Author: victor.stinner Date: Fri Jun 11 23:53:36 2010 New Revision: 81913 Log: Blocked revisions 81911 via svnmerge ........ r81911 | victor.stinner | 2010-06-11 23:50:30 +0200 (ven., 11 juin 2010) | 3 lines Issue #8966: If a ctypes structure field is an array of c_char, convert its value to bytes instead of str (as done for c_char and c_char_p). ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sat Jun 12 00:09:52 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 00:09:52 +0200 (CEST) Subject: [Python-checkins] r81914 - python/branches/py3k/Modules/_localemodule.c Message-ID: <20100611220952.0F064F599@mail.python.org> Author: victor.stinner Date: Sat Jun 12 00:09:51 2010 New Revision: 81914 Log: locale.bindtextdomain(): use PyUnicode_FSConverter() to parse the filename Modified: python/branches/py3k/Modules/_localemodule.c Modified: python/branches/py3k/Modules/_localemodule.c ============================================================================== --- python/branches/py3k/Modules/_localemodule.c (original) +++ python/branches/py3k/Modules/_localemodule.c Sat Jun 12 00:09:51 2010 @@ -572,19 +572,31 @@ static PyObject* PyIntl_bindtextdomain(PyObject* self,PyObject*args) { - char *domain, *dirname; - if (!PyArg_ParseTuple(args, "sz", &domain, &dirname)) + char *domain, *dirname, *current_dirname; + PyObject *dirname_obj, *dirname_bytes = NULL, *result; + if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj)) return 0; if (!strlen(domain)) { PyErr_SetString(Error, "domain must be a non-empty string"); return 0; } - dirname = bindtextdomain(domain, dirname); - if (!dirname) { + if (dirname_obj != Py_None) { + if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes)) + return NULL; + dirname = PyBytes_AsString(dirname_bytes); + } else { + dirname_bytes = NULL; + dirname = NULL; + } + current_dirname = bindtextdomain(domain, dirname); + if (current_dirname == NULL) { + Py_XDECREF(dirname_bytes); PyErr_SetFromErrno(PyExc_OSError); return NULL; } - return str2uni(dirname); + result = str2uni(current_dirname); + Py_XDECREF(dirname_bytes); + return result; } #ifdef HAVE_BIND_TEXTDOMAIN_CODESET From python-checkins at python.org Sat Jun 12 00:12:43 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 00:12:43 +0200 (CEST) Subject: [Python-checkins] r81915 - python/branches/release31-maint Message-ID: <20100611221243.47999EE9C6@mail.python.org> Author: victor.stinner Date: Sat Jun 12 00:12:43 2010 New Revision: 81915 Log: Blocked revisions 81914 via svnmerge ........ r81914 | victor.stinner | 2010-06-12 00:09:51 +0200 (sam., 12 juin 2010) | 2 lines locale.bindtextdomain(): use PyUnicode_FSConverter() to parse the filename ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sat Jun 12 00:17:52 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 00:17:52 +0200 (CEST) Subject: [Python-checkins] r81916 - python/branches/py3k/Lib/test/test_sys.py Message-ID: <20100611221752.93ADBEE9E1@mail.python.org> Author: victor.stinner Date: Sat Jun 12 00:17:52 2010 New Revision: 81916 Log: Issue #8965: Add a regression test to test_sys with LANG=C Modified: python/branches/py3k/Lib/test/test_sys.py Modified: python/branches/py3k/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k/Lib/test/test_sys.py (original) +++ python/branches/py3k/Lib/test/test_sys.py Sat Jun 12 00:17:52 2010 @@ -863,10 +863,21 @@ # sys.flags check(sys.flags, size(vh) + self.P * len(sys.flags)) + @unittest.skipUnless(sys.platform == 'darwin', "test specific to Mac OS X") def test_getfilesystemencoding(self): + # On Darwing FS encoding is always UTF-8 fs_encoding = sys.getfilesystemencoding() - if sys.platform == 'darwin': - self.assertEqual(fs_encoding, 'utf-8') + self.assertEqual(fs_encoding, 'utf-8') + + # Even in C locale + env = os.environ.copy() + env['LANG'] = 'C' + output = subprocess.check_output( + [sys.executable, "-c", + "import sys; print(sys.getfilesystemencoding())"], + env=env) + fs_encoding = output.rstrip() + self.assertEqual(fs_encoding, b'utf-8') def test_setfilesystemencoding(self): old = sys.getfilesystemencoding() From python-checkins at python.org Sat Jun 12 00:18:40 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 00:18:40 +0200 (CEST) Subject: [Python-checkins] r81917 - python/branches/release31-maint Message-ID: <20100611221840.131FCEE9B9@mail.python.org> Author: victor.stinner Date: Sat Jun 12 00:18:39 2010 New Revision: 81917 Log: Blocked revisions 81916 via svnmerge ........ r81916 | victor.stinner | 2010-06-12 00:17:52 +0200 (sam., 12 juin 2010) | 2 lines Issue #8965: Add a regression test to test_sys with LANG=C ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sat Jun 12 00:27:14 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 00:27:14 +0200 (CEST) Subject: [Python-checkins] r81918 - python/branches/py3k/Modules/readline.c Message-ID: <20100611222714.54825EE989@mail.python.org> Author: victor.stinner Date: Sat Jun 12 00:27:14 2010 New Revision: 81918 Log: readline: use PyUnicode_FSConverter() to parse filenames Modified: python/branches/py3k/Modules/readline.c Modified: python/branches/py3k/Modules/readline.c ============================================================================== --- python/branches/py3k/Modules/readline.c (original) +++ python/branches/py3k/Modules/readline.c Sat Jun 12 00:27:14 2010 @@ -98,10 +98,16 @@ static PyObject * read_init_file(PyObject *self, PyObject *args) { - char *s = NULL; - if (!PyArg_ParseTuple(args, "|z:read_init_file", &s)) + PyObject *filename_obj = Py_None, *filename_bytes; + if (!PyArg_ParseTuple(args, "|O:read_init_file", &filename_obj)) return NULL; - errno = rl_read_init_file(s); + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + errno = rl_read_init_file(PyBytes_AsString(filename_bytes)); + Py_DECREF(filename_bytes); + } else + errno = rl_read_init_file(NULL); if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; @@ -118,10 +124,16 @@ static PyObject * read_history_file(PyObject *self, PyObject *args) { - char *s = NULL; - if (!PyArg_ParseTuple(args, "|z:read_history_file", &s)) + PyObject *filename_obj = Py_None, *filename_bytes; + if (!PyArg_ParseTuple(args, "|O:read_history_file", &filename_obj)) return NULL; - errno = read_history(s); + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + errno = read_history(PyBytes_AsString(filename_bytes)); + Py_DECREF(filename_bytes); + } else + errno = read_history(NULL); if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; @@ -139,12 +151,22 @@ static PyObject * write_history_file(PyObject *self, PyObject *args) { - char *s = NULL; - if (!PyArg_ParseTuple(args, "|z:write_history_file", &s)) + PyObject *filename_obj = Py_None, *filename_bytes; + char *filename; + if (!PyArg_ParseTuple(args, "|O:write_history_file", &filename_obj)) return NULL; - errno = write_history(s); + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + filename = PyBytes_AsString(filename_bytes); + } else { + filename_bytes = NULL; + filename = NULL; + } + errno = write_history(filename); if (!errno && _history_length >= 0) - history_truncate_file(s, _history_length); + history_truncate_file(filename, _history_length); + Py_XDECREF(filename_bytes); if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; From python-checkins at python.org Sat Jun 12 00:56:50 2010 From: python-checkins at python.org (vinay.sajip) Date: Sat, 12 Jun 2010 00:56:50 +0200 (CEST) Subject: [Python-checkins] r81919 - in python: branches/release26-maint/Lib/logging/__init__.py branches/release26-maint/Misc/NEWS trunk/Lib/logging/__init__.py trunk/Misc/NEWS Message-ID: <20100611225650.5D76AEE989@mail.python.org> Author: vinay.sajip Date: Sat Jun 12 00:56:50 2010 New Revision: 81919 Log: Issue #8924: logging: Improved error handling for Unicode in exception text. Modified: python/branches/release26-maint/Lib/logging/__init__.py python/branches/release26-maint/Misc/NEWS python/trunk/Lib/logging/__init__.py python/trunk/Misc/NEWS Modified: python/branches/release26-maint/Lib/logging/__init__.py ============================================================================== --- python/branches/release26-maint/Lib/logging/__init__.py (original) +++ python/branches/release26-maint/Lib/logging/__init__.py Sat Jun 12 00:56:50 2010 @@ -445,7 +445,13 @@ if record.exc_text: if s[-1:] != "\n": s = s + "\n" - s = s + record.exc_text + try: + s = s + record.exc_text + except UnicodeError: + # Sometimes filenames have non-ASCII chars, which can lead + # to errors when s is Unicode and record.exc_text is str + # See issue 8924 + s = s + record.exc_text.decode(sys.getfilesystemencoding()) return s # Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Jun 12 00:56:50 2010 @@ -71,6 +71,8 @@ Library ------- +- Issue #8924: logging: Improved error handling for Unicode in exception text. + - Fix codecs.escape_encode to return the correct consumed size. - Issue #6470: Drop UNC prefix in FixTk. Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Sat Jun 12 00:56:50 2010 @@ -473,7 +473,13 @@ if record.exc_text: if s[-1:] != "\n": s = s + "\n" - s = s + record.exc_text + try: + s = s + record.exc_text + except UnicodeError: + # Sometimes filenames have non-ASCII chars, which can lead + # to errors when s is Unicode and record.exc_text is str + # See issue 8924 + s = s + record.exc_text.decode(sys.getfilesystemencoding()) return s # Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Jun 12 00:56:50 2010 @@ -21,6 +21,7 @@ Library ------- +- Issue #8924: logging: Improved error handling for Unicode in exception text. - Issue #8948: cleanup functions and class / module setups and teardowns are now honored in unittest debug methods. From python-checkins at python.org Sat Jun 12 01:06:13 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 01:06:13 +0200 (CEST) Subject: [Python-checkins] r81920 - python/branches/py3k/Lib/test/test_sys.py Message-ID: <20100611230613.8174BEE98F@mail.python.org> Author: victor.stinner Date: Sat Jun 12 01:06:13 2010 New Revision: 81920 Log: Issue #8965: Write more tests for sys.getfilesystemencoding() Modified: python/branches/py3k/Lib/test/test_sys.py Modified: python/branches/py3k/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k/Lib/test/test_sys.py (original) +++ python/branches/py3k/Lib/test/test_sys.py Sat Jun 12 01:06:13 2010 @@ -863,21 +863,34 @@ # sys.flags check(sys.flags, size(vh) + self.P * len(sys.flags)) - @unittest.skipUnless(sys.platform == 'darwin', "test specific to Mac OS X") def test_getfilesystemencoding(self): - # On Darwing FS encoding is always UTF-8 + import codecs + + def check_fsencoding(fs_encoding): + self.assertIsNotNone(fs_encoding) + if sys.platform == 'darwin': + self.assertEqual(fs_encoding, 'utf-8') + codecs.lookup(fs_encoding) + fs_encoding = sys.getfilesystemencoding() - self.assertEqual(fs_encoding, 'utf-8') + check_fsencoding(fs_encoding) # Even in C locale - env = os.environ.copy() - env['LANG'] = 'C' - output = subprocess.check_output( - [sys.executable, "-c", - "import sys; print(sys.getfilesystemencoding())"], - env=env) - fs_encoding = output.rstrip() - self.assertEqual(fs_encoding, b'utf-8') + try: + sys.executable.encode('ascii') + except UnicodeEncodeError: + # Python doesn't start with ASCII locale if its path is not ASCII, + # see issue #8611 + pass + else: + env = os.environ.copy() + env['LANG'] = 'C' + output = subprocess.check_output( + [sys.executable, "-c", + "import sys; print(sys.getfilesystemencoding())"], + env=env) + fs_encoding = output.rstrip().decode('ascii') + check_fsencoding(fs_encoding) def test_setfilesystemencoding(self): old = sys.getfilesystemencoding() From python-checkins at python.org Sat Jun 12 01:12:58 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 01:12:58 +0200 (CEST) Subject: [Python-checkins] r81921 - in python/branches/release31-maint: Lib/test/test_sys.py Message-ID: <20100611231258.3FA39D2CC@mail.python.org> Author: victor.stinner Date: Sat Jun 12 01:12:58 2010 New Revision: 81921 Log: Backport test_getfilesystemencoding() from py3k Note: On Python 3.1, file system encoding can be None. Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_sys.py Modified: python/branches/release31-maint/Lib/test/test_sys.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_sys.py (original) +++ python/branches/release31-maint/Lib/test/test_sys.py Sat Jun 12 01:12:58 2010 @@ -792,6 +792,36 @@ # sys.flags check(sys.flags, size(vh) + self.P * len(sys.flags)) + def test_getfilesystemencoding(self): + import codecs + + def check_fsencoding(fs_encoding): + if sys.platform == 'darwin': + self.assertEqual(fs_encoding, 'utf-8') + elif fs_encoding is None: + return + codecs.lookup(fs_encoding) + + fs_encoding = sys.getfilesystemencoding() + check_fsencoding(fs_encoding) + + # Even in C locale + try: + sys.executable.encode('ascii') + except UnicodeEncodeError: + # Python doesn't start with ASCII locale if its path is not ASCII, + # see issue #8611 + pass + else: + env = os.environ.copy() + env['LANG'] = 'C' + output = subprocess.check_output( + [sys.executable, "-c", + "import sys; print(sys.getfilesystemencoding())"], + env=env) + fs_encoding = output.rstrip().decode('ascii') + check_fsencoding(fs_encoding) + def test_setfilesystemencoding(self): old = sys.getfilesystemencoding() try: From python-checkins at python.org Sat Jun 12 01:13:29 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 01:13:29 +0200 (CEST) Subject: [Python-checkins] r81922 - python/branches/release31-maint Message-ID: <20100611231329.BBCA9EE993@mail.python.org> Author: victor.stinner Date: Sat Jun 12 01:13:29 2010 New Revision: 81922 Log: Blocked revisions 81918 via svnmerge ........ r81918 | victor.stinner | 2010-06-12 00:27:14 +0200 (sam., 12 juin 2010) | 2 lines readline: use PyUnicode_FSConverter() to parse filenames ........ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Sat Jun 12 01:26:26 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 12 Jun 2010 01:26:26 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81902): sum=0 Message-ID: <20100611232626.921271775B@ns6635.ovh.net> py3k results for svn r81902 (hg cset 0b804d3c59ca) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog75XWoJ', '-x'] From python-checkins at python.org Sat Jun 12 01:30:12 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 01:30:12 +0200 (CEST) Subject: [Python-checkins] r81923 - python/branches/py3k/Doc/c-api/arg.rst Message-ID: <20100611233012.68406EB69@mail.python.org> Author: victor.stinner Date: Sat Jun 12 01:30:12 2010 New Revision: 81923 Log: Fix some bugs in c-api/arg.rst documentation * replace "the default encoding" by "'utf-8' encoding" * fix "w" / "w*" / "w#" doc: similar to "y" / "y*" / "y#" and not "s" / "s*" / "s#" * "u#": remove "Non-Unicode objects are handled by interpreting their read-buffer pointer ...", it's no more true * "es", "es#": remove "... and objects convertible to Unicode into a character buffer", it's no more true * Py_BuildValue(), "K" and "L" formats: specify the name of the C type on Windows (_int64 / unsigned _int64) as done for PyArg_Parse*() long long types --CETTE ligne, et les suivantes ci-dessous, seront ignor?es-- M Doc/c-api/arg.rst Modified: python/branches/py3k/Doc/c-api/arg.rst Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Sat Jun 12 01:30:12 2010 @@ -133,9 +133,7 @@ ``u#`` (:class:`str`) [Py_UNICODE \*, int] This variant on ``u`` stores into two C variables, the first one a pointer to a - Unicode data buffer, the second one its length. Non-Unicode objects are handled - by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` - array. + Unicode data buffer, the second one its length. ``Z`` (:class:`str` or ``None``) [Py_UNICODE \*] Like ``u``, but the Python object may also be ``None``, in which case the @@ -151,29 +149,28 @@ object. The C variable may also be declared as :ctype:`PyObject\*`. ``w`` (:class:`bytearray` or read-write character buffer) [char \*] - Similar to ``s``, but accepts any object which implements the read-write buffer + Similar to ``y``, but accepts any object which implements the read-write buffer interface. The caller must determine the length of the buffer by other means, or use ``w#`` instead. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. ``w*`` (:class:`bytearray` or read-write byte-oriented buffer) [Py_buffer] - This is to ``w`` what ``s*`` is to ``s``. + This is to ``w`` what ``y*`` is to ``y``. ``w#`` (:class:`bytearray` or read-write character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-write buffer + Like ``y#``, but accepts any object which implements the read-write buffer interface. The :ctype:`char \*` variable is set to point to the first byte of the buffer, and the :ctype:`int` is set to the length of the buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. ``es`` (:class:`str`) [const char \*encoding, char \*\*buffer] - This variant on ``s`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. It only works for encoded data without embedded - NUL bytes. + This variant on ``s`` is used for encoding Unicode into a character buffer. + It only works for encoded data without embedded NUL bytes. This format requires two arguments. The first is only used as input, and must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. + NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a :ctype:`char\*\*`; the value of the pointer it references will be set to a buffer with the contents of the argument text. @@ -190,13 +187,13 @@ the encoding passed in as parameter. ``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] - This variant on ``s#`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. Unlike the ``es`` format, this variant allows - input data which contains NUL characters. + This variant on ``s#`` is used for encoding Unicode into a character buffer. + Unlike the ``es`` format, this variant allows input data which contains NUL + characters. It requires three arguments. The first is only used as input, and must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. + NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a :ctype:`char\*\*`; the value of the pointer it references will be set to a buffer with the contents of the argument text. @@ -556,11 +553,13 @@ ``L`` (:class:`int`) [PY_LONG_LONG] Convert a C :ctype:`long long` to a Python integer object. Only available - on platforms that support :ctype:`long long`. + on platforms that support :ctype:`long long` (or :ctype:`_int64` on + Windows). ``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a C :ctype:`unsigned long long` to a Python integer object. Only - available on platforms that support :ctype:`unsigned long long`. + available on platforms that support :ctype:`unsigned long long` (or + :ctype:`unsigned _int64` on Windows). ``n`` (:class:`int`) [Py_ssize_t] Convert a C :ctype:`Py_ssize_t` to a Python integer. From python-checkins at python.org Sat Jun 12 01:33:56 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 01:33:56 +0200 (CEST) Subject: [Python-checkins] r81924 - in python/branches/release31-maint: Doc/c-api/arg.rst Message-ID: <20100611233356.7AFB0EE98C@mail.python.org> Author: victor.stinner Date: Sat Jun 12 01:33:56 2010 New Revision: 81924 Log: Merged revisions 81923 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81923 | victor.stinner | 2010-06-12 01:30:12 +0200 (sam., 12 juin 2010) | 16 lines Fix some bugs in c-api/arg.rst documentation * replace "the default encoding" by "'utf-8' encoding" * fix "w" / "w*" / "w#" doc: similar to "y" / "y*" / "y#" and not "s" / "s*" / "s#" * "u#": remove "Non-Unicode objects are handled by interpreting their read-buffer pointer ...", it's no more true * "es", "es#": remove "... and objects convertible to Unicode into a character buffer", it's no more true * Py_BuildValue(), "K" and "L" formats: specify the name of the C type on Windows (_int64 / unsigned _int64) as done for PyArg_Parse*() long long types --CETTE ligne, et les suivantes ci-dessous, seront ignor?es-- M Doc/c-api/arg.rst ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/c-api/arg.rst Modified: python/branches/release31-maint/Doc/c-api/arg.rst ============================================================================== --- python/branches/release31-maint/Doc/c-api/arg.rst (original) +++ python/branches/release31-maint/Doc/c-api/arg.rst Sat Jun 12 01:33:56 2010 @@ -133,9 +133,7 @@ ``u#`` (:class:`str`) [Py_UNICODE \*, int] This variant on ``u`` stores into two C variables, the first one a pointer to a - Unicode data buffer, the second one its length. Non-Unicode objects are handled - by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` - array. + Unicode data buffer, the second one its length. ``Z`` (:class:`str` or ``None``) [Py_UNICODE \*] Like ``u``, but the Python object may also be ``None``, in which case the @@ -158,29 +156,28 @@ others. ``w`` (:class:`bytearray` or read-write character buffer) [char \*] - Similar to ``s``, but accepts any object which implements the read-write buffer + Similar to ``y``, but accepts any object which implements the read-write buffer interface. The caller must determine the length of the buffer by other means, or use ``w#`` instead. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. ``w*`` (:class:`bytearray` or read-write byte-oriented buffer) [Py_buffer] - This is to ``w`` what ``s*`` is to ``s``. + This is to ``w`` what ``y*`` is to ``y``. ``w#`` (:class:`bytearray` or read-write character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-write buffer + Like ``y#``, but accepts any object which implements the read-write buffer interface. The :ctype:`char \*` variable is set to point to the first byte of the buffer, and the :ctype:`int` is set to the length of the buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. ``es`` (:class:`str`) [const char \*encoding, char \*\*buffer] - This variant on ``s`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. It only works for encoded data without embedded - NUL bytes. + This variant on ``s`` is used for encoding Unicode into a character buffer. + It only works for encoded data without embedded NUL bytes. This format requires two arguments. The first is only used as input, and must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. + NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a :ctype:`char\*\*`; the value of the pointer it references will be set to a buffer with the contents of the argument text. @@ -197,13 +194,13 @@ the encoding passed in as parameter. ``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] - This variant on ``s#`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. Unlike the ``es`` format, this variant allows - input data which contains NUL characters. + This variant on ``s#`` is used for encoding Unicode into a character buffer. + Unlike the ``es`` format, this variant allows input data which contains NUL + characters. It requires three arguments. The first is only used as input, and must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. + NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a :ctype:`char\*\*`; the value of the pointer it references will be set to a buffer with the contents of the argument text. @@ -556,11 +553,13 @@ ``L`` (:class:`int`) [PY_LONG_LONG] Convert a C :ctype:`long long` to a Python integer object. Only available - on platforms that support :ctype:`long long`. + on platforms that support :ctype:`long long` (or :ctype:`_int64` on + Windows). ``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a C :ctype:`unsigned long long` to a Python integer object. Only - available on platforms that support :ctype:`unsigned long long`. + available on platforms that support :ctype:`unsigned long long` (or + :ctype:`unsigned _int64` on Windows). ``n`` (:class:`int`) [Py_ssize_t] Convert a C :ctype:`Py_ssize_t` to a Python integer. From python-checkins at python.org Sat Jun 12 01:46:47 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 01:46:47 +0200 (CEST) Subject: [Python-checkins] r81925 - in python/branches/py3k: Doc/library/tarfile.rst Lib/tarfile.py Misc/NEWS Message-ID: <20100611234647.D713BEE9C7@mail.python.org> Author: victor.stinner Date: Sat Jun 12 01:46:47 2010 New Revision: 81925 Log: Issue #8784: Set tarfile default encoding to 'utf-8' on Windows. Note: file system encoding cannot be None anymore (since r81190, issue #8610). Modified: python/branches/py3k/Doc/library/tarfile.rst python/branches/py3k/Lib/tarfile.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/tarfile.rst ============================================================================== --- python/branches/py3k/Doc/library/tarfile.rst (original) +++ python/branches/py3k/Doc/library/tarfile.rst Sat Jun 12 01:46:47 2010 @@ -185,8 +185,8 @@ .. data:: ENCODING - The default character encoding i.e. the value from either - :func:`sys.getfilesystemencoding` or :func:`sys.getdefaultencoding`. + The default character encoding: ``'utf-8'`` on Windows, + :func:`sys.getfilesystemencoding` otherwise. .. seealso:: Modified: python/branches/py3k/Lib/tarfile.py ============================================================================== --- python/branches/py3k/Lib/tarfile.py (original) +++ python/branches/py3k/Lib/tarfile.py Sat Jun 12 01:46:47 2010 @@ -159,9 +159,10 @@ #--------------------------------------------------------- # initialization #--------------------------------------------------------- -ENCODING = sys.getfilesystemencoding() -if ENCODING is None: - ENCODING = "ascii" +if os.name in ("nt", "ce"): + ENCODING = "utf-8" +else: + ENCODING = sys.getfilesystemencoding() #--------------------------------------------------------- # Some useful functions Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jun 12 01:46:47 2010 @@ -421,6 +421,8 @@ Library ------- +- Issue #8784: Set tarfile default encoding to 'utf-8' on Windows. + - Issue #8966: If a ctypes structure field is an array of c_char, convert its value to bytes instead of str (as done for c_char and c_char_p). From python-checkins at python.org Sat Jun 12 01:49:41 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 01:49:41 +0200 (CEST) Subject: [Python-checkins] r81926 - python/branches/release31-maint Message-ID: <20100611234941.C2566EE9A9@mail.python.org> Author: victor.stinner Date: Sat Jun 12 01:49:41 2010 New Revision: 81926 Log: Blocked revisions 81925 via svnmerge ........ r81925 | victor.stinner | 2010-06-12 01:46:47 +0200 (sam., 12 juin 2010) | 4 lines Issue #8784: Set tarfile default encoding to 'utf-8' on Windows. Note: file system encoding cannot be None anymore (since r81190, issue #8610). ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sat Jun 12 01:56:52 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 01:56:52 +0200 (CEST) Subject: [Python-checkins] r81927 - in python/branches/py3k: Doc/library/os.rst Lib/os.py Lib/test/test_ssl.py Misc/NEWS Objects/unicodeobject.c Message-ID: <20100611235652.041C5F545@mail.python.org> Author: victor.stinner Date: Sat Jun 12 01:56:51 2010 New Revision: 81927 Log: Issue #8969: On Windows, use mbcs codec in strict mode to encode and decode filenames and enable os.fsencode(). Modified: python/branches/py3k/Doc/library/os.rst python/branches/py3k/Lib/os.py python/branches/py3k/Lib/test/test_ssl.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Sat Jun 12 01:56:51 2010 @@ -159,10 +159,10 @@ .. function:: fsencode(value) Encode *value* to bytes for use in the file system, environment variables or - the command line. Uses :func:`sys.getfilesystemencoding` and - ``'surrogateescape'`` error handler for strings and returns bytes unchanged. - - Availability: Unix. + the command line. Use :func:`sys.getfilesystemencoding` and + ``'surrogateescape'`` error handler for strings and return bytes unchanged. + On Windows, use ``'strict'`` error handler for strings if the file system + encoding is ``'mbcs'`` (which is the default encoding). .. versionadded:: 3.2 Modified: python/branches/py3k/Lib/os.py ============================================================================== --- python/branches/py3k/Lib/os.py (original) +++ python/branches/py3k/Lib/os.py Sat Jun 12 01:56:51 2010 @@ -533,16 +533,19 @@ return environb.get(key, default) __all__.append("getenvb") -if name != 'nt': - def fsencode(value): - """Encode value for use in the file system, environment variables - or the command line.""" - if isinstance(value, bytes): - return value - elif isinstance(value, str): - return value.encode(sys.getfilesystemencoding(), 'surrogateescape') +def fsencode(value): + """Encode value for use in the file system, environment variables + or the command line.""" + if isinstance(value, bytes): + return value + elif isinstance(value, str): + encoding = sys.getfilesystemencoding() + if encoding == 'mbcs': + return value.encode(encoding) else: - raise TypeError("expect bytes or str, not %s" % type(value).__name__) + return value.encode(encoding, 'surrogateescape') + else: + raise TypeError("expect bytes or str, not %s" % type(value).__name__) def _exists(name): return name in globals() Modified: python/branches/py3k/Lib/test/test_ssl.py ============================================================================== --- python/branches/py3k/Lib/test/test_ssl.py (original) +++ python/branches/py3k/Lib/test/test_ssl.py Sat Jun 12 01:56:51 2010 @@ -33,16 +33,15 @@ HOST = support.HOST data_file = lambda name: os.path.join(os.path.dirname(__file__), name) -fsencode = lambda name: name.encode(sys.getfilesystemencoding(), "surrogateescape") CERTFILE = data_file("keycert.pem") -BYTES_CERTFILE = fsencode(CERTFILE) +BYTES_CERTFILE = os.fsencode(CERTFILE) ONLYCERT = data_file("ssl_cert.pem") ONLYKEY = data_file("ssl_key.pem") -BYTES_ONLYCERT = fsencode(ONLYCERT) -BYTES_ONLYKEY = fsencode(ONLYKEY) +BYTES_ONLYCERT = os.fsencode(ONLYCERT) +BYTES_ONLYKEY = os.fsencode(ONLYKEY) CAPATH = data_file("capath") -BYTES_CAPATH = fsencode(CAPATH) +BYTES_CAPATH = os.fsencode(CAPATH) SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem") Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jun 12 01:56:51 2010 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #8969: On Windows, use mbcs codec in strict mode to encode and decode + filenames and enable os.fsencode(). + - Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Sat Jun 12 01:56:51 2010 @@ -1478,11 +1478,17 @@ PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) { - if (Py_FileSystemDefaultEncoding) + if (Py_FileSystemDefaultEncoding) { +#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) + if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + NULL); +#endif return PyUnicode_AsEncodedString(unicode, Py_FileSystemDefaultEncoding, "surrogateescape"); - else + } else return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), "surrogateescape"); @@ -1639,7 +1645,7 @@ if (Py_FileSystemDefaultEncoding) { #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) { - return PyUnicode_DecodeMBCS(s, size, "surrogateescape"); + return PyUnicode_DecodeMBCS(s, size, NULL); } #elif defined(__APPLE__) if (strcmp(Py_FileSystemDefaultEncoding, "utf-8") == 0) { @@ -2745,7 +2751,7 @@ #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - + q = (unsigned char *)s; e = q + size; From python-checkins at python.org Sat Jun 12 01:57:10 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 12 Jun 2010 01:57:10 +0200 (CEST) Subject: [Python-checkins] r81928 - python/branches/release31-maint Message-ID: <20100611235710.A6F0EF545@mail.python.org> Author: victor.stinner Date: Sat Jun 12 01:57:10 2010 New Revision: 81928 Log: Blocked revisions 81927 via svnmerge ........ r81927 | victor.stinner | 2010-06-12 01:56:51 +0200 (sam., 12 juin 2010) | 3 lines Issue #8969: On Windows, use mbcs codec in strict mode to encode and decode filenames and enable os.fsencode(). ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sat Jun 12 02:38:29 2010 From: python-checkins at python.org (brett.cannon) Date: Sat, 12 Jun 2010 02:38:29 +0200 (CEST) Subject: [Python-checkins] r81929 - python/branches/py3k/Lib/test/regrtest.py Message-ID: <20100612003829.5C063EE993@mail.python.org> Author: brett.cannon Date: Sat Jun 12 02:38:29 2010 New Revision: 81929 Log: When dealing with __import__ for detecting a global state change made by a test, make sure to check if __builtins__ is a dict or not. Discovered when running importlib.test.regrtest. Modified: python/branches/py3k/Lib/test/regrtest.py Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Sat Jun 12 02:38:29 2010 @@ -859,9 +859,15 @@ sys.path_hooks[:] = saved_hooks[2] def get___import__(self): - return __builtins__.__import__ + if isinstance(__builtins__, dict): + return __builtins__['__import__'] + else: + return __builtins__.__import__ def restore___import__(self, import_): - __builtins__.__import__ = import_ + if isinstance(__builtins__, dict): + __builtins__['__import__'] = import_ + else: + __builtins__.__import__ = import_ def get_warnings_filters(self): return id(warnings.filters), warnings.filters, warnings.filters[:] From python-checkins at python.org Sat Jun 12 02:39:29 2010 From: python-checkins at python.org (brett.cannon) Date: Sat, 12 Jun 2010 02:39:29 +0200 (CEST) Subject: [Python-checkins] r81930 - python/branches/py3k/Lib/logging/config.py Message-ID: <20100612003929.050B0EE993@mail.python.org> Author: brett.cannon Date: Sat Jun 12 02:39:28 2010 New Revision: 81930 Log: Calling __import__ as a method technically works, but really should be wrapped in a staticmethod. This is important for when __import__ is set to a function defined in Python instead of C. Modified: python/branches/py3k/Lib/logging/config.py Modified: python/branches/py3k/Lib/logging/config.py ============================================================================== --- python/branches/py3k/Lib/logging/config.py (original) +++ python/branches/py3k/Lib/logging/config.py Sat Jun 12 02:39:28 2010 @@ -373,7 +373,7 @@ } # We might want to use a different one, e.g. importlib - importer = __import__ + importer = staticmethod(__import__) def __init__(self, config): self.config = ConvertingDict(config) From pjenvey at underboss.org Sat Jun 12 07:50:25 2010 From: pjenvey at underboss.org (Philip Jenvey) Date: Fri, 11 Jun 2010 22:50:25 -0700 Subject: [Python-checkins] r81929 - python/branches/py3k/Lib/test/regrtest.py In-Reply-To: <20100612003829.5C063EE993@mail.python.org> References: <20100612003829.5C063EE993@mail.python.org> Message-ID: <97BCF441-A9B3-4A23-A710-5CA0865CCEA5@underboss.org> On Jun 11, 2010, at 5:38 PM, brett.cannon wrote: > Author: brett.cannon > Date: Sat Jun 12 02:38:29 2010 > New Revision: 81929 > > Log: > When dealing with __import__ for detecting a global state change made by a > test, make sure to check if __builtins__ is a dict or not. > > Discovered when running importlib.test.regrtest. Hey Brett, You should import the builtin module and use it here instead for better portability to other impls. As an added bonus, you wouldn't need this check. -- Philip Jenvey From python-checkins at python.org Sat Jun 12 08:26:54 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 12 Jun 2010 08:26:54 +0200 (CEST) Subject: [Python-checkins] r81931 - python/trunk/Doc/tutorial/classes.rst Message-ID: <20100612062654.CDFEFEE9B9@mail.python.org> Author: georg.brandl Date: Sat Jun 12 08:26:54 2010 New Revision: 81931 Log: Fix punctuation. Modified: python/trunk/Doc/tutorial/classes.rst Modified: python/trunk/Doc/tutorial/classes.rst ============================================================================== --- python/trunk/Doc/tutorial/classes.rst (original) +++ python/trunk/Doc/tutorial/classes.rst Sat Jun 12 08:26:54 2010 @@ -537,7 +537,7 @@ ================= "Private" instance variables that cannot be accessed except from inside an -object, don't exist in Python. However, there is a convention that is followed +object don't exist in Python. However, there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. ``_spam``) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject From python-checkins at python.org Sat Jun 12 08:28:58 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 12 Jun 2010 08:28:58 +0200 (CEST) Subject: [Python-checkins] r81932 - python/trunk/Doc/library/os.rst Message-ID: <20100612062858.97B6DEE987@mail.python.org> Author: georg.brandl Date: Sat Jun 12 08:28:58 2010 New Revision: 81932 Log: Document that an existing directory raises in mkdir(). 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 Jun 12 08:28:58 2010 @@ -1175,7 +1175,8 @@ Create a directory named *path* with numeric mode *mode*. The default *mode* is ``0777`` (octal). On some systems, *mode* is ignored. Where it is used, the - current umask value is first masked out. + current umask value is first masked out. If the directory already exists, + :exc:`OSError` is raised. It is also possible to create temporary directories; see the :mod:`tempfile` module's :func:`tempfile.mkdtemp` function. From python-checkins at python.org Sat Jun 12 08:45:34 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 12 Jun 2010 08:45:34 +0200 (CEST) Subject: [Python-checkins] r81933 - python/trunk/README Message-ID: <20100612064534.24602EE985@mail.python.org> Author: georg.brandl Date: Sat Jun 12 08:45:33 2010 New Revision: 81933 Log: Update version in README. Modified: python/trunk/README Modified: python/trunk/README ============================================================================== --- python/trunk/README (original) +++ python/trunk/README Sat Jun 12 08:45:33 2010 @@ -225,8 +225,8 @@ Unsupported systems ------------------- -A number of features are not supported in Python 2.5 anymore. Some -support code is still present, but will be removed in Python 2.6. +A number of systems is not supported in Python 2.7 anymore. Some +support code is still present, but will be removed in later versions. If you still need to use current Python versions on these systems, please send a message to python-dev at python.org indicating that you volunteer to support this system. For a more detailed discussion From python-checkins at python.org Sat Jun 12 08:46:31 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 12 Jun 2010 08:46:31 +0200 (CEST) Subject: [Python-checkins] r81934 - in python/branches/release26-maint: README Message-ID: <20100612064631.95D4FEE987@mail.python.org> Author: georg.brandl Date: Sat Jun 12 08:46:31 2010 New Revision: 81934 Log: Merged revisions 81933 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81933 | georg.brandl | 2010-06-12 08:45:33 +0200 (Sa, 12 Jun 2010) | 1 line Update version in README. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/README Modified: python/branches/release26-maint/README ============================================================================== --- python/branches/release26-maint/README (original) +++ python/branches/release26-maint/README Sat Jun 12 08:46:31 2010 @@ -225,8 +225,8 @@ Unsupported systems ------------------- -A number of features are not supported in Python 2.5 anymore. Some -support code is still present, but will be removed in Python 2.6. +A number of systems is not supported in Python 2.6 anymore. Some +support code is still present, but will be removed in later versions. If you still need to use current Python versions on these systems, please send a message to python-dev at python.org indicating that you volunteer to support this system. For a more detailed discussion From python-checkins at python.org Sat Jun 12 10:49:43 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 10:49:43 +0200 (CEST) Subject: [Python-checkins] r81935 - in python/branches/release26-maint: Lib/test/test_struct.py Modules/_struct.c Message-ID: <20100612084943.0B92DEE9F2@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 10:49:42 2010 New Revision: 81935 Log: Merged revisions 81904 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81904 | mark.dickinson | 2010-06-11 21:27:05 +0100 (Fri, 11 Jun 2010) | 4 lines Fix possible undefined behaviour from signed overflow in struct module. Backport of revisions 81897, 81898 and 81902 from py3k. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_struct.py python/branches/release26-maint/Modules/_struct.c Modified: python/branches/release26-maint/Lib/test/test_struct.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_struct.py (original) +++ python/branches/release26-maint/Lib/test/test_struct.py Sat Jun 12 10:49:42 2010 @@ -12,7 +12,6 @@ import sys ISBIGENDIAN = sys.byteorder == "big" IS32BIT = sys.maxsize == 0x7fffffff -del sys try: import _struct @@ -605,7 +604,12 @@ def test_crasher(self): self.assertRaises(MemoryError, struct.pack, "357913941c", "a") + def test_count_overflow(self): + hugecount = '{0}b'.format(sys.maxsize+1) + self.assertRaises(struct.error, struct.calcsize, hugecount) + hugecount2 = '{0}b{1}H'.format(sys.maxsize//2, sys.maxsize//2) + self.assertRaises(struct.error, struct.calcsize, hugecount2) def test_main(): run_unittest(StructTest) Modified: python/branches/release26-maint/Modules/_struct.c ============================================================================== --- python/branches/release26-maint/Modules/_struct.c (original) +++ python/branches/release26-maint/Modules/_struct.c Sat Jun 12 10:49:42 2010 @@ -1309,16 +1309,19 @@ } -/* Align a size according to a format code */ +/* Align a size according to a format code. Return -1 on overflow. */ -static int +static Py_ssize_t align(Py_ssize_t size, char c, const formatdef *e) { + Py_ssize_t extra; + if (e->format == c) { - if (e->alignment) { - size = ((size + e->alignment - 1) - / e->alignment) - * e->alignment; + if (e->alignment && size > 0) { + extra = (e->alignment - 1) - (size - 1) % (e->alignment); + if (extra > PY_SSIZE_T_MAX - size) + return -1; + size += extra; } } return size; @@ -1337,7 +1340,7 @@ const char *s; const char *fmt; char c; - Py_ssize_t size, len, num, itemsize, x; + Py_ssize_t size, len, num, itemsize; fmt = PyString_AS_STRING(self->s_format); @@ -1352,14 +1355,13 @@ if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { - x = num*10 + (c - '0'); - if (x/10 != num) { - PyErr_SetString( - StructError, - "overflow in item count"); - return -1; - } - num = x; + /* overflow-safe version of + if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ + if (num >= PY_SSIZE_T_MAX / 10 && ( + num > PY_SSIZE_T_MAX / 10 || + (c - '0') > PY_SSIZE_T_MAX % 10)) + goto overflow; + num = num*10 + (c - '0'); } if (c == '\0') break; @@ -1380,13 +1382,13 @@ itemsize = e->size; size = align(size, c, e); - x = num * itemsize; - size += x; - if (x/itemsize != num || size < 0) { - PyErr_SetString(StructError, - "total struct size too long"); - return -1; - } + if (size == -1) + goto overflow; + + /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ + if (num > (PY_SSIZE_T_MAX - size) / itemsize) + goto overflow; + size += num * itemsize; } /* check for overflow */ @@ -1445,6 +1447,11 @@ codes->size = 0; return 0; + + overflow: + PyErr_SetString(StructError, + "total struct size too long"); + return -1; } static PyObject * From python-checkins at python.org Sat Jun 12 11:10:14 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 11:10:14 +0200 (CEST) Subject: [Python-checkins] r81936 - python/branches/py3k/Objects/unicodeobject.c Message-ID: <20100612091014.70BCFEE9F5@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 11:10:14 2010 New Revision: 81936 Log: Silence 'unused variable' gcc warning. Patch by ?ric Araujo. Modified: python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Sat Jun 12 11:10:14 2010 @@ -2737,10 +2737,11 @@ Py_UNICODE *p; #ifndef Py_UNICODE_WIDE int pairs = 0; + const unsigned char *qq; #else const int pairs = 0; #endif - const unsigned char *q, *e, *qq; + const unsigned char *q, *e; int bo = 0; /* assume native ordering by default */ const char *errmsg = ""; /* Offsets from q for retrieving bytes in the right order. */ From python-checkins at python.org Sat Jun 12 11:24:02 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 11:24:02 +0200 (CEST) Subject: [Python-checkins] r81937 - python/branches/py3k/Modules/_struct.c Message-ID: <20100612092402.1CA24EEA14@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 11:24:01 2010 New Revision: 81937 Log: Issue #8981: Remove _struct.__version__. Modified: python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Sat Jun 12 11:24:01 2010 @@ -1965,10 +1965,6 @@ { PyObject *ver, *m; - ver = PyBytes_FromString("0.3"); - if (ver == NULL) - return NULL; - m = PyModule_Create(&_structmodule); if (m == NULL) return NULL; @@ -2029,7 +2025,5 @@ Py_INCREF((PyObject*)&PyStructType); PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType); - PyModule_AddObject(m, "__version__", ver); - return m; } From python-checkins at python.org Sat Jun 12 11:25:14 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 11:25:14 +0200 (CEST) Subject: [Python-checkins] r81938 - python/branches/py3k/Modules/_struct.c Message-ID: <20100612092514.1B65AEE9A1@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 11:25:13 2010 New Revision: 81938 Log: Remove unused variable. Modified: python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Sat Jun 12 11:25:13 2010 @@ -1963,7 +1963,7 @@ PyMODINIT_FUNC PyInit__struct(void) { - PyObject *ver, *m; + PyObject *m; m = PyModule_Create(&_structmodule); if (m == NULL) From python-checkins at python.org Sat Jun 12 11:45:01 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 12 Jun 2010 11:45:01 +0200 (CEST) Subject: [Python-checkins] r81939 - python/trunk/Doc/documenting/markup.rst Message-ID: <20100612094501.64B39EE996@mail.python.org> Author: georg.brandl Date: Sat Jun 12 11:45:01 2010 New Revision: 81939 Log: Use newer toctree syntax. Modified: python/trunk/Doc/documenting/markup.rst Modified: python/trunk/Doc/documenting/markup.rst ============================================================================== --- python/trunk/Doc/documenting/markup.rst (original) +++ python/trunk/Doc/documenting/markup.rst Sat Jun 12 11:45:01 2010 @@ -698,10 +698,10 @@ .. toctree:: :maxdepth: 2 - intro.rst - strings.rst - datatypes.rst - numeric.rst + intro + strings + datatypes + numeric (many more files listed here) This accomplishes two things: @@ -709,8 +709,8 @@ * Tables of contents from all those files are inserted, with a maximum depth of two, that means one nested heading. ``toctree`` directives in those files are also taken into account. - * Sphinx knows that the relative order of the files ``intro.rst``, - ``strings.rst`` and so forth, and it knows that they are children of the + * Sphinx knows that the relative order of the files ``intro``, + ``strings`` and so forth, and it knows that they are children of the shown file, the library index. From this information it generates "next chapter", "previous chapter" and "parent chapter" links. From python-checkins at python.org Sat Jun 12 11:45:28 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 12 Jun 2010 11:45:28 +0200 (CEST) Subject: [Python-checkins] r81940 - in python/trunk/Doc/documenting: building.rst index.rst Message-ID: <20100612094528.C333DEE996@mail.python.org> Author: georg.brandl Date: Sat Jun 12 11:45:28 2010 New Revision: 81940 Log: Add document on how to build. Added: python/trunk/Doc/documenting/building.rst Modified: python/trunk/Doc/documenting/index.rst Added: python/trunk/Doc/documenting/building.rst ============================================================================== --- (empty file) +++ python/trunk/Doc/documenting/building.rst Sat Jun 12 11:45:28 2010 @@ -0,0 +1,91 @@ +Building the documentation +========================== + +You need to have Python 2.4 or higher installed; the toolset used to build the +docs is written in Python. It is called *Sphinx*, it is not included in this +tree, but maintained separately. Also needed are the docutils, supplying the +base markup that Sphinx uses, Jinja, a templating engine, and optionally +Pygments, a code highlighter. + + +Using make +---------- + +Luckily, a Makefile has been prepared so that on Unix, provided you have +installed Python and Subversion, you can just run :: + + make html + +to check out the necessary toolset in the `tools/` subdirectory and build the +HTML output files. To view the generated HTML, point your favorite browser at +the top-level index `build/html/index.html` after running "make". + +Available make targets are: + + * "html", which builds standalone HTML files for offline viewing. + + * "htmlhelp", which builds HTML files and a HTML Help project file usable to + convert them into a single Compiled HTML (.chm) file -- these are popular + under Microsoft Windows, but very handy on every platform. + + To create the CHM file, you need to run the Microsoft HTML Help Workshop + over the generated project (.hhp) file. + + * "latex", which builds LaTeX source files as input to "pdflatex" to produce + PDF documents. + + * "text", which builds a plain text file for each source file. + + * "linkcheck", which checks all external references to see whether they are + broken, redirected or malformed, and outputs this information to stdout + as well as a plain-text (.txt) file. + + * "changes", which builds an overview over all versionadded/versionchanged/ + deprecated items in the current version. This is meant as a help for the + writer of the "What's New" document. + + * "coverage", which builds a coverage overview for standard library modules + and C API. + + * "pydoc-topics", which builds a Python module containing a dictionary with + plain text documentation for the labels defined in + `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic and + keyword help. + +A "make update" updates the Subversion checkouts in `tools/`. + + +Without make +------------ + +You'll need to install the Sphinx package, either by checking it out via :: + + svn co http://svn.python.org/projects/external/Sphinx-0.6.5/sphinx tools/sphinx + +or by installing it from PyPI. + +Then, you need to install Docutils, either by checking it out via :: + + svn co http://svn.python.org/projects/external/docutils-0.6/docutils tools/docutils + +or by installing it from http://docutils.sf.net/. + +You also need Jinja2, either by checking it out via :: + + svn co http://svn.python.org/projects/external/Jinja-2.3.1/jinja2 tools/jinja2 + +or by installing it from PyPI. + +You can optionally also install Pygments, either as a checkout via :: + + svn co http://svn.python.org/projects/external/Pygments-1.3.1/pygments tools/pygments + +or from PyPI at http://pypi.python.org/pypi/Pygments. + + +Then, make an output directory, e.g. under `build/`, and run :: + + python tools/sphinx-build.py -b . build/ + +where `` is one of html, text, latex, or htmlhelp (for explanations see +the make targets above). Modified: python/trunk/Doc/documenting/index.rst ============================================================================== --- python/trunk/Doc/documenting/index.rst (original) +++ python/trunk/Doc/documenting/index.rst Sat Jun 12 11:45:28 2010 @@ -10,9 +10,9 @@ `reStructuredText`_, developed by the `docutils`_ project, amended by custom directives and using a toolset named `Sphinx`_ to postprocess the HTML output. -This document describes the style guide for our documentation, the custom -reStructuredText markup introduced to support Python documentation and how it -should be used, as well as the Sphinx build system. +This document describes the style guide for our documentation as well as the +custom reStructuredText markup introduced by Sphinx to support Python +documentation and how it should be used. .. _reStructuredText: http://docutils.sf.net/rst.html .. _docutils: http://docutils.sf.net/ @@ -35,3 +35,4 @@ rest.rst markup.rst fromlatex.rst + building.rst From python-checkins at python.org Sat Jun 12 11:45:58 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 12 Jun 2010 11:45:58 +0200 (CEST) Subject: [Python-checkins] r81941 - python/trunk/Doc/library/socket.rst Message-ID: <20100612094558.ECAE6EE996@mail.python.org> Author: georg.brandl Date: Sat Jun 12 11:45:58 2010 New Revision: 81941 Log: Fix gratuitous indentation. Modified: python/trunk/Doc/library/socket.rst Modified: python/trunk/Doc/library/socket.rst ============================================================================== --- python/trunk/Doc/library/socket.rst (original) +++ python/trunk/Doc/library/socket.rst Sat Jun 12 11:45:58 2010 @@ -72,18 +72,18 @@ tuple, and the fields depend on the address type. The general tuple form is ``(addr_type, v1, v2, v3 [, scope])``, where: - - *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or - TIPC_ADDR_ID. - - *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and - TIPC_NODE_SCOPE. - - If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is - the port identifier, and *v3* should be 0. + - *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or + TIPC_ADDR_ID. + - *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and + TIPC_NODE_SCOPE. + - If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is + the port identifier, and *v3* should be 0. - If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2* - is the lower port number, and *v3* is the upper port number. + If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2* + is the lower port number, and *v3* is the upper port number. - If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the - reference, and *v3* should be set to 0. + If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the + reference, and *v3* should be set to 0. All errors raise exceptions. The normal exceptions for invalid argument types From python-checkins at python.org Sat Jun 12 11:46:03 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 12 Jun 2010 11:46:03 +0200 (CEST) Subject: [Python-checkins] r81942 - python/trunk/Doc/README.txt Message-ID: <20100612094603.BCB85EEA06@mail.python.org> Author: georg.brandl Date: Sat Jun 12 11:46:03 2010 New Revision: 81942 Log: Update README. Modified: python/trunk/Doc/README.txt Modified: python/trunk/Doc/README.txt ============================================================================== --- python/trunk/Doc/README.txt (original) +++ python/trunk/Doc/README.txt Sat Jun 12 11:46:03 2010 @@ -14,12 +14,11 @@ Building the docs ================= -You need to install Python 2.4 or higher; the toolset used to build the docs are -written in Python. The toolset used to build the documentation is called -*Sphinx*, it is not included in this tree, but maintained separately in the -Python Subversion repository. Also needed are Jinja, a templating engine -(included in Sphinx as a Subversion external), and optionally Pygments, a code -highlighter. +You need to have Python 2.4 or higher installed; the toolset used to build the +docs is written in Python. It is called *Sphinx*, it is not included in this +tree, but maintained separately. Also needed are the docutils, supplying the +base markup that Sphinx uses, Jinja, a templating engine, and optionally +Pygments, a code highlighter. Using make @@ -42,29 +41,29 @@ convert them into a single Compiled HTML (.chm) file -- these are popular under Microsoft Windows, but very handy on every platform. - To create the CHM file, you need to run the Microsoft HTML Help Workshop - over the generated project (.hhp) file. + To create the CHM file, you need to run the Microsoft HTML Help Workshop over + the generated project (.hhp) file. - * "latex", which builds LaTeX source files that can be run with "pdflatex" - to produce PDF documents. + * "latex", which builds LaTeX source files as input to "pdflatex" to produce + PDF documents. * "text", which builds a plain text file for each source file. * "linkcheck", which checks all external references to see whether they are - broken, redirected or malformed, and outputs this information to stdout - as well as a plain-text (.txt) file. + broken, redirected or malformed, and outputs this information to stdout as + well as a plain-text (.txt) file. * "changes", which builds an overview over all versionadded/versionchanged/ deprecated items in the current version. This is meant as a help for the writer of the "What's New" document. - * "coverage", which builds a coverage overview for standard library modules - and C API. + * "coverage", which builds a coverage overview for standard library modules and + C API. - * "pydoc-topics", which builds a Python module containing a dictionary - with plain text documentation for the labels defined in - `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic - and keyword help. + * "pydoc-topics", which builds a Python module containing a dictionary with + plain text documentation for the labels defined in + `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic and + keyword help. A "make update" updates the Subversion checkouts in `tools/`. @@ -90,7 +89,7 @@ or by installing it from PyPI. -You can optionally also install Pygments, either as a checkout via :: +You can optionally also install Pygments, either as a checkout via :: svn co http://svn.python.org/projects/external/Pygments-1.3.1/pygments tools/pygments From python-checkins at python.org Sat Jun 12 11:50:02 2010 From: python-checkins at python.org (georg.brandl) Date: Sat, 12 Jun 2010 11:50:02 +0200 (CEST) Subject: [Python-checkins] r81943 - in python/branches/release26-maint: Doc/README.txt Doc/documenting/building.rst Doc/documenting/index.rst Doc/library/socket.rst Message-ID: <20100612095002.E78DEEE993@mail.python.org> Author: georg.brandl Date: Sat Jun 12 11:50:02 2010 New Revision: 81943 Log: Merged revisions 81940-81942 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81940 | georg.brandl | 2010-06-12 11:45:28 +0200 (Sa, 12 Jun 2010) | 1 line Add document on how to build. ........ r81941 | georg.brandl | 2010-06-12 11:45:58 +0200 (Sa, 12 Jun 2010) | 1 line Fix gratuitous indentation. ........ r81942 | georg.brandl | 2010-06-12 11:46:03 +0200 (Sa, 12 Jun 2010) | 1 line Update README. ........ Added: python/branches/release26-maint/Doc/documenting/building.rst - copied unchanged from r81942, /python/trunk/Doc/documenting/building.rst Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/README.txt python/branches/release26-maint/Doc/documenting/index.rst python/branches/release26-maint/Doc/library/socket.rst Modified: python/branches/release26-maint/Doc/README.txt ============================================================================== --- python/branches/release26-maint/Doc/README.txt (original) +++ python/branches/release26-maint/Doc/README.txt Sat Jun 12 11:50:02 2010 @@ -14,12 +14,11 @@ Building the docs ================= -You need to install Python 2.4 or higher; the toolset used to build the docs are -written in Python. The toolset used to build the documentation is called -*Sphinx*, it is not included in this tree, but maintained separately in the -Python Subversion repository. Also needed are Jinja, a templating engine -(included in Sphinx as a Subversion external), and optionally Pygments, a code -highlighter. +You need to have Python 2.4 or higher installed; the toolset used to build the +docs is written in Python. It is called *Sphinx*, it is not included in this +tree, but maintained separately. Also needed are the docutils, supplying the +base markup that Sphinx uses, Jinja, a templating engine, and optionally +Pygments, a code highlighter. Using make @@ -42,29 +41,29 @@ convert them into a single Compiled HTML (.chm) file -- these are popular under Microsoft Windows, but very handy on every platform. - To create the CHM file, you need to run the Microsoft HTML Help Workshop - over the generated project (.hhp) file. + To create the CHM file, you need to run the Microsoft HTML Help Workshop over + the generated project (.hhp) file. - * "latex", which builds LaTeX source files that can be run with "pdflatex" - to produce PDF documents. + * "latex", which builds LaTeX source files as input to "pdflatex" to produce + PDF documents. * "text", which builds a plain text file for each source file. * "linkcheck", which checks all external references to see whether they are - broken, redirected or malformed, and outputs this information to stdout - as well as a plain-text (.txt) file. + broken, redirected or malformed, and outputs this information to stdout as + well as a plain-text (.txt) file. * "changes", which builds an overview over all versionadded/versionchanged/ deprecated items in the current version. This is meant as a help for the writer of the "What's New" document. - * "coverage", which builds a coverage overview for standard library modules - and C API. + * "coverage", which builds a coverage overview for standard library modules and + C API. - * "pydoc-topics", which builds a Python module containing a dictionary - with plain text documentation for the labels defined in - `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic - and keyword help. + * "pydoc-topics", which builds a Python module containing a dictionary with + plain text documentation for the labels defined in + `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic and + keyword help. A "make update" updates the Subversion checkouts in `tools/`. @@ -90,7 +89,7 @@ or by installing it from PyPI. -You can optionally also install Pygments, either as a checkout via :: +You can optionally also install Pygments, either as a checkout via :: svn co http://svn.python.org/projects/external/Pygments-1.3.1/pygments tools/pygments Modified: python/branches/release26-maint/Doc/documenting/index.rst ============================================================================== --- python/branches/release26-maint/Doc/documenting/index.rst (original) +++ python/branches/release26-maint/Doc/documenting/index.rst Sat Jun 12 11:50:02 2010 @@ -10,9 +10,9 @@ `reStructuredText`_, developed by the `docutils`_ project, amended by custom directives and using a toolset named `Sphinx`_ to postprocess the HTML output. -This document describes the style guide for our documentation, the custom -reStructuredText markup introduced to support Python documentation and how it -should be used, as well as the Sphinx build system. +This document describes the style guide for our documentation as well as the +custom reStructuredText markup introduced by Sphinx to support Python +documentation and how it should be used. .. _reStructuredText: http://docutils.sf.net/rst.html .. _docutils: http://docutils.sf.net/ @@ -35,3 +35,4 @@ rest.rst markup.rst fromlatex.rst + building.rst 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 Jun 12 11:50:02 2010 @@ -72,18 +72,18 @@ tuple, and the fields depend on the address type. The general tuple form is ``(addr_type, v1, v2, v3 [, scope])``, where: - - *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or - TIPC_ADDR_ID. - - *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and - TIPC_NODE_SCOPE. - - If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is - the port identifier, and *v3* should be 0. + - *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or + TIPC_ADDR_ID. + - *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and + TIPC_NODE_SCOPE. + - If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is + the port identifier, and *v3* should be 0. - If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2* - is the lower port number, and *v3* is the upper port number. + If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2* + is the lower port number, and *v3* is the upper port number. - If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the - reference, and *v3* should be set to 0. + If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the + reference, and *v3* should be set to 0. All errors raise exceptions. The normal exceptions for invalid argument types From python-checkins at python.org Sat Jun 12 15:42:46 2010 From: python-checkins at python.org (nick.coghlan) Date: Sat, 12 Jun 2010 15:42:46 +0200 (CEST) Subject: [Python-checkins] r81944 - in python/branches/py3k: Doc/library/doctest.rst Lib/doctest.py Lib/test/test_doctest.py Misc/ACKS Misc/NEWS Message-ID: <20100612134246.BDC3EEE99E@mail.python.org> Author: nick.coghlan Date: Sat Jun 12 15:42:46 2010 New Revision: 81944 Log: Merged revisions 80578 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r80578 | nick.coghlan | 2010-04-29 00:29:06 +1000 (Thu, 29 Apr 2010) | 1 line Issue 7490: make IGNORE_EXCEPTION_DETAIL also ignore details of the module containing the exception under test (original patch by Lennart Regebro) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/doctest.rst python/branches/py3k/Lib/doctest.py python/branches/py3k/Lib/test/test_doctest.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k/Doc/library/doctest.rst (original) +++ python/branches/py3k/Doc/library/doctest.rst Sat Jun 12 15:42:46 2010 @@ -444,8 +444,9 @@ with an alphanumeric is taken to be the start of the exception detail. Of course this does the right thing for genuine tracebacks. -* When the :const:`IGNORE_EXCEPTION_DETAIL` doctest option is is specified, - everything following the leftmost colon is ignored. +* When the :const:`IGNORE_EXCEPTION_DETAIL` doctest option is specified, + everything following the leftmost colon and any module information in the + exception name is ignored. * The interactive shell omits the traceback header line for some :exc:`SyntaxError`\ s. But doctest uses the traceback header line to @@ -535,20 +536,38 @@ exception raised is ``ValueError: 3*14``, but will fail, e.g., if :exc:`TypeError` is raised. - Note that a similar effect can be obtained using :const:`ELLIPSIS`, and - :const:`IGNORE_EXCEPTION_DETAIL` may go away when Python releases prior to 2.4 - become uninteresting. Until then, :const:`IGNORE_EXCEPTION_DETAIL` is the only - clear way to write a doctest that doesn't care about the exception detail yet - continues to pass under Python releases prior to 2.4 (doctest directives appear - to be comments to them). For example, :: + It will also ignore the module name used in Python 3 doctest reports. Hence + both these variations will work regardless of whether the test is run under + Python 2.7 or Python 3.2 (or later versions): + + >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + CustomError: message + + >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + my_module.CustomError: message + + Note that :const:`ELLIPSIS` can also be used to ignore the + details of the exception message, but such a test may still fail based + on whether or not the module details are printed as part of the + exception name. Using :const:`IGNORE_EXCEPTION_DETAIL` and the details + from Python 2.3 is also the only clear way to write a doctest that doesn't + care about the exception detail yet continues to pass under Python 2.3 or + earlier (those releases do not support doctest directives and ignore them + as irrelevant comments). For example, :: >>> (1, 2)[3] = 'moo' #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): File "", line 1, in ? TypeError: object doesn't support item assignment - passes under Python 2.4 and Python 2.3. The detail changed in 2.4, to say "does - not" instead of "doesn't". + passes under Python 2.3 and later Python versions, even though the detail + changed in Python 2.4 to say "does not" instead of "doesn't". + + .. versionchanged:: 3.2 + :const:`IGNORE_EXCEPTION_DETAIL` now also ignores any information + relating to the module containing the exception under test .. data:: SKIP @@ -663,7 +682,6 @@ functions that run doctests, establishing different defaults. In such cases, disabling an option via ``-`` in a directive can be useful. - There's also a way to register new option flag names, although this isn't useful unless you intend to extend :mod:`doctest` internals via subclassing: Modified: python/branches/py3k/Lib/doctest.py ============================================================================== --- python/branches/py3k/Lib/doctest.py (original) +++ python/branches/py3k/Lib/doctest.py Sat Jun 12 15:42:46 2010 @@ -1277,9 +1277,9 @@ # Another chance if they didn't care about the detail. elif self.optionflags & IGNORE_EXCEPTION_DETAIL: - m1 = re.match(r'[^:]*:', example.exc_msg) - m2 = re.match(r'[^:]*:', exc_msg) - if m1 and m2 and check(m1.group(0), m2.group(0), + m1 = re.match(r'(?:[^:]*\.)?([^:]*:)', example.exc_msg) + m2 = re.match(r'(?:[^:]*\.)?([^:]*:)', exc_msg) + if m1 and m2 and check(m1.group(1), m2.group(1), self.optionflags): outcome = SUCCESS Modified: python/branches/py3k/Lib/test/test_doctest.py ============================================================================== --- python/branches/py3k/Lib/test/test_doctest.py (original) +++ python/branches/py3k/Lib/test/test_doctest.py Sat Jun 12 15:42:46 2010 @@ -864,6 +864,77 @@ >>> doctest.DocTestRunner(verbose=False).run(test) TestResults(failed=0, attempted=1) +IGNORE_EXCEPTION_DETAIL also ignores difference in exception formatting +between Python versions. For example, in Python 2.x, the module path of +the exception is not in the output, but this will fail under Python 3: + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') + ... Traceback (most recent call last): + ... HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 4, in f + Failed example: + raise HTTPException('message') + Expected: + Traceback (most recent call last): + HTTPException: message + Got: + Traceback (most recent call last): + ... + http.client.HTTPException: message + TestResults(failed=1, attempted=2) + +But in Python 3 the module path is included, and therefore a test must look +like the following test to succeed in Python 3. But that test will fail under +Python 2. + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') + ... Traceback (most recent call last): + ... http.client.HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + +However, with IGNORE_EXCEPTION_DETAIL, the module name of the exception +(or its unexpected absence) will be ignored: + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + +The module path will be completely ignored, so two different module paths will +still pass if IGNORE_EXCEPTION_DETAIL is given. This is intentional, so it can +be used when exceptions have changed module. + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... foo.bar.HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type: >>> def f(x): Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Sat Jun 12 15:42:46 2010 @@ -638,6 +638,7 @@ John Redford Terry Reedy Steve Reeves +Lennart Regebro Ofir Reichenberg Sean Reifschneider Michael P. Reilly Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jun 12 15:42:46 2010 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #7490: to facilitate sharing of doctests between 2.x and 3.x test + suites, the IGNORE_EXCEPTION_DETAIL directive now also ignores the module + location of the raised exception. + - Issue #8969: On Windows, use mbcs codec in strict mode to encode and decode filenames and enable os.fsencode(). From python-checkins at python.org Sat Jun 12 15:45:37 2010 From: python-checkins at python.org (nick.coghlan) Date: Sat, 12 Jun 2010 15:45:37 +0200 (CEST) Subject: [Python-checkins] r81945 - python/trunk/Doc/library/doctest.rst Message-ID: <20100612134537.53D14EEA38@mail.python.org> Author: nick.coghlan Date: Sat Jun 12 15:45:37 2010 New Revision: 81945 Log: Backport a fix from Py3k for a potentially misleading example Modified: python/trunk/Doc/library/doctest.rst Modified: python/trunk/Doc/library/doctest.rst ============================================================================== --- python/trunk/Doc/library/doctest.rst (original) +++ python/trunk/Doc/library/doctest.rst Sat Jun 12 15:45:37 2010 @@ -576,13 +576,13 @@ both these variations will work regardless of whether the test is run under Python 2.7 or Python 3.2 (or later versions): - >>> raise ValueError('message') #doctest: +IGNORE_EXCEPTION_DETAIL + >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): - ValueError: message + CustomError: message - >>> raise ValueError('message') #doctest: +IGNORE_EXCEPTION_DETAIL + >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): - builtin.ValueError: message + my_module.CustomError: message Note that :const:`ELLIPSIS` can also be used to ignore the details of the exception message, but such a test may still fail based From python-checkins at python.org Sat Jun 12 15:46:57 2010 From: python-checkins at python.org (nick.coghlan) Date: Sat, 12 Jun 2010 15:46:57 +0200 (CEST) Subject: [Python-checkins] r81946 - python/branches/py3k Message-ID: <20100612134657.131C1EEA5A@mail.python.org> Author: nick.coghlan Date: Sat Jun 12 15:46:56 2010 New Revision: 81946 Log: Blocked revisions 81945 via svnmerge ........ r81945 | nick.coghlan | 2010-06-12 23:45:37 +1000 (Sat, 12 Jun 2010) | 1 line Backport a fix from Py3k for a potentially misleading example ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Jun 12 17:17:02 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 17:17:02 +0200 (CEST) Subject: [Python-checkins] r81947 - in python/branches/py3k: Lib/struct.py Misc/NEWS Modules/_struct.c Message-ID: <20100612151702.C1279EEA84@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 17:17:02 2010 New Revision: 81947 Log: Issue #8973: Add __all__ to struct module, so that help(struct) correctly displays information for the struct.Struct class. Modified: python/branches/py3k/Lib/struct.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Lib/struct.py ============================================================================== --- python/branches/py3k/Lib/struct.py (original) +++ python/branches/py3k/Lib/struct.py Sat Jun 12 17:17:02 2010 @@ -1,3 +1,14 @@ +__all__ = [ + # Functions + 'calcsize', 'pack', 'unpack', 'unpack', 'unpack_from', + + # Classes + 'Struct', + + # Exceptions + 'error' + ] + from _struct import * from _struct import _clearcache from _struct import __doc__ Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jun 12 17:17:02 2010 @@ -1299,6 +1299,9 @@ Extension Modules ----------------- +- Issue #8973: Add __all__ to struct module; this ensures that + help(struct) includes documentation for the struct.Struct class. + - Issue #3129: Trailing digits in format string are no longer ignored. For example, "1" or "ilib123" are now invalid formats and cause ``struct.error`` to be raised. Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Sat Jun 12 17:17:02 2010 @@ -1398,9 +1398,8 @@ PyDoc_STRVAR(s_unpack__doc__, "S.unpack(buffer) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\ -strings."); +Return a tuple containing values unpacked according to S.format. Requires\n\ +len(buffer) == S.size. See help(struct) for more on format strings."); static PyObject * s_unpack(PyObject *self, PyObject *input) @@ -1426,12 +1425,10 @@ } PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\ +"S.unpack_from(buffer[, offset=0]) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Unlike unpack, unpack_from can unpack values from any object supporting\n\ -the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\ -See struct.__doc__ for more on format strings."); +Return a tuple containing values unpacked according to S.format. Requires\n\ +len(buffer[offset:]) >= S.size. See help(struct) for more on format strings."); static PyObject * s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds) @@ -1566,8 +1563,8 @@ PyDoc_STRVAR(s_pack__doc__, "S.pack(v1, v2, ...) -> bytes\n\ \n\ -Return a bytes containing values v1, v2, ... packed according to this\n\ -Struct's format. See struct.__doc__ for more on format strings."); +Return a bytes object containing values v1, v2, ... packed according to\n\ +S.format. See help(struct) for more on format strings."); static PyObject * s_pack(PyObject *self, PyObject *args) @@ -1603,10 +1600,9 @@ PyDoc_STRVAR(s_pack_into__doc__, "S.pack_into(buffer, offset, v1, v2, ...)\n\ \n\ -Pack the values v1, v2, ... according to this Struct's format, write \n\ -the packed bytes into the writable buffer buf starting at offset. Note\n\ -that the offset is not an optional argument. See struct.__doc__ for \n\ -more on format strings."); +Pack the values v1, v2, ... according to S.format and write the packed bytes\n\ +into the writable buffer buf starting at offset. Note that the offset is not\n\ +an optional argument. See help(struct) for more on format strings."); static PyObject * s_pack_into(PyObject *self, PyObject *args) @@ -1796,7 +1792,10 @@ } PyDoc_STRVAR(pack_doc, -"Return bytes containing values v1, v2, ... packed according to fmt."); +"pack(fmt, v1, v2, ...) -> bytes\n\ +\n\ +Return a bytes object containing values v1, v2, ... packed according to fmt.\n\ +See help(struct) for more on format strings."); static PyObject * pack(PyObject *self, PyObject *args) @@ -1825,8 +1824,11 @@ } PyDoc_STRVAR(pack_into_doc, -"Pack the values v1, v2, ... according to fmt.\n\ -Write the packed bytes into the writable buffer buf starting at offset."); +"pack_into(fmt, buffer, offset, v1, v2, ...)\n\ +\n\ +Pack the values v1, v2, ... according to fmt and write the packed bytes into\n\ +the writable buffer buf starting at offset. Note that the offset is not an\n\ +optional argument. See help(struct) for more on format strings."); static PyObject * pack_into(PyObject *self, PyObject *args) @@ -1855,8 +1857,10 @@ } PyDoc_STRVAR(unpack_doc, -"Unpack the bytes containing packed C structure data, according to fmt.\n\ -Requires len(bytes) == calcsize(fmt)."); +"unpack(fmt, buffer) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to fmt. Requires\n\ +len(buffer) == calcsize(fmt). See help(struct) for more on format strings."); static PyObject * unpack(PyObject *self, PyObject *args) @@ -1875,8 +1879,11 @@ } PyDoc_STRVAR(unpack_from_doc, -"Unpack the buffer, containing packed C structure data, according to\n\ -fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt)."); +"unpack_from(fmt, buffer[, offset=0]) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to fmt. Requires\n\ +len(buffer[offset:]) >= calcsize(fmt). See help(struct) for more on format\n\ +strings."); static PyObject * unpack_from(PyObject *self, PyObject *args, PyObject *kwds) From python-checkins at python.org Sat Jun 12 17:19:23 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 17:19:23 +0200 (CEST) Subject: [Python-checkins] r81948 - python/branches/py3k/Modules/_struct.c Message-ID: <20100612151923.85036EEA9E@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 17:19:23 2010 New Revision: 81948 Log: Remove accidental (yet-to-be-reviewed) docstring changes included in r81947. Modified: python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Sat Jun 12 17:19:23 2010 @@ -1398,8 +1398,9 @@ PyDoc_STRVAR(s_unpack__doc__, "S.unpack(buffer) -> (v1, v2, ...)\n\ \n\ -Return a tuple containing values unpacked according to S.format. Requires\n\ -len(buffer) == S.size. See help(struct) for more on format strings."); +Return tuple containing values unpacked according to this Struct's format.\n\ +Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\ +strings."); static PyObject * s_unpack(PyObject *self, PyObject *input) @@ -1425,10 +1426,12 @@ } PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer[, offset=0]) -> (v1, v2, ...)\n\ +"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\ \n\ -Return a tuple containing values unpacked according to S.format. Requires\n\ -len(buffer[offset:]) >= S.size. See help(struct) for more on format strings."); +Return tuple containing values unpacked according to this Struct's format.\n\ +Unlike unpack, unpack_from can unpack values from any object supporting\n\ +the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\ +See struct.__doc__ for more on format strings."); static PyObject * s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds) @@ -1563,8 +1566,8 @@ PyDoc_STRVAR(s_pack__doc__, "S.pack(v1, v2, ...) -> bytes\n\ \n\ -Return a bytes object containing values v1, v2, ... packed according to\n\ -S.format. See help(struct) for more on format strings."); +Return a bytes containing values v1, v2, ... packed according to this\n\ +Struct's format. See struct.__doc__ for more on format strings."); static PyObject * s_pack(PyObject *self, PyObject *args) @@ -1600,9 +1603,10 @@ PyDoc_STRVAR(s_pack_into__doc__, "S.pack_into(buffer, offset, v1, v2, ...)\n\ \n\ -Pack the values v1, v2, ... according to S.format and write the packed bytes\n\ -into the writable buffer buf starting at offset. Note that the offset is not\n\ -an optional argument. See help(struct) for more on format strings."); +Pack the values v1, v2, ... according to this Struct's format, write \n\ +the packed bytes into the writable buffer buf starting at offset. Note\n\ +that the offset is not an optional argument. See struct.__doc__ for \n\ +more on format strings."); static PyObject * s_pack_into(PyObject *self, PyObject *args) @@ -1792,10 +1796,7 @@ } PyDoc_STRVAR(pack_doc, -"pack(fmt, v1, v2, ...) -> bytes\n\ -\n\ -Return a bytes object containing values v1, v2, ... packed according to fmt.\n\ -See help(struct) for more on format strings."); +"Return bytes containing values v1, v2, ... packed according to fmt."); static PyObject * pack(PyObject *self, PyObject *args) @@ -1824,11 +1825,8 @@ } PyDoc_STRVAR(pack_into_doc, -"pack_into(fmt, buffer, offset, v1, v2, ...)\n\ -\n\ -Pack the values v1, v2, ... according to fmt and write the packed bytes into\n\ -the writable buffer buf starting at offset. Note that the offset is not an\n\ -optional argument. See help(struct) for more on format strings."); +"Pack the values v1, v2, ... according to fmt.\n\ +Write the packed bytes into the writable buffer buf starting at offset."); static PyObject * pack_into(PyObject *self, PyObject *args) @@ -1857,10 +1855,8 @@ } PyDoc_STRVAR(unpack_doc, -"unpack(fmt, buffer) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to fmt. Requires\n\ -len(buffer) == calcsize(fmt). See help(struct) for more on format strings."); +"Unpack the bytes containing packed C structure data, according to fmt.\n\ +Requires len(bytes) == calcsize(fmt)."); static PyObject * unpack(PyObject *self, PyObject *args) @@ -1879,11 +1875,8 @@ } PyDoc_STRVAR(unpack_from_doc, -"unpack_from(fmt, buffer[, offset=0]) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to fmt. Requires\n\ -len(buffer[offset:]) >= calcsize(fmt). See help(struct) for more on format\n\ -strings."); +"Unpack the buffer, containing packed C structure data, according to\n\ +fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt)."); static PyObject * unpack_from(PyObject *self, PyObject *args, PyObject *kwds) From python-checkins at python.org Sat Jun 12 17:43:45 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 17:43:45 +0200 (CEST) Subject: [Python-checkins] r81949 - python/branches/py3k/Modules/_struct.c Message-ID: <20100612154345.58AFFEEAAE@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 17:43:45 2010 New Revision: 81949 Log: Issue #8973: Improve struct module docstrings. Modified: python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Sat Jun 12 17:43:45 2010 @@ -1398,9 +1398,9 @@ PyDoc_STRVAR(s_unpack__doc__, "S.unpack(buffer) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\ -strings."); +Return a tuple containing values unpacked according to the format\n\ +string S.format. Requires len(buffer) == S.size. See help(struct)\n\ +for more on format strings."); static PyObject * s_unpack(PyObject *self, PyObject *input) @@ -1426,12 +1426,11 @@ } PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\ +"S.unpack_from(buffer[, offset=0]) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Unlike unpack, unpack_from can unpack values from any object supporting\n\ -the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\ -See struct.__doc__ for more on format strings."); +Return a tuple containing values unpacked according to the format\n\ +string S.format. Requires len(buffer[offset:]) >= S.size. See\n\ +help(struct) for more on format strings."); static PyObject * s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds) @@ -1566,8 +1565,9 @@ PyDoc_STRVAR(s_pack__doc__, "S.pack(v1, v2, ...) -> bytes\n\ \n\ -Return a bytes containing values v1, v2, ... packed according to this\n\ -Struct's format. See struct.__doc__ for more on format strings."); +Return a bytes object containing values v1, v2, ... packed according\n\ +to the format string S.format. See help(struct) for more on format\n\ +strings."); static PyObject * s_pack(PyObject *self, PyObject *args) @@ -1603,10 +1603,10 @@ PyDoc_STRVAR(s_pack_into__doc__, "S.pack_into(buffer, offset, v1, v2, ...)\n\ \n\ -Pack the values v1, v2, ... according to this Struct's format, write \n\ -the packed bytes into the writable buffer buf starting at offset. Note\n\ -that the offset is not an optional argument. See struct.__doc__ for \n\ -more on format strings."); +Pack the values v1, v2, ... according to the format string S.format\n\ +and write the packed bytes into the writable buffer buf starting at\n\ +offset. Note that the offset is not an optional argument. See\n\ +help(struct) for more on format strings."); static PyObject * s_pack_into(PyObject *self, PyObject *args) @@ -1781,7 +1781,9 @@ } PyDoc_STRVAR(calcsize_doc, -"Return size of C struct described by format string fmt."); +"calcsize(fmt) -> integer\n\ +\n\ +Return size in bytes of the struct described by the format string fmt."); static PyObject * calcsize(PyObject *self, PyObject *fmt) @@ -1796,7 +1798,10 @@ } PyDoc_STRVAR(pack_doc, -"Return bytes containing values v1, v2, ... packed according to fmt."); +"pack(fmt, v1, v2, ...) -> bytes\n\ +\n\ +Return a bytes object containing values v1, v2, ... packed according to\n\ +the format string fmt. See help(struct) for more on format strings."); static PyObject * pack(PyObject *self, PyObject *args) @@ -1825,8 +1830,12 @@ } PyDoc_STRVAR(pack_into_doc, -"Pack the values v1, v2, ... according to fmt.\n\ -Write the packed bytes into the writable buffer buf starting at offset."); +"pack_into(fmt, buffer, offset, v1, v2, ...)\n\ +\n\ +Pack the values v1, v2, ... according to the format string fmt and write\n\ +the packed bytes into the writable buffer buf starting at offset. Note\n\ +that the offset is not an optional argument. See help(struct) for more\n\ +on format strings."); static PyObject * pack_into(PyObject *self, PyObject *args) @@ -1855,8 +1864,11 @@ } PyDoc_STRVAR(unpack_doc, -"Unpack the bytes containing packed C structure data, according to fmt.\n\ -Requires len(bytes) == calcsize(fmt)."); +"unpack(fmt, buffer) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to the format string\n\ +fmt. Requires len(buffer) == calcsize(fmt). See help(struct) for more\n\ +on format strings."); static PyObject * unpack(PyObject *self, PyObject *args) @@ -1875,8 +1887,11 @@ } PyDoc_STRVAR(unpack_from_doc, -"Unpack the buffer, containing packed C structure data, according to\n\ -fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt)."); +"unpack_from(fmt, buffer[, offset=0]) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to the format string\n\ +fmt. Requires len(buffer[offset:]) >= calcsize(fmt). See help(struct)\n\ +for more on format strings."); static PyObject * unpack_from(PyObject *self, PyObject *args, PyObject *kwds) From python-checkins at python.org Sat Jun 12 18:30:53 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 18:30:53 +0200 (CEST) Subject: [Python-checkins] r81950 - in python/branches/py3k: Doc/library/struct.rst Modules/_struct.c Message-ID: <20100612163053.B5A48EEA62@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 18:30:53 2010 New Revision: 81950 Log: More struct module docs and docstring tweaks. Modified: python/branches/py3k/Doc/library/struct.rst python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Doc/library/struct.rst ============================================================================== --- python/branches/py3k/Doc/library/struct.rst (original) +++ python/branches/py3k/Doc/library/struct.rst Sat Jun 12 18:30:53 2010 @@ -38,38 +38,38 @@ .. function:: pack(fmt, v1, v2, ...) - Return a bytes containing the values ``v1, v2, ...`` packed according to the - given format. The arguments must match the values required by the format - exactly. + Return a bytes object containing the values *v1*, *v2*, ... packed according + to the format string *fmt*. The arguments must match the values required by + the format exactly. .. function:: pack_into(fmt, buffer, offset, v1, v2, ...) - Pack the values ``v1, v2, ...`` according to the given format, write the - packed bytes into the writable *buffer* starting at *offset*. Note that the - offset is a required argument. + Pack the values *v1*, *v2*, ... according to the format string *fmt* and + write the packed bytes into the writable buffer *buffer* starting at + position *offset*. Note that *offset* is a required argument. -.. function:: unpack(fmt, bytes) +.. function:: unpack(fmt, buffer) - Unpack the bytes (presumably packed by ``pack(fmt, ...)``) according to the - given format. The result is a tuple even if it contains exactly one item. - The bytes must contain exactly the amount of data required by the format - (``len(bytes)`` must equal ``calcsize(fmt)``). + Unpack from the buffer *buffer* (presumably packed by ``pack(fmt, ...)``) + according to the format string *fmt*. The result is a tuple even if it + contains exactly one item. The buffer must contain exactly the amount of + data required by the format (``len(bytes)`` must equal ``calcsize(fmt)``). .. function:: unpack_from(fmt, buffer, offset=0) - Unpack the *buffer* according to the given format. The result is a tuple even - if it contains exactly one item. The *buffer* must contain at least the - amount of data required by the format (``len(buffer[offset:])`` must be at - least ``calcsize(fmt)``). + Unpack from *buffer* starting at position *offset*, according to the format + string *fmt*. The result is a tuple even if it contains exactly one + item. *buffer* must contain at least the amount of data required by the + format (``len(buffer[offset:])`` must be at least ``calcsize(fmt)``). .. function:: calcsize(fmt) - Return the size of the struct (and hence of the bytes) corresponding to the - given format. + Return the size of the struct (and hence of the bytes object produced by + ``pack(fmt, ...)``) corresponding to the format string *fmt*. .. _struct-format-strings: @@ -358,10 +358,10 @@ Identical to the :func:`pack_into` function, using the compiled format. - .. method:: unpack(bytes) + .. method:: unpack(buffer) Identical to the :func:`unpack` function, using the compiled format. - (``len(bytes)`` must equal :attr:`self.size`). + (``len(buffer)`` must equal :attr:`self.size`). .. method:: unpack_from(buffer, offset=0) @@ -376,6 +376,6 @@ .. attribute:: size - The calculated size of the struct (and hence of the bytes) corresponding - to :attr:`format`. + The calculated size of the struct (and hence of the bytes object produced + by the :meth:`pack` method) corresponding to :attr:`format`. Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Sat Jun 12 18:30:53 2010 @@ -1605,7 +1605,7 @@ \n\ Pack the values v1, v2, ... according to the format string S.format\n\ and write the packed bytes into the writable buffer buf starting at\n\ -offset. Note that the offset is not an optional argument. See\n\ +offset. Note that the offset is a required argument. See\n\ help(struct) for more on format strings."); static PyObject * @@ -1800,8 +1800,8 @@ PyDoc_STRVAR(pack_doc, "pack(fmt, v1, v2, ...) -> bytes\n\ \n\ -Return a bytes object containing values v1, v2, ... packed according to\n\ -the format string fmt. See help(struct) for more on format strings."); +Return a bytes object containing the values v1, v2, ... packed according\n\ +to the format string fmt. See help(struct) for more on format strings."); static PyObject * pack(PyObject *self, PyObject *args) @@ -1834,7 +1834,7 @@ \n\ Pack the values v1, v2, ... according to the format string fmt and write\n\ the packed bytes into the writable buffer buf starting at offset. Note\n\ -that the offset is not an optional argument. See help(struct) for more\n\ +that the offset is a required argument. See help(struct) for more\n\ on format strings."); static PyObject * From python-checkins at python.org Sat Jun 12 18:37:53 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 18:37:53 +0200 (CEST) Subject: [Python-checkins] r81951 - python/branches/py3k/Lib/decimal.py Message-ID: <20100612163753.B03DBEEA62@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 18:37:53 2010 New Revision: 81951 Log: Fix mild type confusion in decimal module docstring. Modified: python/branches/py3k/Lib/decimal.py Modified: python/branches/py3k/Lib/decimal.py ============================================================================== --- python/branches/py3k/Lib/decimal.py (original) +++ python/branches/py3k/Lib/decimal.py Sat Jun 12 18:37:53 2010 @@ -31,7 +31,8 @@ useful for financial applications or for contexts where users have expectations that are at odds with binary floating point (for instance, in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead -of the expected Decimal('0.00') returned by decimal floating point). +of 0.0; Decimal('1.00') % Decimal('0.1') returns the expected +Decimal('0.00')). Here are some examples of using the decimal module: From python-checkins at python.org Sat Jun 12 19:18:45 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Sat, 12 Jun 2010 19:18:45 +0200 (CEST) Subject: [Python-checkins] r81952 - in python/branches/py3k/Misc: ACKS NEWS Message-ID: <20100612171845.D5F46EEA11@mail.python.org> Author: alexander.belopolsky Date: Sat Jun 12 19:18:45 2010 New Revision: 81952 Log: Added acknowlegement for Issue #3129 Modified: python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Sat Jun 12 19:18:45 2010 @@ -188,6 +188,7 @@ Erik Demaine Roger Dev Raghuram Devarakonda +Caleb Deveraux Toby Dickenson Mark Dickinson Jack Diederich Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jun 12 19:18:45 2010 @@ -1302,9 +1302,9 @@ - Issue #8973: Add __all__ to struct module; this ensures that help(struct) includes documentation for the struct.Struct class. -- Issue #3129: Trailing digits in format string are no longer ignored. +- Issue #3129: Trailing digits in struct format string are no longer ignored. For example, "1" or "ilib123" are now invalid formats and cause - ``struct.error`` to be raised. + ``struct.error`` to be raised. Patch by Caleb Deveraux. - Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it From python-checkins at python.org Sat Jun 12 19:47:06 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 12 Jun 2010 19:47:06 +0200 (CEST) Subject: [Python-checkins] r81953 - python/trunk/Objects/unicodeobject.c Message-ID: <20100612174706.E38B5EE987@mail.python.org> Author: benjamin.peterson Date: Sat Jun 12 19:47:06 2010 New Revision: 81953 Log: fix warning with ucs4 Modified: python/trunk/Objects/unicodeobject.c Modified: python/trunk/Objects/unicodeobject.c ============================================================================== --- python/trunk/Objects/unicodeobject.c (original) +++ python/trunk/Objects/unicodeobject.c Sat Jun 12 19:47:06 2010 @@ -2208,10 +2208,11 @@ Py_UNICODE *p; #ifndef Py_UNICODE_WIDE int pairs = 0; + const unsigned char *qq; #else const int pairs = 0; #endif - const unsigned char *q, *e, *qq; + const unsigned char *q, *e; int bo = 0; /* assume native ordering by default */ const char *errmsg = ""; /* Offsets from q for retrieving bytes in the right order. */ From python-checkins at python.org Sat Jun 12 19:54:44 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 12 Jun 2010 19:54:44 +0200 (CEST) Subject: [Python-checkins] r81954 - python/branches/py3k Message-ID: <20100612175444.D4CC0EE987@mail.python.org> Author: benjamin.peterson Date: Sat Jun 12 19:54:44 2010 New Revision: 81954 Log: Merged revisions 81953 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81953 | benjamin.peterson | 2010-06-12 12:47:06 -0500 (Sat, 12 Jun 2010) | 1 line fix warning with ucs4 ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Jun 12 20:20:48 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 20:20:48 +0200 (CEST) Subject: [Python-checkins] r81955 - python/branches/py3k/Doc/library/struct.rst Message-ID: <20100612182048.270DAEEA87@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 20:20:47 2010 New Revision: 81955 Log: Issue #8649: add standard sizes to struct docs table. Modified: python/branches/py3k/Doc/library/struct.rst Modified: python/branches/py3k/Doc/library/struct.rst ============================================================================== --- python/branches/py3k/Doc/library/struct.rst (original) +++ python/branches/py3k/Doc/library/struct.rst Sat Jun 12 20:20:47 2010 @@ -87,46 +87,46 @@ Format characters have the following meaning; the conversion between C and Python values should be obvious given their types: -+--------+-------------------------+--------------------+------------+ -| Format | C Type | Python | Notes | -+========+=========================+====================+============+ -| ``x`` | pad byte | no value | | -+--------+-------------------------+--------------------+------------+ -| ``c`` | :ctype:`char` | bytes of length 1 | | -+--------+-------------------------+--------------------+------------+ -| ``b`` | :ctype:`signed char` | integer | \(1),\(4) | -+--------+-------------------------+--------------------+------------+ -| ``B`` | :ctype:`unsigned char` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``?`` | :ctype:`_Bool` | bool | \(2) | -+--------+-------------------------+--------------------+------------+ -| ``h`` | :ctype:`short` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``H`` | :ctype:`unsigned short` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``i`` | :ctype:`int` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``I`` | :ctype:`unsigned int` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``l`` | :ctype:`long` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``L`` | :ctype:`unsigned long` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``q`` | :ctype:`long long` | integer | \(3), \(4) | -+--------+-------------------------+--------------------+------------+ -| ``Q`` | :ctype:`unsigned long | integer | \(3), \(4) | -| | long` | | | -+--------+-------------------------+--------------------+------------+ -| ``f`` | :ctype:`float` | float | | -+--------+-------------------------+--------------------+------------+ -| ``d`` | :ctype:`double` | float | | -+--------+-------------------------+--------------------+------------+ -| ``s`` | :ctype:`char[]` | bytes | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``p`` | :ctype:`char[]` | bytes | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | -+--------+-------------------------+--------------------+------------+ ++--------+-------------------------+--------------------+----------------+------------+ +| Format | C Type | Python type | Standard size | Notes | ++========+=========================+====================+================+============+ +| ``x`` | pad byte | no value | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``c`` | :ctype:`char` | bytes of length 1 | 1 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``b`` | :ctype:`signed char` | integer | 1 | \(1),\(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``B`` | :ctype:`unsigned char` | integer | 1 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``?`` | :ctype:`_Bool` | bool | 1 | \(2) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``h`` | :ctype:`short` | integer | 2 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``H`` | :ctype:`unsigned short` | integer | 2 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``i`` | :ctype:`int` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``I`` | :ctype:`unsigned int` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``l`` | :ctype:`long` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``L`` | :ctype:`unsigned long` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``q`` | :ctype:`long long` | integer | 8 | \(3), \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``Q`` | :ctype:`unsigned long | integer | 8 | \(3), \(4) | +| | long` | | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``f`` | :ctype:`float` | float | 4 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``d`` | :ctype:`double` | float | 8 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``s`` | :ctype:`char[]` | bytes | | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``p`` | :ctype:`char[]` | bytes | | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``P`` | :ctype:`void \*` | integer | | | ++--------+-------------------------+--------------------+----------------+------------+ Notes: From python-checkins at python.org Sat Jun 12 20:36:16 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 20:36:16 +0200 (CEST) Subject: [Python-checkins] r81955 - svn:log Message-ID: <20100612183616.1350AEE99D@mail.python.org> Author: mark.dickinson Revision: 81955 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -Issue #8649: add standard sizes to struct docs table. \ No newline at end of file +Issue #8469: add standard sizes to struct docs table. \ No newline at end of file From python-checkins at python.org Sat Jun 12 20:37:54 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 20:37:54 +0200 (CEST) Subject: [Python-checkins] r81956 - python/branches/py3k/Doc/library/struct.rst Message-ID: <20100612183754.9539FEE99D@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 20:37:54 2010 New Revision: 81956 Log: Issue #8469: Reorder struct module sections for clarity; other minor tweaks. Modified: python/branches/py3k/Doc/library/struct.rst Modified: python/branches/py3k/Doc/library/struct.rst ============================================================================== --- python/branches/py3k/Doc/library/struct.rst (original) +++ python/branches/py3k/Doc/library/struct.rst Sat Jun 12 20:37:54 2010 @@ -77,9 +77,84 @@ -------------- Format strings are the mechanism used to specify the expected layout when -packing and unpacking data. They are built up from format characters, which -specify the type of data being packed/unpacked. In addition, there are -special characters for controlling the byte order, size, and alignment. +packing and unpacking data. They are built up from :ref:`format-characters`, +which specify the type of data being packed/unpacked. In addition, there are +special characters for controlling the :ref:`struct-alignment`. + + +.. _struct-alignment: + +Byte Order, Size, and Alignment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, C types are represented in the machine's native format and byte +order, and properly aligned by skipping pad bytes if necessary (according to the +rules used by the C compiler). + +Alternatively, the first character of the format string can be used to indicate +the byte order, size and alignment of the packed data, according to the +following table: + ++-----------+------------------------+--------------------+ +| Character | Byte order | Size and alignment | ++===========+========================+====================+ +| ``@`` | native | native | ++-----------+------------------------+--------------------+ +| ``=`` | native | standard | ++-----------+------------------------+--------------------+ +| ``<`` | little-endian | standard | ++-----------+------------------------+--------------------+ +| ``>`` | big-endian | standard | ++-----------+------------------------+--------------------+ +| ``!`` | network (= big-endian) | standard | ++-----------+------------------------+--------------------+ + +If the first character is not one of these, ``'@'`` is assumed. + +Native byte order is big-endian or little-endian, depending on the host +system. For example, Intel x86 and AMD64 (x86-64) are little-endian; +Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature +switchable endianness (bi-endian). Use ``sys.byteorder`` to check the +endianness of your system. + +Native size and alignment are determined using the C compiler's +``sizeof`` expression. This is always combined with native byte order. + +Standard size and alignment are as follows: no alignment is required for any +type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and +:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 +bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating +point numbers, respectively. :ctype:`_Bool` is 1 byte. + +Note the difference between ``'@'`` and ``'='``: both use native byte order, but +the size and alignment of the latter is standardized. + +The form ``'!'`` is available for those poor souls who claim they can't remember +whether network byte order is big-endian or little-endian. + +There is no way to indicate non-native byte order (force byte-swapping); use the +appropriate choice of ``'<'`` or ``'>'``. + +The ``'P'`` format character is only available for the native byte ordering +(selected as the default or with the ``'@'`` byte order character). The byte +order character ``'='`` chooses to use little- or big-endian ordering based on +the host system. The struct module does not interpret this as native ordering, +so the ``'P'`` format is not available. + +Notes: + +(1) Padding is only automatically added between successive structure members. + No padding is added at the beginning or the end of the encoded struct. + +(2) No padding is added when using non-native size and alignment, e.g. + with '<', '>', '=', and '!'. + +(3) To align the end of a structure to the alignment requirement of a + particular type, end the format with the code for that type with a repeat + count of zero. See :ref:`struct-examples`. + + +.. _format-characters: Format Characters ^^^^^^^^^^^^^^^^^ @@ -196,77 +271,6 @@ any non-zero value will be True when unpacking. -.. _struct-alignment: - -Byte Order, Size, and Alignment -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -By default, C types are represented in the machine's native format and byte -order, and properly aligned by skipping pad bytes if necessary (according to the -rules used by the C compiler). - -Alternatively, the first character of the format string can be used to indicate -the byte order, size and alignment of the packed data, according to the -following table: - -+-----------+------------------------+--------------------+ -| Character | Byte order | Size and alignment | -+===========+========================+====================+ -| ``@`` | native | native | -+-----------+------------------------+--------------------+ -| ``=`` | native | standard | -+-----------+------------------------+--------------------+ -| ``<`` | little-endian | standard | -+-----------+------------------------+--------------------+ -| ``>`` | big-endian | standard | -+-----------+------------------------+--------------------+ -| ``!`` | network (= big-endian) | standard | -+-----------+------------------------+--------------------+ - -If the first character is not one of these, ``'@'`` is assumed. - -Native byte order is big-endian or little-endian, depending on the host -system. For example, Intel x86 and AMD64 (x86-64) are little-endian; -Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature -switchable endianness (bi-endian). Use ``sys.byteorder`` to check the -endianness of your system. - -Native size and alignment are determined using the C compiler's -``sizeof`` expression. This is always combined with native byte order. - -Standard size and alignment are as follows: no alignment is required for any -type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and -:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 -bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating -point numbers, respectively. :ctype:`_Bool` is 1 byte. - -Note the difference between ``'@'`` and ``'='``: both use native byte order, but -the size and alignment of the latter is standardized. - -The form ``'!'`` is available for those poor souls who claim they can't remember -whether network byte order is big-endian or little-endian. - -There is no way to indicate non-native byte order (force byte-swapping); use the -appropriate choice of ``'<'`` or ``'>'``. - -The ``'P'`` format character is only available for the native byte ordering -(selected as the default or with the ``'@'`` byte order character). The byte -order character ``'='`` chooses to use little- or big-endian ordering based on -the host system. The struct module does not interpret this as native ordering, -so the ``'P'`` format is not available. - -Notes: - -(1) Padding is only automatically added between successive structure members. - No padding is added at the beginning or the end of the encoded struct. - -(2) No padding is added when using non-native size and alignment, e.g. - with '<', '>', '=', and '!'. - -(3) To align the end of a structure to the alignment requirement of a - particular type, end the format with the code for that type with a repeat - count of zero. See :ref:`struct-examples`. - .. _struct-examples: @@ -331,7 +335,7 @@ .. _struct-objects: -Objects +Classes ------- The :mod:`struct` module also defines the following type: From python-checkins at python.org Sat Jun 12 20:50:34 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 20:50:34 +0200 (CEST) Subject: [Python-checkins] r81957 - python/trunk/Doc/library/struct.rst Message-ID: <20100612185034.8BFAAEE99D@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 20:50:34 2010 New Revision: 81957 Log: Issue #8469: Add standard sizes to table in struct documentation; additional clarifications and documentation tweaks. Backport of revisions 81955-81956 from py3k. Modified: python/trunk/Doc/library/struct.rst Modified: python/trunk/Doc/library/struct.rst ============================================================================== --- python/trunk/Doc/library/struct.rst (original) +++ python/trunk/Doc/library/struct.rst Sat Jun 12 20:50:34 2010 @@ -82,9 +82,84 @@ -------------- Format strings are the mechanism used to specify the expected layout when -packing and unpacking data. They are built up from format characters, which -specify the type of data being packed/unpacked. In addition, there are -special characters for controlling the byte order, size, and alignment. +packing and unpacking data. They are built up from :ref:`format-characters`, +which specify the type of data being packed/unpacked. In addition, there are +special characters for controlling the :ref:`struct-alignment`. + + +.. _struct-alignment: + +Byte Order, Size, and Alignment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, C types are represented in the machine's native format and byte +order, and properly aligned by skipping pad bytes if necessary (according to the +rules used by the C compiler). + +Alternatively, the first character of the format string can be used to indicate +the byte order, size and alignment of the packed data, according to the +following table: + ++-----------+------------------------+--------------------+ +| Character | Byte order | Size and alignment | ++===========+========================+====================+ +| ``@`` | native | native | ++-----------+------------------------+--------------------+ +| ``=`` | native | standard | ++-----------+------------------------+--------------------+ +| ``<`` | little-endian | standard | ++-----------+------------------------+--------------------+ +| ``>`` | big-endian | standard | ++-----------+------------------------+--------------------+ +| ``!`` | network (= big-endian) | standard | ++-----------+------------------------+--------------------+ + +If the first character is not one of these, ``'@'`` is assumed. + +Native byte order is big-endian or little-endian, depending on the host +system. For example, Intel x86 and AMD64 (x86-64) are little-endian; +Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature +switchable endianness (bi-endian). Use ``sys.byteorder`` to check the +endianness of your system. + +Native size and alignment are determined using the C compiler's +``sizeof`` expression. This is always combined with native byte order. + +Standard size and alignment are as follows: no alignment is required for any +type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and +:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 +bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating +point numbers, respectively. :ctype:`_Bool` is 1 byte. + +Note the difference between ``'@'`` and ``'='``: both use native byte order, but +the size and alignment of the latter is standardized. + +The form ``'!'`` is available for those poor souls who claim they can't remember +whether network byte order is big-endian or little-endian. + +There is no way to indicate non-native byte order (force byte-swapping); use the +appropriate choice of ``'<'`` or ``'>'``. + +The ``'P'`` format character is only available for the native byte ordering +(selected as the default or with the ``'@'`` byte order character). The byte +order character ``'='`` chooses to use little- or big-endian ordering based on +the host system. The struct module does not interpret this as native ordering, +so the ``'P'`` format is not available. + +Notes: + +(1) Padding is only automatically added between successive structure members. + No padding is added at the beginning or the end of the encoded struct. + +(2) No padding is added when using non-native size and alignment, e.g. + with '<', '>', '=', and '!'. + +(3) To align the end of a structure to the alignment requirement of a + particular type, end the format with the code for that type with a repeat + count of zero. See :ref:`struct-examples`. + + +.. _format-characters: Format Characters ^^^^^^^^^^^^^^^^^ @@ -92,46 +167,46 @@ Format characters have the following meaning; the conversion between C and Python values should be obvious given their types: -+--------+-------------------------+--------------------+------------+ -| Format | C Type | Python | Notes | -+========+=========================+====================+============+ -| ``x`` | pad byte | no value | | -+--------+-------------------------+--------------------+------------+ -| ``c`` | :ctype:`char` | string of length 1 | | -+--------+-------------------------+--------------------+------------+ -| ``b`` | :ctype:`signed char` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``B`` | :ctype:`unsigned char` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``?`` | :ctype:`_Bool` | bool | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``h`` | :ctype:`short` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``H`` | :ctype:`unsigned short` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``i`` | :ctype:`int` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``I`` | :ctype:`unsigned int` | integer or long | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``l`` | :ctype:`long` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``L`` | :ctype:`unsigned long` | long | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``q`` | :ctype:`long long` | long | \(2),\(3) | -+--------+-------------------------+--------------------+------------+ -| ``Q`` | :ctype:`unsigned long | long | \(2),\(3) | -| | long` | | | -+--------+-------------------------+--------------------+------------+ -| ``f`` | :ctype:`float` | float | | -+--------+-------------------------+--------------------+------------+ -| ``d`` | :ctype:`double` | float | | -+--------+-------------------------+--------------------+------------+ -| ``s`` | :ctype:`char[]` | string | | -+--------+-------------------------+--------------------+------------+ -| ``p`` | :ctype:`char[]` | string | | -+--------+-------------------------+--------------------+------------+ -| ``P`` | :ctype:`void \*` | long | \(3) | -+--------+-------------------------+--------------------+------------+ ++--------+-------------------------+--------------------+----------------+------------+ +| Format | C Type | Python type | Standard size | Notes | ++========+=========================+====================+================+============+ +| ``x`` | pad byte | no value | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``c`` | :ctype:`char` | string of length 1 | 1 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``b`` | :ctype:`signed char` | integer | 1 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``B`` | :ctype:`unsigned char` | integer | 1 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``?`` | :ctype:`_Bool` | bool | 1 | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``h`` | :ctype:`short` | integer | 2 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``H`` | :ctype:`unsigned short` | integer | 2 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``i`` | :ctype:`int` | integer | 4 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``I`` | :ctype:`unsigned int` | integer | 4 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``l`` | :ctype:`long` | integer | 4 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``L`` | :ctype:`unsigned long` | integer | 4 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``q`` | :ctype:`long long` | integer | 8 | \(2), \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``Q`` | :ctype:`unsigned long | integer | 8 | \(2), \(3) | +| | long` | | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``f`` | :ctype:`float` | float | 4 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``d`` | :ctype:`double` | float | 8 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``s`` | :ctype:`char[]` | string | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``p`` | :ctype:`char[]` | string | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``P`` | :ctype:`void \*` | integer | | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ Notes: @@ -190,9 +265,6 @@ used. Note that for :func:`unpack`, the ``'p'`` format character consumes count bytes, but that the string returned can never contain more than 255 characters. -For the ``'I'``, ``'L'``, ``'q'`` and ``'Q'`` format characters, the return -value is a Python long integer. - For the ``'P'`` format character, the return value is a Python integer or long integer, depending on the size needed to hold a pointer when it has been cast to an integer type. A *NULL* pointer will always be returned as the Python integer @@ -207,77 +279,6 @@ any non-zero value will be True when unpacking. -.. _struct-alignment: - -Byte Order, Size, and Alignment -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -By default, C types are represented in the machine's native format and byte -order, and properly aligned by skipping pad bytes if necessary (according to the -rules used by the C compiler). - -Alternatively, the first character of the format string can be used to indicate -the byte order, size and alignment of the packed data, according to the -following table: - -+-----------+------------------------+--------------------+ -| Character | Byte order | Size and alignment | -+===========+========================+====================+ -| ``@`` | native | native | -+-----------+------------------------+--------------------+ -| ``=`` | native | standard | -+-----------+------------------------+--------------------+ -| ``<`` | little-endian | standard | -+-----------+------------------------+--------------------+ -| ``>`` | big-endian | standard | -+-----------+------------------------+--------------------+ -| ``!`` | network (= big-endian) | standard | -+-----------+------------------------+--------------------+ - -If the first character is not one of these, ``'@'`` is assumed. - -Native byte order is big-endian or little-endian, depending on the host -system. For example, Intel x86 and AMD64 (x86-64) are little-endian; -Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature -switchable endianness (bi-endian). Use ``sys.byteorder`` to check the -endianness of your system. - -Native size and alignment are determined using the C compiler's -``sizeof`` expression. This is always combined with native byte order. - -Standard size and alignment are as follows: no alignment is required for any -type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and -:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 -bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating -point numbers, respectively. :ctype:`_Bool` is 1 byte. - -Note the difference between ``'@'`` and ``'='``: both use native byte order, but -the size and alignment of the latter is standardized. - -The form ``'!'`` is available for those poor souls who claim they can't remember -whether network byte order is big-endian or little-endian. - -There is no way to indicate non-native byte order (force byte-swapping); use the -appropriate choice of ``'<'`` or ``'>'``. - -The ``'P'`` format character is only available for the native byte ordering -(selected as the default or with the ``'@'`` byte order character). The byte -order character ``'='`` chooses to use little- or big-endian ordering based on -the host system. The struct module does not interpret this as native ordering, -so the ``'P'`` format is not available. - -Notes: - -(1) Padding is only automatically added between successive structure members. - No padding is added at the beginning or the end of the encoded struct. - -(2) No padding is added when using non-native size and alignment, e.g. - with '<', '>', '=', and '!'. - -(3) To align the end of a structure to the alignment requirement of a - particular type, end the format with the code for that type with a repeat - count of zero. See :ref:`struct-examples`. - .. _struct-examples: @@ -342,7 +343,7 @@ .. _struct-objects: -Objects +Classes ------- The :mod:`struct` module also defines the following type: From python-checkins at python.org Sat Jun 12 20:54:20 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 20:54:20 +0200 (CEST) Subject: [Python-checkins] r81958 - python/branches/py3k Message-ID: <20100612185420.F0303EE9EA@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 20:54:20 2010 New Revision: 81958 Log: Blocked revisions 81957 via svnmerge ........ r81957 | mark.dickinson | 2010-06-12 19:50:34 +0100 (Sat, 12 Jun 2010) | 5 lines Issue #8469: Add standard sizes to table in struct documentation; additional clarifications and documentation tweaks. Backport of revisions 81955-81956 from py3k. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Jun 12 20:55:47 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 20:55:47 +0200 (CEST) Subject: [Python-checkins] r81959 - in python/branches/release26-maint: Doc/library/struct.rst Message-ID: <20100612185547.C8D7CEE99D@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 20:55:47 2010 New Revision: 81959 Log: Merged revisions 81957 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81957 | mark.dickinson | 2010-06-12 19:50:34 +0100 (Sat, 12 Jun 2010) | 5 lines Issue #8469: Add standard sizes to table in struct documentation; additional clarifications and documentation tweaks. Backport of revisions 81955-81956 from py3k. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/struct.rst Modified: python/branches/release26-maint/Doc/library/struct.rst ============================================================================== --- python/branches/release26-maint/Doc/library/struct.rst (original) +++ python/branches/release26-maint/Doc/library/struct.rst Sat Jun 12 20:55:47 2010 @@ -82,112 +82,9 @@ -------------- Format strings are the mechanism used to specify the expected layout when -packing and unpacking data. They are built up from format characters, which -specify the type of data being packed/unpacked. In addition, there are -special characters for controlling the byte order, size, and alignment. - -Format Characters -^^^^^^^^^^^^^^^^^ - -Format characters have the following meaning; the conversion between C and -Python values should be obvious given their types: - -+--------+-------------------------+--------------------+------------+ -| Format | C Type | Python | Notes | -+========+=========================+====================+============+ -| ``x`` | pad byte | no value | | -+--------+-------------------------+--------------------+------------+ -| ``c`` | :ctype:`char` | string of length 1 | | -+--------+-------------------------+--------------------+------------+ -| ``b`` | :ctype:`signed char` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``B`` | :ctype:`unsigned char` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``?`` | :ctype:`_Bool` | bool | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``h`` | :ctype:`short` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``H`` | :ctype:`unsigned short` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``i`` | :ctype:`int` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``I`` | :ctype:`unsigned int` | integer or long | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``l`` | :ctype:`long` | integer | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``L`` | :ctype:`unsigned long` | long | \(3) | -+--------+-------------------------+--------------------+------------+ -| ``q`` | :ctype:`long long` | long | \(2),\(3) | -+--------+-------------------------+--------------------+------------+ -| ``Q`` | :ctype:`unsigned long | long | \(2),\(3) | -| | long` | | | -+--------+-------------------------+--------------------+------------+ -| ``f`` | :ctype:`float` | float | | -+--------+-------------------------+--------------------+------------+ -| ``d`` | :ctype:`double` | float | | -+--------+-------------------------+--------------------+------------+ -| ``s`` | :ctype:`char[]` | string | | -+--------+-------------------------+--------------------+------------+ -| ``p`` | :ctype:`char[]` | string | | -+--------+-------------------------+--------------------+------------+ -| ``P`` | :ctype:`void \*` | long | \(3) | -+--------+-------------------------+--------------------+------------+ - -Notes: - -(1) - The ``'?'`` conversion code corresponds to the :ctype:`_Bool` type defined by - C99. If this type is not available, it is simulated using a :ctype:`char`. In - standard mode, it is always represented by one byte. - - .. versionadded:: 2.6 - -(2) - The ``'q'`` and ``'Q'`` conversion codes are available in native mode only if - the platform C compiler supports C :ctype:`long long`, or, on Windows, - :ctype:`__int64`. They are always available in standard modes. - - .. versionadded:: 2.2 - -A format character may be preceded by an integral repeat count. For example, -the format string ``'4h'`` means exactly the same as ``'hhhh'``. - -Whitespace characters between formats are ignored; a count and its format must -not contain whitespace though. - -For the ``'s'`` format character, the count is interpreted as the size of the -string, not a repeat count like for the other format characters; for example, -``'10s'`` means a single 10-byte string, while ``'10c'`` means 10 characters. -For packing, the string is truncated or padded with null bytes as appropriate to -make it fit. For unpacking, the resulting string always has exactly the -specified number of bytes. As a special case, ``'0s'`` means a single, empty -string (while ``'0c'`` means 0 characters). - -The ``'p'`` format character encodes a "Pascal string", meaning a short -variable-length string stored in a fixed number of bytes. The count is the total -number of bytes stored. The first byte stored is the length of the string, or -255, whichever is smaller. The bytes of the string follow. If the string -passed in to :func:`pack` is too long (longer than the count minus 1), only the -leading count-1 bytes of the string are stored. If the string is shorter than -count-1, it is padded with null bytes so that exactly count bytes in all are -used. Note that for :func:`unpack`, the ``'p'`` format character consumes count -bytes, but that the string returned can never contain more than 255 characters. - -For the ``'I'``, ``'L'``, ``'q'`` and ``'Q'`` format characters, the return -value is a Python long integer. - -For the ``'P'`` format character, the return value is a Python integer or long -integer, depending on the size needed to hold a pointer when it has been cast to -an integer type. A *NULL* pointer will always be returned as the Python integer -``0``. When packing pointer-sized values, Python integer or long integer objects -may be used. For example, the Alpha and Merced processors use 64-bit pointer -values, meaning a Python long integer will be used to hold the pointer; other -platforms use 32-bit pointers and will use a Python integer. - -For the ``'?'`` format character, the return value is either :const:`True` or -:const:`False`. When packing, the truth value of the argument object is used. -Either 0 or 1 in the native or standard bool representation will be packed, and -any non-zero value will be True when unpacking. +packing and unpacking data. They are built up from :ref:`format-characters`, +which specify the type of data being packed/unpacked. In addition, there are +special characters for controlling the :ref:`struct-alignment`. .. _struct-alignment: @@ -262,6 +159,110 @@ count of zero. See :ref:`struct-examples`. +.. _format-characters: + +Format Characters +^^^^^^^^^^^^^^^^^ + +Format characters have the following meaning; the conversion between C and +Python values should be obvious given their types: + ++--------+-------------------------+--------------------+----------------+------------+ +| Format | C Type | Python type | Standard size | Notes | ++========+=========================+====================+================+============+ +| ``x`` | pad byte | no value | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``c`` | :ctype:`char` | string of length 1 | 1 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``b`` | :ctype:`signed char` | integer | 1 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``B`` | :ctype:`unsigned char` | integer | 1 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``?`` | :ctype:`_Bool` | bool | 1 | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``h`` | :ctype:`short` | integer | 2 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``H`` | :ctype:`unsigned short` | integer | 2 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``i`` | :ctype:`int` | integer | 4 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``I`` | :ctype:`unsigned int` | integer | 4 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``l`` | :ctype:`long` | integer | 4 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``L`` | :ctype:`unsigned long` | integer | 4 | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``q`` | :ctype:`long long` | integer | 8 | \(2), \(3) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``Q`` | :ctype:`unsigned long | integer | 8 | \(2), \(3) | +| | long` | | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``f`` | :ctype:`float` | float | 4 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``d`` | :ctype:`double` | float | 8 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``s`` | :ctype:`char[]` | string | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``p`` | :ctype:`char[]` | string | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``P`` | :ctype:`void \*` | integer | | \(3) | ++--------+-------------------------+--------------------+----------------+------------+ + +Notes: + +(1) + The ``'?'`` conversion code corresponds to the :ctype:`_Bool` type defined by + C99. If this type is not available, it is simulated using a :ctype:`char`. In + standard mode, it is always represented by one byte. + + .. versionadded:: 2.6 + +(2) + The ``'q'`` and ``'Q'`` conversion codes are available in native mode only if + the platform C compiler supports C :ctype:`long long`, or, on Windows, + :ctype:`__int64`. They are always available in standard modes. + + .. versionadded:: 2.2 + +A format character may be preceded by an integral repeat count. For example, +the format string ``'4h'`` means exactly the same as ``'hhhh'``. + +Whitespace characters between formats are ignored; a count and its format must +not contain whitespace though. + +For the ``'s'`` format character, the count is interpreted as the size of the +string, not a repeat count like for the other format characters; for example, +``'10s'`` means a single 10-byte string, while ``'10c'`` means 10 characters. +For packing, the string is truncated or padded with null bytes as appropriate to +make it fit. For unpacking, the resulting string always has exactly the +specified number of bytes. As a special case, ``'0s'`` means a single, empty +string (while ``'0c'`` means 0 characters). + +The ``'p'`` format character encodes a "Pascal string", meaning a short +variable-length string stored in a fixed number of bytes. The count is the total +number of bytes stored. The first byte stored is the length of the string, or +255, whichever is smaller. The bytes of the string follow. If the string +passed in to :func:`pack` is too long (longer than the count minus 1), only the +leading count-1 bytes of the string are stored. If the string is shorter than +count-1, it is padded with null bytes so that exactly count bytes in all are +used. Note that for :func:`unpack`, the ``'p'`` format character consumes count +bytes, but that the string returned can never contain more than 255 characters. + +For the ``'P'`` format character, the return value is a Python integer or long +integer, depending on the size needed to hold a pointer when it has been cast to +an integer type. A *NULL* pointer will always be returned as the Python integer +``0``. When packing pointer-sized values, Python integer or long integer objects +may be used. For example, the Alpha and Merced processors use 64-bit pointer +values, meaning a Python long integer will be used to hold the pointer; other +platforms use 32-bit pointers and will use a Python integer. + +For the ``'?'`` format character, the return value is either :const:`True` or +:const:`False`. When packing, the truth value of the argument object is used. +Either 0 or 1 in the native or standard bool representation will be packed, and +any non-zero value will be True when unpacking. + + + .. _struct-examples: Examples @@ -325,7 +326,7 @@ .. _struct-objects: -Objects +Classes ------- The :mod:`struct` module also defines the following type: From python-checkins at python.org Sat Jun 12 21:18:51 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 21:18:51 +0200 (CEST) Subject: [Python-checkins] r81960 - in python/branches/release31-maint: Doc/library/struct.rst Lib/struct.py Misc/NEWS Modules/_struct.c Message-ID: <20100612191851.4B043EEAB3@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 21:18:51 2010 New Revision: 81960 Log: Merged revisions 81947-81950,81955-81956 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81947 | mark.dickinson | 2010-06-12 16:17:02 +0100 (Sat, 12 Jun 2010) | 3 lines Issue #8973: Add __all__ to struct module, so that help(struct) correctly displays information for the struct.Struct class. ........ r81948 | mark.dickinson | 2010-06-12 16:19:23 +0100 (Sat, 12 Jun 2010) | 1 line Remove accidental (yet-to-be-reviewed) docstring changes included in r81947. ........ r81949 | mark.dickinson | 2010-06-12 16:43:45 +0100 (Sat, 12 Jun 2010) | 1 line Issue #8973: Improve struct module docstrings. ........ r81950 | mark.dickinson | 2010-06-12 17:30:53 +0100 (Sat, 12 Jun 2010) | 1 line More struct module docs and docstring tweaks. ........ r81955 | mark.dickinson | 2010-06-12 19:20:47 +0100 (Sat, 12 Jun 2010) | 1 line Issue #8469: add standard sizes to struct docs table. ........ r81956 | mark.dickinson | 2010-06-12 19:37:54 +0100 (Sat, 12 Jun 2010) | 2 lines Issue #8469: Reorder struct module sections for clarity; other minor tweaks. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/struct.rst python/branches/release31-maint/Lib/struct.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/_struct.c Modified: python/branches/release31-maint/Doc/library/struct.rst ============================================================================== --- python/branches/release31-maint/Doc/library/struct.rst (original) +++ python/branches/release31-maint/Doc/library/struct.rst Sat Jun 12 21:18:51 2010 @@ -38,38 +38,38 @@ .. function:: pack(fmt, v1, v2, ...) - Return a bytes containing the values ``v1, v2, ...`` packed according to the - given format. The arguments must match the values required by the format - exactly. + Return a bytes object containing the values *v1*, *v2*, ... packed according + to the format string *fmt*. The arguments must match the values required by + the format exactly. .. function:: pack_into(fmt, buffer, offset, v1, v2, ...) - Pack the values ``v1, v2, ...`` according to the given format, write the - packed bytes into the writable *buffer* starting at *offset*. Note that the - offset is a required argument. + Pack the values *v1*, *v2*, ... according to the format string *fmt* and + write the packed bytes into the writable buffer *buffer* starting at + position *offset*. Note that *offset* is a required argument. -.. function:: unpack(fmt, bytes) +.. function:: unpack(fmt, buffer) - Unpack the bytes (presumably packed by ``pack(fmt, ...)``) according to the - given format. The result is a tuple even if it contains exactly one item. - The bytes must contain exactly the amount of data required by the format - (``len(bytes)`` must equal ``calcsize(fmt)``). + Unpack from the buffer *buffer* (presumably packed by ``pack(fmt, ...)``) + according to the format string *fmt*. The result is a tuple even if it + contains exactly one item. The buffer must contain exactly the amount of + data required by the format (``len(bytes)`` must equal ``calcsize(fmt)``). .. function:: unpack_from(fmt, buffer, offset=0) - Unpack the *buffer* according to the given format. The result is a tuple even - if it contains exactly one item. The *buffer* must contain at least the - amount of data required by the format (``len(buffer[offset:])`` must be at - least ``calcsize(fmt)``). + Unpack from *buffer* starting at position *offset*, according to the format + string *fmt*. The result is a tuple even if it contains exactly one + item. *buffer* must contain at least the amount of data required by the + format (``len(buffer[offset:])`` must be at least ``calcsize(fmt)``). .. function:: calcsize(fmt) - Return the size of the struct (and hence of the bytes) corresponding to the - given format. + Return the size of the struct (and hence of the bytes object produced by + ``pack(fmt, ...)``) corresponding to the format string *fmt*. .. _struct-format-strings: @@ -77,114 +77,9 @@ -------------- Format strings are the mechanism used to specify the expected layout when -packing and unpacking data. They are built up from format characters, which -specify the type of data being packed/unpacked. In addition, there are -special characters for controlling the byte order, size, and alignment. - -Format Characters -^^^^^^^^^^^^^^^^^ - -Format characters have the following meaning; the conversion between C and -Python values should be obvious given their types: - -+--------+-------------------------+--------------------+------------+ -| Format | C Type | Python | Notes | -+========+=========================+====================+============+ -| ``x`` | pad byte | no value | | -+--------+-------------------------+--------------------+------------+ -| ``c`` | :ctype:`char` | bytes of length 1 | | -+--------+-------------------------+--------------------+------------+ -| ``b`` | :ctype:`signed char` | integer | \(1),\(4) | -+--------+-------------------------+--------------------+------------+ -| ``B`` | :ctype:`unsigned char` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``?`` | :ctype:`_Bool` | bool | \(2) | -+--------+-------------------------+--------------------+------------+ -| ``h`` | :ctype:`short` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``H`` | :ctype:`unsigned short` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``i`` | :ctype:`int` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``I`` | :ctype:`unsigned int` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``l`` | :ctype:`long` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``L`` | :ctype:`unsigned long` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``q`` | :ctype:`long long` | integer | \(3), \(4) | -+--------+-------------------------+--------------------+------------+ -| ``Q`` | :ctype:`unsigned long | integer | \(3), \(4) | -| | long` | | | -+--------+-------------------------+--------------------+------------+ -| ``f`` | :ctype:`float` | float | | -+--------+-------------------------+--------------------+------------+ -| ``d`` | :ctype:`double` | float | | -+--------+-------------------------+--------------------+------------+ -| ``s`` | :ctype:`char[]` | bytes | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``p`` | :ctype:`char[]` | bytes | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | -+--------+-------------------------+--------------------+------------+ - -Notes: - -(1) - The ``c``, ``s`` and ``p`` conversion codes operate on :class:`bytes` - objects, but packing with such codes also supports :class:`str` objects, - which are encoded using UTF-8. - -(2) - The ``'?'`` conversion code corresponds to the :ctype:`_Bool` type defined by - C99. If this type is not available, it is simulated using a :ctype:`char`. In - standard mode, it is always represented by one byte. - -(3) - The ``'q'`` and ``'Q'`` conversion codes are available in native mode only if - the platform C compiler supports C :ctype:`long long`, or, on Windows, - :ctype:`__int64`. They are always available in standard modes. - -A format character may be preceded by an integral repeat count. For example, -the format string ``'4h'`` means exactly the same as ``'hhhh'``. - -Whitespace characters between formats are ignored; a count and its format must -not contain whitespace though. - -For the ``'s'`` format character, the count is interpreted as the length of the -bytes, not a repeat count like for the other format characters; for example, -``'10s'`` means a single 10-byte string, while ``'10c'`` means 10 characters. -For packing, the string is truncated or padded with null bytes as appropriate to -make it fit. For unpacking, the resulting bytes object always has exactly the -specified number of bytes. As a special case, ``'0s'`` means a single, empty -string (while ``'0c'`` means 0 characters). - -When packing a value ``x`` using one of the integer formats (``'b'``, -``'B'``, ``'h'``, ``'H'``, ``'i'``, ``'I'``, ``'l'``, ``'L'``, -``'q'``, ``'Q'``), if ``x`` is outside the valid range for that format -then :exc:`struct.error` is raised. - -.. versionchanged:: 3.1 - In 3.0, some of the integer formats wrapped out-of-range values and - raised :exc:`DeprecationWarning` instead of :exc:`struct.error`. - - -The ``'p'`` format character encodes a "Pascal string", meaning a short -variable-length string stored in a fixed number of bytes. The count is the total -number of bytes stored. The first byte stored is the length of the string, or -255, whichever is smaller. The bytes of the string follow. If the string -passed in to :func:`pack` is too long (longer than the count minus 1), only the -leading count-1 bytes of the string are stored. If the string is shorter than -count-1, it is padded with null bytes so that exactly count bytes in all are -used. Note that for :func:`unpack`, the ``'p'`` format character consumes count -bytes, but that the string returned can never contain more than 255 bytes. - - - -For the ``'?'`` format character, the return value is either :const:`True` or -:const:`False`. When packing, the truth value of the argument object is used. -Either 0 or 1 in the native or standard bool representation will be packed, and -any non-zero value will be True when unpacking. +packing and unpacking data. They are built up from :ref:`format-characters`, +which specify the type of data being packed/unpacked. In addition, there are +special characters for controlling the :ref:`struct-alignment`. .. _struct-alignment: @@ -216,9 +111,11 @@ If the first character is not one of these, ``'@'`` is assumed. -Native byte order is big-endian or little-endian, depending on the host system. -For example, Motorola and Sun processors are big-endian; Intel and DEC -processors are little-endian. +Native byte order is big-endian or little-endian, depending on the host +system. For example, Intel x86 and AMD64 (x86-64) are little-endian; +Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature +switchable endianness (bi-endian). Use ``sys.byteorder`` to check the +endianness of your system. Native size and alignment are determined using the C compiler's ``sizeof`` expression. This is always combined with native byte order. @@ -257,6 +154,115 @@ count of zero. See :ref:`struct-examples`. +.. _format-characters: + +Format Characters +^^^^^^^^^^^^^^^^^ + +Format characters have the following meaning; the conversion between C and +Python values should be obvious given their types: + ++--------+-------------------------+--------------------+----------------+------------+ +| Format | C Type | Python type | Standard size | Notes | ++========+=========================+====================+================+============+ +| ``x`` | pad byte | no value | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``c`` | :ctype:`char` | bytes of length 1 | 1 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``b`` | :ctype:`signed char` | integer | 1 | \(1),\(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``B`` | :ctype:`unsigned char` | integer | 1 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``?`` | :ctype:`_Bool` | bool | 1 | \(2) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``h`` | :ctype:`short` | integer | 2 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``H`` | :ctype:`unsigned short` | integer | 2 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``i`` | :ctype:`int` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``I`` | :ctype:`unsigned int` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``l`` | :ctype:`long` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``L`` | :ctype:`unsigned long` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``q`` | :ctype:`long long` | integer | 8 | \(3), \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``Q`` | :ctype:`unsigned long | integer | 8 | \(3), \(4) | +| | long` | | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``f`` | :ctype:`float` | float | 4 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``d`` | :ctype:`double` | float | 8 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``s`` | :ctype:`char[]` | bytes | | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``p`` | :ctype:`char[]` | bytes | | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``P`` | :ctype:`void \*` | integer | | | ++--------+-------------------------+--------------------+----------------+------------+ + +Notes: + +(1) + The ``c``, ``s`` and ``p`` conversion codes operate on :class:`bytes` + objects, but packing with such codes also supports :class:`str` objects, + which are encoded using UTF-8. + +(2) + The ``'?'`` conversion code corresponds to the :ctype:`_Bool` type defined by + C99. If this type is not available, it is simulated using a :ctype:`char`. In + standard mode, it is always represented by one byte. + +(3) + The ``'q'`` and ``'Q'`` conversion codes are available in native mode only if + the platform C compiler supports C :ctype:`long long`, or, on Windows, + :ctype:`__int64`. They are always available in standard modes. + +A format character may be preceded by an integral repeat count. For example, +the format string ``'4h'`` means exactly the same as ``'hhhh'``. + +Whitespace characters between formats are ignored; a count and its format must +not contain whitespace though. + +For the ``'s'`` format character, the count is interpreted as the length of the +bytes, not a repeat count like for the other format characters; for example, +``'10s'`` means a single 10-byte string, while ``'10c'`` means 10 characters. +For packing, the string is truncated or padded with null bytes as appropriate to +make it fit. For unpacking, the resulting bytes object always has exactly the +specified number of bytes. As a special case, ``'0s'`` means a single, empty +string (while ``'0c'`` means 0 characters). + +When packing a value ``x`` using one of the integer formats (``'b'``, +``'B'``, ``'h'``, ``'H'``, ``'i'``, ``'I'``, ``'l'``, ``'L'``, +``'q'``, ``'Q'``), if ``x`` is outside the valid range for that format +then :exc:`struct.error` is raised. + +.. versionchanged:: 3.1 + In 3.0, some of the integer formats wrapped out-of-range values and + raised :exc:`DeprecationWarning` instead of :exc:`struct.error`. + + +The ``'p'`` format character encodes a "Pascal string", meaning a short +variable-length string stored in a fixed number of bytes. The count is the total +number of bytes stored. The first byte stored is the length of the string, or +255, whichever is smaller. The bytes of the string follow. If the string +passed in to :func:`pack` is too long (longer than the count minus 1), only the +leading count-1 bytes of the string are stored. If the string is shorter than +count-1, it is padded with null bytes so that exactly count bytes in all are +used. Note that for :func:`unpack`, the ``'p'`` format character consumes count +bytes, but that the string returned can never contain more than 255 bytes. + + + +For the ``'?'`` format character, the return value is either :const:`True` or +:const:`False`. When packing, the truth value of the argument object is used. +Either 0 or 1 in the native or standard bool representation will be packed, and +any non-zero value will be True when unpacking. + + + .. _struct-examples: Examples @@ -320,7 +326,7 @@ .. _struct-objects: -Objects +Classes ------- The :mod:`struct` module also defines the following type: @@ -347,10 +353,10 @@ Identical to the :func:`pack_into` function, using the compiled format. - .. method:: unpack(bytes) + .. method:: unpack(buffer) Identical to the :func:`unpack` function, using the compiled format. - (``len(bytes)`` must equal :attr:`self.size`). + (``len(buffer)`` must equal :attr:`self.size`). .. method:: unpack_from(buffer, offset=0) @@ -365,6 +371,6 @@ .. attribute:: size - The calculated size of the struct (and hence of the bytes) corresponding - to :attr:`format`. + The calculated size of the struct (and hence of the bytes object produced + by the :meth:`pack` method) corresponding to :attr:`format`. Modified: python/branches/release31-maint/Lib/struct.py ============================================================================== --- python/branches/release31-maint/Lib/struct.py (original) +++ python/branches/release31-maint/Lib/struct.py Sat Jun 12 21:18:51 2010 @@ -1,3 +1,14 @@ +__all__ = [ + # Functions + 'calcsize', 'pack', 'unpack', 'unpack', 'unpack_from', + + # Classes + 'Struct', + + # Exceptions + 'error' + ] + from _struct import * from _struct import _clearcache from _struct import __doc__ Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sat Jun 12 21:18:51 2010 @@ -241,6 +241,9 @@ Extension Modules ----------------- +- Issue #8973: Add __all__ to struct module; this ensures that + help(struct) includes documentation for the struct.Struct class. + - Issue #2810: Fix cases where the Windows registry API returns ERROR_MORE_DATA, requiring a re-try in order to get the complete result. Modified: python/branches/release31-maint/Modules/_struct.c ============================================================================== --- python/branches/release31-maint/Modules/_struct.c (original) +++ python/branches/release31-maint/Modules/_struct.c Sat Jun 12 21:18:51 2010 @@ -1384,9 +1384,9 @@ PyDoc_STRVAR(s_unpack__doc__, "S.unpack(buffer) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\ -strings."); +Return a tuple containing values unpacked according to the format\n\ +string S.format. Requires len(buffer) == S.size. See help(struct)\n\ +for more on format strings."); static PyObject * s_unpack(PyObject *self, PyObject *input) @@ -1412,12 +1412,11 @@ } PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\ +"S.unpack_from(buffer[, offset=0]) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Unlike unpack, unpack_from can unpack values from any object supporting\n\ -the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\ -See struct.__doc__ for more on format strings."); +Return a tuple containing values unpacked according to the format\n\ +string S.format. Requires len(buffer[offset:]) >= S.size. See\n\ +help(struct) for more on format strings."); static PyObject * s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds) @@ -1552,8 +1551,9 @@ PyDoc_STRVAR(s_pack__doc__, "S.pack(v1, v2, ...) -> bytes\n\ \n\ -Return a bytes containing values v1, v2, ... packed according to this\n\ -Struct's format. See struct.__doc__ for more on format strings."); +Return a bytes object containing values v1, v2, ... packed according\n\ +to the format string S.format. See help(struct) for more on format\n\ +strings."); static PyObject * s_pack(PyObject *self, PyObject *args) @@ -1589,10 +1589,10 @@ PyDoc_STRVAR(s_pack_into__doc__, "S.pack_into(buffer, offset, v1, v2, ...)\n\ \n\ -Pack the values v1, v2, ... according to this Struct's format, write \n\ -the packed bytes into the writable buffer buf starting at offset. Note\n\ -that the offset is not an optional argument. See struct.__doc__ for \n\ -more on format strings."); +Pack the values v1, v2, ... according to the format string S.format\n\ +and write the packed bytes into the writable buffer buf starting at\n\ +offset. Note that the offset is a required argument. See\n\ +help(struct) for more on format strings."); static PyObject * s_pack_into(PyObject *self, PyObject *args) @@ -1767,7 +1767,9 @@ } PyDoc_STRVAR(calcsize_doc, -"Return size of C struct described by format string fmt."); +"calcsize(fmt) -> integer\n\ +\n\ +Return size in bytes of the struct described by the format string fmt."); static PyObject * calcsize(PyObject *self, PyObject *fmt) @@ -1782,7 +1784,10 @@ } PyDoc_STRVAR(pack_doc, -"Return bytes containing values v1, v2, ... packed according to fmt."); +"pack(fmt, v1, v2, ...) -> bytes\n\ +\n\ +Return a bytes object containing the values v1, v2, ... packed according\n\ +to the format string fmt. See help(struct) for more on format strings."); static PyObject * pack(PyObject *self, PyObject *args) @@ -1811,8 +1816,12 @@ } PyDoc_STRVAR(pack_into_doc, -"Pack the values v1, v2, ... according to fmt.\n\ -Write the packed bytes into the writable buffer buf starting at offset."); +"pack_into(fmt, buffer, offset, v1, v2, ...)\n\ +\n\ +Pack the values v1, v2, ... according to the format string fmt and write\n\ +the packed bytes into the writable buffer buf starting at offset. Note\n\ +that the offset is a required argument. See help(struct) for more\n\ +on format strings."); static PyObject * pack_into(PyObject *self, PyObject *args) @@ -1841,8 +1850,11 @@ } PyDoc_STRVAR(unpack_doc, -"Unpack the bytes containing packed C structure data, according to fmt.\n\ -Requires len(bytes) == calcsize(fmt)."); +"unpack(fmt, buffer) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to the format string\n\ +fmt. Requires len(buffer) == calcsize(fmt). See help(struct) for more\n\ +on format strings."); static PyObject * unpack(PyObject *self, PyObject *args) @@ -1861,8 +1873,11 @@ } PyDoc_STRVAR(unpack_from_doc, -"Unpack the buffer, containing packed C structure data, according to\n\ -fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt)."); +"unpack_from(fmt, buffer[, offset=0]) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to the format string\n\ +fmt. Requires len(buffer[offset:]) >= calcsize(fmt). See help(struct)\n\ +for more on format strings."); static PyObject * unpack_from(PyObject *self, PyObject *args, PyObject *kwds) From python-checkins at python.org Sat Jun 12 21:36:28 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Sat, 12 Jun 2010 21:36:28 +0200 (CEST) Subject: [Python-checkins] r81961 - python/branches/py3k/Modules/_struct.c Message-ID: <20100612193628.E83E9EEAC2@mail.python.org> Author: alexander.belopolsky Date: Sat Jun 12 21:36:28 2010 New Revision: 81961 Log: Issue #8973: Expanded Struct.__doc__. Modified: python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Sat Jun 12 21:36:28 2010 @@ -1683,7 +1683,11 @@ {NULL, NULL} /* sentinel */ }; -PyDoc_STRVAR(s__doc__, "Compiled struct object"); +PyDoc_STRVAR(s__doc__, +"Struct(fmt) --> compiled struct object\n" +"\n" +"Return a new Struct object which writes and reads binary data according to\n" +"the format string fmt. See help(struct) for more on format strings."); #define OFF(x) offsetof(PyStructObject, x) From python-checkins at python.org Sat Jun 12 21:44:22 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 12 Jun 2010 21:44:22 +0200 (CEST) Subject: [Python-checkins] r81962 - in python/branches/release31-maint: Modules/_struct.c Message-ID: <20100612194422.D1496EEAD0@mail.python.org> Author: mark.dickinson Date: Sat Jun 12 21:44:22 2010 New Revision: 81962 Log: Merged revisions 81961 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81961 | alexander.belopolsky | 2010-06-12 20:36:28 +0100 (Sat, 12 Jun 2010) | 1 line Issue #8973: Expanded Struct.__doc__. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Modules/_struct.c Modified: python/branches/release31-maint/Modules/_struct.c ============================================================================== --- python/branches/release31-maint/Modules/_struct.c (original) +++ python/branches/release31-maint/Modules/_struct.c Sat Jun 12 21:44:22 2010 @@ -1669,7 +1669,11 @@ {NULL, NULL} /* sentinel */ }; -PyDoc_STRVAR(s__doc__, "Compiled struct object"); +PyDoc_STRVAR(s__doc__, +"Struct(fmt) --> compiled struct object\n" +"\n" +"Return a new Struct object which writes and reads binary data according to\n" +"the format string fmt. See help(struct) for more on format strings."); #define OFF(x) offsetof(PyStructObject, x) From python-checkins at python.org Sat Jun 12 22:00:55 2010 From: python-checkins at python.org (andrew.kuchling) Date: Sat, 12 Jun 2010 22:00:55 +0200 (CEST) Subject: [Python-checkins] r81963 - python/trunk/README Message-ID: <20100612200055.B85CDEEAED@mail.python.org> Author: andrew.kuchling Date: Sat Jun 12 22:00:55 2010 New Revision: 81963 Log: Grammar fix Modified: python/trunk/README Modified: python/trunk/README ============================================================================== --- python/trunk/README (original) +++ python/trunk/README Sat Jun 12 22:00:55 2010 @@ -225,7 +225,7 @@ Unsupported systems ------------------- -A number of systems is not supported in Python 2.7 anymore. Some +A number of systems are not supported in Python 2.7 anymore. Some support code is still present, but will be removed in later versions. If you still need to use current Python versions on these systems, please send a message to python-dev at python.org indicating that you From solipsis at pitrou.net Sun Jun 13 01:23:41 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 13 Jun 2010 01:23:41 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81961): sum=0 Message-ID: <20100612232341.D2C7F1770B@ns6635.ovh.net> py3k results for svn r81961 (hg cset 2f8f3f5a52cb) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogi-U3pE', '-x'] From python-checkins at python.org Sun Jun 13 08:50:40 2010 From: python-checkins at python.org (nick.coghlan) Date: Sun, 13 Jun 2010 08:50:40 +0200 (CEST) Subject: [Python-checkins] r81964 - in python/trunk: Doc/using/cmdline.rst Misc/NEWS Modules/main.c Message-ID: <20100613065040.369ABEEBCF@mail.python.org> Author: nick.coghlan Date: Sun Jun 13 08:50:39 2010 New Revision: 81964 Log: Revert r80580 due to some unintended side effects. See issue #8202 for details. Modified: python/trunk/Doc/using/cmdline.rst python/trunk/Misc/NEWS python/trunk/Modules/main.c Modified: python/trunk/Doc/using/cmdline.rst ============================================================================== --- python/trunk/Doc/using/cmdline.rst (original) +++ python/trunk/Doc/using/cmdline.rst Sun Jun 13 08:50:39 2010 @@ -95,9 +95,8 @@ file is not available. If this option is given, the first element of :data:`sys.argv` will be the - full path to the module file (while the module file is being located, the - first element will be set to ``"-m"``). As with the :option:`-c` option, - the current directory will be added to the start of :data:`sys.path`. + full path to the module file. As with the :option:`-c` option, the current + directory will be added to the start of :data:`sys.path`. Many standard library modules contain code that is invoked on their execution as a script. An example is the :mod:`timeit` module:: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Jun 13 08:50:39 2010 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #8202: Previous change to ``sys.argv[0]`` handling for -m command line + option reverted due to unintended side effects on handling of ``sys.path``. + See tracker issue for details. + - Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). Modified: python/trunk/Modules/main.c ============================================================================== --- python/trunk/Modules/main.c (original) +++ python/trunk/Modules/main.c Sun Jun 13 08:50:39 2010 @@ -519,10 +519,12 @@ } if (module != NULL) { - /* Backup _PyOS_optind and force sys.argv[0] = '-m' - so that PySys_SetArgv correctly sets sys.path[0] to ''*/ + /* Backup _PyOS_optind and force sys.argv[0] = '-c' + so that PySys_SetArgv correctly sets sys.path[0] to '' + rather than looking for a file called "-m". See + tracker issue #8202 for details. */ _PyOS_optind--; - argv[_PyOS_optind] = "-m"; + argv[_PyOS_optind] = "-c"; } PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); From python-checkins at python.org Sun Jun 13 11:17:13 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Jun 2010 11:17:13 +0200 (CEST) Subject: [Python-checkins] r81965 - python/branches/py3k/Modules/_struct.c Message-ID: <20100613091713.4F4CFEEA3A@mail.python.org> Author: mark.dickinson Date: Sun Jun 13 11:17:13 2010 New Revision: 81965 Log: Remove unnecessary brackets from docstring optional arguments. Modified: python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Sun Jun 13 11:17:13 2010 @@ -1426,7 +1426,7 @@ } PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer[, offset=0]) -> (v1, v2, ...)\n\ +"S.unpack_from(buffer, offset=0) -> (v1, v2, ...)\n\ \n\ Return a tuple containing values unpacked according to the format\n\ string S.format. Requires len(buffer[offset:]) >= S.size. See\n\ @@ -1891,7 +1891,7 @@ } PyDoc_STRVAR(unpack_from_doc, -"unpack_from(fmt, buffer[, offset=0]) -> (v1, v2, ...)\n\ +"unpack_from(fmt, buffer, offset=0) -> (v1, v2, ...)\n\ \n\ Return a tuple containing values unpacked according to the format string\n\ fmt. Requires len(buffer[offset:]) >= calcsize(fmt). See help(struct)\n\ From python-checkins at python.org Sun Jun 13 11:18:16 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Jun 2010 11:18:16 +0200 (CEST) Subject: [Python-checkins] r81966 - in python/branches/release31-maint: Modules/_struct.c Message-ID: <20100613091816.D91DDEEA3A@mail.python.org> Author: mark.dickinson Date: Sun Jun 13 11:18:16 2010 New Revision: 81966 Log: Merged revisions 81965 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r81965 | mark.dickinson | 2010-06-13 10:17:13 +0100 (Sun, 13 Jun 2010) | 1 line Remove unnecessary brackets from docstring optional arguments. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Modules/_struct.c Modified: python/branches/release31-maint/Modules/_struct.c ============================================================================== --- python/branches/release31-maint/Modules/_struct.c (original) +++ python/branches/release31-maint/Modules/_struct.c Sun Jun 13 11:18:16 2010 @@ -1412,7 +1412,7 @@ } PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer[, offset=0]) -> (v1, v2, ...)\n\ +"S.unpack_from(buffer, offset=0) -> (v1, v2, ...)\n\ \n\ Return a tuple containing values unpacked according to the format\n\ string S.format. Requires len(buffer[offset:]) >= S.size. See\n\ @@ -1877,7 +1877,7 @@ } PyDoc_STRVAR(unpack_from_doc, -"unpack_from(fmt, buffer[, offset=0]) -> (v1, v2, ...)\n\ +"unpack_from(fmt, buffer, offset=0) -> (v1, v2, ...)\n\ \n\ Return a tuple containing values unpacked according to the format string\n\ fmt. Requires len(buffer[offset:]) >= calcsize(fmt). See help(struct)\n\ From python-checkins at python.org Sun Jun 13 12:50:30 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Jun 2010 12:50:30 +0200 (CEST) Subject: [Python-checkins] r81967 - in python/trunk: Lib/test/math_testcases.txt Lib/test/test_math.py Misc/ACKS Misc/NEWS Modules/mathmodule.c Message-ID: <20100613105030.2F142EEBA1@mail.python.org> Author: mark.dickinson Date: Sun Jun 13 12:50:29 2010 New Revision: 81967 Log: Issue #8986: erfc was raising OverflowError on Linux for arguments in the (approximate) range (-27.3, 30.0), as a result of an escaped errno value. Modified: python/trunk/Lib/test/math_testcases.txt python/trunk/Lib/test/test_math.py python/trunk/Misc/ACKS python/trunk/Misc/NEWS python/trunk/Modules/mathmodule.c Modified: python/trunk/Lib/test/math_testcases.txt ============================================================================== --- python/trunk/Lib/test/math_testcases.txt (original) +++ python/trunk/Lib/test/math_testcases.txt Sun Jun 13 12:50:29 2010 @@ -84,6 +84,25 @@ erf0042 erf -1e150 -> -1.0 erf0043 erf 1.7e308 -> 1.0 +-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold +-- incorrectly signalled overflow on some platforms. +erf0100 erf 26.2 -> 1.0 +erf0101 erf 26.4 -> 1.0 +erf0102 erf 26.6 -> 1.0 +erf0103 erf 26.8 -> 1.0 +erf0104 erf 27.0 -> 1.0 +erf0105 erf 27.2 -> 1.0 +erf0106 erf 27.4 -> 1.0 +erf0107 erf 27.6 -> 1.0 + +erf0110 erf -26.2 -> -1.0 +erf0111 erf -26.4 -> -1.0 +erf0112 erf -26.6 -> -1.0 +erf0113 erf -26.8 -> -1.0 +erf0114 erf -27.0 -> -1.0 +erf0115 erf -27.2 -> -1.0 +erf0116 erf -27.4 -> -1.0 +erf0117 erf -27.6 -> -1.0 ---------------------------------------- -- erfc: complementary error function -- @@ -127,6 +146,25 @@ erfc0052 erfc -1e150 -> 2.0 erfc0053 erfc 1.7e308 -> 0.0 +-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold +-- incorrectly signalled overflow on some platforms. +erfc0100 erfc 26.2 -> 1.6432507924389461e-300 +erfc0101 erfc 26.4 -> 4.4017768588035426e-305 +erfc0102 erfc 26.6 -> 1.0885125885442269e-309 +erfc0103 erfc 26.8 -> 2.4849621571966629e-314 +erfc0104 erfc 27.0 -> 5.2370464393526292e-319 +erfc0105 erfc 27.2 -> 9.8813129168249309e-324 +erfc0106 erfc 27.4 -> 0.0 +erfc0107 erfc 27.6 -> 0.0 + +erfc0110 erfc -26.2 -> 2.0 +erfc0111 erfc -26.4 -> 2.0 +erfc0112 erfc -26.6 -> 2.0 +erfc0113 erfc -26.8 -> 2.0 +erfc0114 erfc -27.0 -> 2.0 +erfc0115 erfc -27.2 -> 2.0 +erfc0116 erfc -27.4 -> 2.0 +erfc0117 erfc -27.6 -> 2.0 --------------------------------------------------------- -- lgamma: log of absolute value of the 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 Sun Jun 13 12:50:29 2010 @@ -996,6 +996,15 @@ accuracy_failure = acc_check(expected, got, rel_err = 5e-15, abs_err = 5e-15) + elif fn == 'erfc': + # erfc has less-than-ideal accuracy for large + # arguments (x ~ 25 or so), mainly due to the + # error involved in computing exp(-x*x). + # + # XXX Would be better to weaken this test only + # for large x, instead of for all x. + accuracy_failure = ulps_check(expected, got, 2000) + else: accuracy_failure = ulps_check(expected, got, 20) if accuracy_failure is None: Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Sun Jun 13 12:50:29 2010 @@ -151,6 +151,7 @@ Jeffery Collins Robert Collins Paul Colomiets +Geremy Condra Juan Jos? Conti Matt Conway David M. Cooke Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Jun 13 12:50:29 2010 @@ -25,6 +25,10 @@ Library ------- + +- Issue #8986: math.erfc was incorrectly raising OverflowError for + values between -27.3 and -30.0 on some platforms. + - Issue #8924: logging: Improved error handling for Unicode in exception text. - Issue #8948: cleanup functions and class / module setups and teardowns are Modified: python/trunk/Modules/mathmodule.c ============================================================================== --- python/trunk/Modules/mathmodule.c (original) +++ python/trunk/Modules/mathmodule.c Sun Jun 13 12:50:29 2010 @@ -428,8 +428,8 @@ static double m_erf_series(double x) { - double x2, acc, fk; - int i; + double x2, acc, fk, result; + int i, saved_errno; x2 = x * x; acc = 0.0; @@ -438,7 +438,12 @@ acc = 2.0 + x2 * acc / fk; fk -= 1.0; } - return acc * x * exp(-x2) / sqrtpi; + /* Make sure the exp call doesn't affect errno; + see m_erfc_contfrac for more. */ + saved_errno = errno; + result = acc * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; } /* @@ -453,8 +458,8 @@ static double m_erfc_contfrac(double x) { - double x2, a, da, p, p_last, q, q_last, b; - int i; + double x2, a, da, p, p_last, q, q_last, b, result; + int i, saved_errno; if (x >= ERFC_CONTFRAC_CUTOFF) return 0.0; @@ -472,7 +477,12 @@ 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; + /* Issue #8986: On some platforms, exp sets errno on underflow to zero; + save the current errno value so that we can restore it later. */ + saved_errno = errno; + result = p / q * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; } /* Error function erf(x), for general x */ From python-checkins at python.org Sun Jun 13 12:52:38 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Jun 2010 12:52:38 +0200 (CEST) Subject: [Python-checkins] r81968 - in python/branches/py3k: Lib/test/math_testcases.txt Lib/test/test_math.py Misc/ACKS Misc/NEWS Modules/mathmodule.c Message-ID: <20100613105238.ECAD3EC3F@mail.python.org> Author: mark.dickinson Date: Sun Jun 13 12:52:38 2010 New Revision: 81968 Log: Merged revisions 81967 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81967 | mark.dickinson | 2010-06-13 11:50:29 +0100 (Sun, 13 Jun 2010) | 4 lines Issue #8986: erfc was raising OverflowError on Linux for arguments in the (approximate) range (-27.3, 30.0), as a result of an escaped errno value. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/math_testcases.txt python/branches/py3k/Lib/test/test_math.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/mathmodule.c 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 Sun Jun 13 12:52:38 2010 @@ -84,6 +84,25 @@ erf0042 erf -1e150 -> -1.0 erf0043 erf 1.7e308 -> 1.0 +-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold +-- incorrectly signalled overflow on some platforms. +erf0100 erf 26.2 -> 1.0 +erf0101 erf 26.4 -> 1.0 +erf0102 erf 26.6 -> 1.0 +erf0103 erf 26.8 -> 1.0 +erf0104 erf 27.0 -> 1.0 +erf0105 erf 27.2 -> 1.0 +erf0106 erf 27.4 -> 1.0 +erf0107 erf 27.6 -> 1.0 + +erf0110 erf -26.2 -> -1.0 +erf0111 erf -26.4 -> -1.0 +erf0112 erf -26.6 -> -1.0 +erf0113 erf -26.8 -> -1.0 +erf0114 erf -27.0 -> -1.0 +erf0115 erf -27.2 -> -1.0 +erf0116 erf -27.4 -> -1.0 +erf0117 erf -27.6 -> -1.0 ---------------------------------------- -- erfc: complementary error function -- @@ -127,6 +146,25 @@ erfc0052 erfc -1e150 -> 2.0 erfc0053 erfc 1.7e308 -> 0.0 +-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold +-- incorrectly signalled overflow on some platforms. +erfc0100 erfc 26.2 -> 1.6432507924389461e-300 +erfc0101 erfc 26.4 -> 4.4017768588035426e-305 +erfc0102 erfc 26.6 -> 1.0885125885442269e-309 +erfc0103 erfc 26.8 -> 2.4849621571966629e-314 +erfc0104 erfc 27.0 -> 5.2370464393526292e-319 +erfc0105 erfc 27.2 -> 9.8813129168249309e-324 +erfc0106 erfc 27.4 -> 0.0 +erfc0107 erfc 27.6 -> 0.0 + +erfc0110 erfc -26.2 -> 2.0 +erfc0111 erfc -26.4 -> 2.0 +erfc0112 erfc -26.6 -> 2.0 +erfc0113 erfc -26.8 -> 2.0 +erfc0114 erfc -27.0 -> 2.0 +erfc0115 erfc -27.2 -> 2.0 +erfc0116 erfc -27.4 -> 2.0 +erfc0117 erfc -27.6 -> 2.0 --------------------------------------------------------- -- lgamma: log of absolute value of the 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 Sun Jun 13 12:52:38 2010 @@ -1042,6 +1042,15 @@ accuracy_failure = acc_check(expected, got, rel_err = 5e-15, abs_err = 5e-15) + elif fn == 'erfc': + # erfc has less-than-ideal accuracy for large + # arguments (x ~ 25 or so), mainly due to the + # error involved in computing exp(-x*x). + # + # XXX Would be better to weaken this test only + # for large x, instead of for all x. + accuracy_failure = ulps_check(expected, got, 2000) + else: accuracy_failure = ulps_check(expected, got, 20) if accuracy_failure is None: Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Sun Jun 13 12:52:38 2010 @@ -153,6 +153,7 @@ Jeffery Collins Robert Collins Paul Colomiets +Geremy Condra Juan Jos? Conti Matt Conway David M. Cooke Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Jun 13 12:52:38 2010 @@ -428,6 +428,9 @@ Library ------- +- Issue #8986: math.erfc was incorrectly raising OverflowError for + values between -27.3 and -30.0 on some platforms. + - Issue #8784: Set tarfile default encoding to 'utf-8' on Windows. - Issue #8966: If a ctypes structure field is an array of c_char, convert its Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Sun Jun 13 12:52:38 2010 @@ -428,8 +428,8 @@ static double m_erf_series(double x) { - double x2, acc, fk; - int i; + double x2, acc, fk, result; + int i, saved_errno; x2 = x * x; acc = 0.0; @@ -438,7 +438,12 @@ acc = 2.0 + x2 * acc / fk; fk -= 1.0; } - return acc * x * exp(-x2) / sqrtpi; + /* Make sure the exp call doesn't affect errno; + see m_erfc_contfrac for more. */ + saved_errno = errno; + result = acc * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; } /* @@ -453,8 +458,8 @@ static double m_erfc_contfrac(double x) { - double x2, a, da, p, p_last, q, q_last, b; - int i; + double x2, a, da, p, p_last, q, q_last, b, result; + int i, saved_errno; if (x >= ERFC_CONTFRAC_CUTOFF) return 0.0; @@ -472,7 +477,12 @@ 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; + /* Issue #8986: On some platforms, exp sets errno on underflow to zero; + save the current errno value so that we can restore it later. */ + saved_errno = errno; + result = p / q * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; } /* Error function erf(x), for general x */ From python-checkins at python.org Sun Jun 13 13:07:00 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Jun 2010 13:07:00 +0200 (CEST) Subject: [Python-checkins] r81969 - python/trunk/Misc/ACKS Message-ID: <20100613110700.3A1E4EEB47@mail.python.org> Author: mark.dickinson Date: Sun Jun 13 13:07:00 2010 New Revision: 81969 Log: Add ?ric Araujo to Misc/ACKS for doc work and many patch and commit reviews. Modified: python/trunk/Misc/ACKS Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Sun Jun 13 13:07:00 2010 @@ -25,6 +25,7 @@ Erik Anders?n Oliver Andrich Ross Andrus +?ric Araujo Jason Asbahr David Ascher Chris AtLee From python-checkins at python.org Sun Jun 13 13:07:57 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Jun 2010 13:07:57 +0200 (CEST) Subject: [Python-checkins] r81970 - in python/branches/py3k: Misc/ACKS Message-ID: <20100613110757.9C6F9EEB47@mail.python.org> Author: mark.dickinson Date: Sun Jun 13 13:07:57 2010 New Revision: 81970 Log: Merged revisions 81969 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81969 | mark.dickinson | 2010-06-13 12:07:00 +0100 (Sun, 13 Jun 2010) | 1 line Add ?ric Araujo to Misc/ACKS for doc work and many patch and commit reviews. ........ 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 Sun Jun 13 13:07:57 2010 @@ -25,6 +25,7 @@ Erik Anders?n Oliver Andrich Ross Andrus +?ric Araujo Jason Asbahr David Ascher Chris AtLee From python-checkins at python.org Sun Jun 13 14:01:34 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Jun 2010 14:01:34 +0200 (CEST) Subject: [Python-checkins] r81971 - python/trunk/Misc/ACKS Message-ID: <20100613120134.B6CF2EEB0E@mail.python.org> Author: mark.dickinson Date: Sun Jun 13 14:01:34 2010 New Revision: 81971 Log: Ezio Melotti was missing from Misc/ACKS. Modified: python/trunk/Misc/ACKS Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Sun Jun 13 14:01:34 2010 @@ -512,6 +512,7 @@ Lambert Meertens Bill van Melle Lucas Prado Melo +Ezio Melotti Brian Merrell Luke Mewburn Mike Meyer From python-checkins at python.org Sun Jun 13 14:02:07 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 13 Jun 2010 14:02:07 +0200 (CEST) Subject: [Python-checkins] r81972 - in python/branches/py3k: Misc/ACKS Message-ID: <20100613120207.A39AAEEB0E@mail.python.org> Author: mark.dickinson Date: Sun Jun 13 14:02:07 2010 New Revision: 81972 Log: Merged revisions 81971 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81971 | mark.dickinson | 2010-06-13 13:01:34 +0100 (Sun, 13 Jun 2010) | 1 line Ezio Melotti was missing from Misc/ACKS. ........ 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 Sun Jun 13 14:02:07 2010 @@ -521,6 +521,7 @@ Lambert Meertens Bill van Melle Lucas Prado Melo +Ezio Melotti Brian Merrell Luke Mewburn Mike Meyer From python-checkins at python.org Sun Jun 13 20:21:50 2010 From: python-checkins at python.org (victor.stinner) Date: Sun, 13 Jun 2010 20:21:50 +0200 (CEST) Subject: [Python-checkins] r81973 - in python/branches/py3k: Doc/c-api/arg.rst Lib/test/test_getargs2.py Misc/NEWS Modules/_testcapimodule.c Python/getargs.c Message-ID: <20100613182150.DE677EECE7@mail.python.org> Author: victor.stinner Date: Sun Jun 13 20:21:50 2010 New Revision: 81973 Log: Issue #8592: PyArg_Parse*() functions raise a TypeError for "y", "u" and "Z" formats if the string contains a null byte/character. Write unit tests for string formats. Modified: python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k/Lib/test/test_getargs2.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_testcapimodule.c python/branches/py3k/Python/getargs.c Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Sun Jun 13 20:21:50 2010 @@ -125,6 +125,8 @@ pointer variable, which will be filled with the pointer to an existing Unicode buffer. Please note that the width of a :ctype:`Py_UNICODE` character depends on compilation options (it is either 16 or 32 bits). + The Python string must not contain embedded NUL characters; if it does, + a :exc:`TypeError` exception is raised. .. note:: Since ``u`` doesn't give you back the length of the string, and it 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 Jun 13 20:21:50 2010 @@ -293,8 +293,136 @@ else: self.fail('TypeError should have been raised') +class Bytes_TestCase(unittest.TestCase): + def test_s(self): + from _testcapi import getargs_s + self.assertEqual(getargs_s('abc\xe9'), b'abc\xc3\xa9') + self.assertRaises(TypeError, getargs_s, 'nul:\0') + self.assertRaises(TypeError, getargs_s, b'bytes') + self.assertRaises(TypeError, getargs_s, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_s, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_s, None) + + def test_s_star(self): + from _testcapi import getargs_s_star + self.assertEqual(getargs_s_star('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_s_star('nul:\0'), b'nul:\0') + self.assertEqual(getargs_s_star(b'bytes'), b'bytes') + self.assertEqual(getargs_s_star(bytearray(b'bytearray')), b'bytearray') + self.assertEqual(getargs_s_star(memoryview(b'memoryview')), b'memoryview') + self.assertRaises(TypeError, getargs_s_star, None) + + def test_s_hash(self): + from _testcapi import getargs_s_hash + self.assertEqual(getargs_s_hash('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_s_hash('nul:\0'), b'nul:\0') + self.assertEqual(getargs_s_hash(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_s_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_s_hash, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_s_hash, None) + + def test_z(self): + from _testcapi import getargs_z + self.assertEqual(getargs_z('abc\xe9'), b'abc\xc3\xa9') + self.assertRaises(TypeError, getargs_z, 'nul:\0') + self.assertEqual(getargs_z(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_z, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_z, memoryview(b'memoryview')) + self.assertIsNone(getargs_z(None)) + + def test_z_star(self): + from _testcapi import getargs_z_star + self.assertEqual(getargs_z_star('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_z_star('nul:\0'), b'nul:\0') + self.assertEqual(getargs_z_star(b'bytes'), b'bytes') + self.assertEqual(getargs_z_star(bytearray(b'bytearray')), b'bytearray') + self.assertEqual(getargs_z_star(memoryview(b'memoryview')), b'memoryview') + self.assertIsNone(getargs_z_star(None)) + + def test_z_hash(self): + from _testcapi import getargs_z_hash + self.assertEqual(getargs_z_hash('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_z_hash('nul:\0'), b'nul:\0') + self.assertEqual(getargs_z_hash(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_z_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_z_hash, memoryview(b'memoryview')) + self.assertIsNone(getargs_z_hash(None)) + + def test_y(self): + from _testcapi import getargs_y + self.assertRaises(TypeError, getargs_y, 'abc\xe9') + self.assertEqual(getargs_y(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_y, b'nul:\0') + self.assertRaises(TypeError, getargs_y, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_y, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_y, None) + + def test_y_star(self): + from _testcapi import getargs_y_star + self.assertRaises(TypeError, getargs_y_star, 'abc\xe9') + self.assertEqual(getargs_y_star(b'bytes'), b'bytes') + self.assertEqual(getargs_y_star(b'nul:\0'), b'nul:\0') + self.assertEqual(getargs_y_star(bytearray(b'bytearray')), b'bytearray') + self.assertEqual(getargs_y_star(memoryview(b'memoryview')), b'memoryview') + self.assertRaises(TypeError, getargs_y_star, None) + + def test_y_hash(self): + from _testcapi import getargs_y_hash + self.assertRaises(TypeError, getargs_y_hash, 'abc\xe9') + self.assertEqual(getargs_y_hash(b'bytes'), b'bytes') + self.assertEqual(getargs_y_hash(b'nul:\0'), b'nul:\0') + self.assertRaises(TypeError, getargs_y_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_y_hash, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_y_hash, None) + + +class Unicode_TestCase(unittest.TestCase): + def test_u(self): + from _testcapi import getargs_u + self.assertEqual(getargs_u('abc\xe9'), 'abc\xe9') + self.assertRaises(TypeError, getargs_u, 'nul:\0') + self.assertRaises(TypeError, getargs_u, b'bytes') + self.assertRaises(TypeError, getargs_u, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_u, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_u, None) + + def test_u_hash(self): + from _testcapi import getargs_u_hash + self.assertEqual(getargs_u_hash('abc\xe9'), 'abc\xe9') + self.assertEqual(getargs_u_hash('nul:\0'), 'nul:\0') + self.assertRaises(TypeError, getargs_u_hash, b'bytes') + self.assertRaises(TypeError, getargs_u_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_u_hash, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_u_hash, None) + + def test_Z(self): + from _testcapi import getargs_Z + self.assertEqual(getargs_Z('abc\xe9'), 'abc\xe9') + self.assertRaises(TypeError, getargs_Z, 'nul:\0') + self.assertRaises(TypeError, getargs_Z, b'bytes') + self.assertRaises(TypeError, getargs_Z, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_Z, memoryview(b'memoryview')) + self.assertIsNone(getargs_Z(None)) + + def test_Z_hash(self): + from _testcapi import getargs_Z_hash + self.assertEqual(getargs_Z_hash('abc\xe9'), 'abc\xe9') + self.assertEqual(getargs_Z_hash('nul:\0'), 'nul:\0') + self.assertRaises(TypeError, getargs_Z_hash, b'bytes') + self.assertRaises(TypeError, getargs_Z_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_Z_hash, memoryview(b'memoryview')) + self.assertIsNone(getargs_Z_hash(None)) + + def test_main(): - tests = [Signed_TestCase, Unsigned_TestCase, Tuple_TestCase, Keywords_TestCase] + tests = [ + Signed_TestCase, + Unsigned_TestCase, + Tuple_TestCase, + Keywords_TestCase, + Bytes_TestCase, + Unicode_TestCase, + ] try: from _testcapi import getargs_L, getargs_K except ImportError: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Jun 13 20:21:50 2010 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #8592: PyArg_Parse*() functions raise a TypeError for "y", "u" and "Z" + formats if the string contains a null byte/character. Write unit tests for + string formats. + - Issue #7490: to facilitate sharing of doctests between 2.x and 3.x test suites, the IGNORE_EXCEPTION_DETAIL directive now also ignores the module location of the raised exception. Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Sun Jun 13 20:21:50 2010 @@ -1011,6 +1011,157 @@ return Py_None; } +static PyObject * +getargs_s(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "s", &str)) + return NULL; + return PyBytes_FromString(str); +} + +static PyObject * +getargs_s_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "s*", &buffer)) + return NULL; + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_s_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &str, &size)) + return NULL; + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_z(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "z", &str)) + return NULL; + if (str != NULL) + return PyBytes_FromString(str); + else + Py_RETURN_NONE; +} + +static PyObject * +getargs_z_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "z*", &buffer)) + return NULL; + if (buffer.buf != NULL) + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + else { + Py_INCREF(Py_None); + bytes = Py_None; + } + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_z_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "z#", &str, &size)) + return NULL; + if (str != NULL) + return PyBytes_FromStringAndSize(str, size); + else + Py_RETURN_NONE; +} + +static PyObject * +getargs_y(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "y", &str)) + return NULL; + return PyBytes_FromString(str); +} + +static PyObject * +getargs_y_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "y*", &buffer)) + return NULL; + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_y_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "y#", &str, &size)) + return NULL; + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_u(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "u", &str)) + return NULL; + size = Py_UNICODE_strlen(str); + return PyUnicode_FromUnicode(str, size); +} + +static PyObject * +getargs_u_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "u#", &str, &size)) + return NULL; + return PyUnicode_FromUnicode(str, size); +} + +static PyObject * +getargs_Z(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Z", &str)) + return NULL; + if (str != NULL) { + size = Py_UNICODE_strlen(str); + return PyUnicode_FromUnicode(str, size); + } else + Py_RETURN_NONE; +} + +static PyObject * +getargs_Z_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Z#", &str, &size)) + return NULL; + if (str != NULL) + return PyUnicode_FromUnicode(str, size); + else + Py_RETURN_NONE; +} /* Test the s and z codes for PyArg_ParseTuple. */ @@ -2062,11 +2213,24 @@ {"test_long_long_and_overflow", (PyCFunction)test_long_long_and_overflow, METH_NOARGS}, {"test_L_code", (PyCFunction)test_L_code, METH_NOARGS}, +#endif + {"getargs_s", getargs_s, METH_VARARGS}, + {"getargs_s_star", getargs_s_star, METH_VARARGS}, + {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, + {"getargs_z", getargs_z, METH_VARARGS}, + {"getargs_z_star", getargs_z_star, METH_VARARGS}, + {"getargs_z_hash", getargs_z_hash, METH_VARARGS}, + {"getargs_y", getargs_y, METH_VARARGS}, + {"getargs_y_star", getargs_y_star, METH_VARARGS}, + {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, + {"getargs_u", getargs_u, METH_VARARGS}, + {"getargs_u_hash", getargs_u_hash, METH_VARARGS}, + {"getargs_Z", getargs_Z, METH_VARARGS}, + {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, {"codec_incrementalencoder", (PyCFunction)codec_incrementalencoder, METH_VARARGS}, {"codec_incrementaldecoder", (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, -#endif {"test_s_code", (PyCFunction)test_s_code, METH_NOARGS}, {"test_u_code", (PyCFunction)test_u_code, METH_NOARGS}, {"test_Z_code", (PyCFunction)test_Z_code, METH_NOARGS}, Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Sun Jun 13 20:21:50 2010 @@ -935,10 +935,15 @@ count = convertbuffer(arg, p, &buf); if (count < 0) return converterr(buf, arg, msgbuf, bufsize); - else if (*format == '#') { + if (*format == '#') { FETCH_SIZE; STORE_SIZE(count); format++; + } else { + if (strlen(*p) != count) + return converterr( + "bytes without null bytes", + arg, msgbuf, bufsize); } break; } @@ -1045,9 +1050,13 @@ if (arg == Py_None) *p = 0; - else if (PyUnicode_Check(arg)) + else if (PyUnicode_Check(arg)) { *p = PyUnicode_AS_UNICODE(arg); - else + if (Py_UNICODE_strlen(*p) != PyUnicode_GET_SIZE(arg)) + return converterr( + "str without null character or None", + arg, msgbuf, bufsize); + } else return converterr("str or None", arg, msgbuf, bufsize); } break; @@ -1227,6 +1236,11 @@ FETCH_SIZE; STORE_SIZE(PyUnicode_GET_SIZE(arg)); format++; + } else { + if (Py_UNICODE_strlen(*p) != PyUnicode_GET_SIZE(arg)) + return converterr( + "str without null character", + arg, msgbuf, bufsize); } break; } From python-checkins at python.org Sun Jun 13 22:31:26 2010 From: python-checkins at python.org (victor.stinner) Date: Sun, 13 Jun 2010 22:31:26 +0200 (CEST) Subject: [Python-checkins] r81974 - python/branches/py3k/Python/getargs.c Message-ID: <20100613203126.4C414F693A@mail.python.org> Author: victor.stinner Date: Sun Jun 13 22:31:26 2010 New Revision: 81974 Log: getargs.c: remove last reference to "t#" format "t#" format was removed from convertitem() (convertsimple) but not skipitem(). Modified: python/branches/py3k/Python/getargs.c Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Sun Jun 13 22:31:26 2010 @@ -1768,7 +1768,6 @@ case 'z': /* string or None */ case 'y': /* bytes */ case 'u': /* unicode string */ - case 't': /* buffer, read-only */ case 'w': /* buffer, read-write */ { (void) va_arg(*p_va, char **); From python-checkins at python.org Sun Jun 13 22:31:51 2010 From: python-checkins at python.org (victor.stinner) Date: Sun, 13 Jun 2010 22:31:51 +0200 (CEST) Subject: [Python-checkins] r81975 - python/branches/release31-maint Message-ID: <20100613203151.7BFBEF6931@mail.python.org> Author: victor.stinner Date: Sun Jun 13 22:31:51 2010 New Revision: 81975 Log: Blocked revisions 81974 via svnmerge ........ r81974 | victor.stinner | 2010-06-13 22:31:26 +0200 (dim., 13 juin 2010) | 4 lines getargs.c: remove last reference to "t#" format "t#" format was removed from convertitem() (convertsimple) but not skipitem(). ........ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Mon Jun 14 01:23:40 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 14 Jun 2010 01:23:40 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81974): sum=14 Message-ID: <20100613232340.DED781771F@ns6635.ovh.net> py3k results for svn r81974 (hg cset 5e132aa608a2) -------------------------------------------------- test_itertools leaked [0, 0, 14] references, sum=14 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogDAWZUd', '-x'] From python-checkins at python.org Mon Jun 14 11:05:26 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 14 Jun 2010 11:05:26 +0200 (CEST) Subject: [Python-checkins] r81976 - python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Message-ID: <20100614090526.0CD96EEBA2@mail.python.org> Author: stefan.krah Date: Mon Jun 14 11:05:25 2010 New Revision: 81976 Log: 1) In the DefaultContext, the InvalidOperation signal was triggered only by the InvalidOperation condition rather than by all conditions of the InvalidOperation spectrum. This bug was introduced by the recent DefaultContext compatibility changes. 2) Change the handling of invalid parameters in context initialization: a) It is of limited value to set InvalidContext in the new context. b) It is not wise to set InvalidContext in the current context either: setcontext(Context()) must fail even if InvalidOperation is disabled in the current context. 3) Must use XDECREF in PyDec_SetCurrentContext(). Modified: python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Modified: python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Mon Jun 14 11:05:25 2010 @@ -1172,7 +1172,7 @@ static mpd_context_t dflt_ctx = { 28, DEC_DFLT_EMAX, DEC_DFLT_EMIN, - MPD_Invalid_operation|MPD_Division_by_zero|MPD_Overflow, + MPD_IEEE_Invalid_operation|MPD_Division_by_zero|MPD_Overflow, 0, 0, MPD_ROUND_HALF_EVEN, 0, 1 }; @@ -1212,13 +1212,12 @@ !mpd_qsetstatus(ctx, t.status) || !mpd_qsetclamp(ctx, t.clamp) || !mpd_qsetcr(ctx, t.allcr)) { - if (dec_addstatus(ctx, MPD_Invalid_context)) { - return -1; - } + PyErr_SetString(PyExc_ValueError, "invalid context"); + return -1; } if (capitals != 0 && capitals != 1) { - PyErr_SetString(PyExc_ValueError, "invalid value for capitals"); + PyErr_SetString(PyExc_ValueError, "invalid context"); return -1; } CtxCaps(self) = capitals; @@ -1481,7 +1480,7 @@ Py_INCREF(v); } - Py_DECREF(module_context); + Py_XDECREF(module_context); module_context = v; module_context_set = 1; Py_RETURN_NONE; From python-checkins at python.org Mon Jun 14 11:14:14 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 14 Jun 2010 11:14:14 +0200 (CEST) Subject: [Python-checkins] r81977 - python/branches/py3k-cdecimal/Lib/test/decimal_tests.py Message-ID: <20100614091414.68C02EEB85@mail.python.org> Author: stefan.krah Date: Mon Jun 14 11:14:14 2010 New Revision: 81977 Log: Test correct setting of traps in DefaultContext and BasicContext. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_tests.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_tests.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_tests.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_tests.py Mon Jun 14 11:14:14 2010 @@ -2585,6 +2585,13 @@ class SpecialContexts(unittest.TestCase): def test_context_templates(self): + if HAVE_CDECIMAL: + self.assertEqual( + BasicContext._traps, + DecIEEEInvalidOperation|DecDivisionByZero|DecOverflow| + DecUnderflow|DecClamped + ) + basic_context_prec = BasicContext.prec extended_context_prec = ExtendedContext.prec @@ -2600,6 +2607,12 @@ ExtendedContext.prec = extended_context_prec def test_default_context(self): + if HAVE_CDECIMAL: + self.assertEqual( + DefaultContext._traps, + DecIEEEInvalidOperation|DecDivisionByZero|DecOverflow + ) + default_context_prec = DefaultContext.prec c = getcontext() From python-checkins at python.org Mon Jun 14 11:17:57 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 14 Jun 2010 11:17:57 +0200 (CEST) Subject: [Python-checkins] r81978 - python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py Message-ID: <20100614091757.89E2BEE9DC@mail.python.org> Author: stefan.krah Date: Mon Jun 14 11:17:57 2010 New Revision: 81978 Log: Fix conversion specifiers. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/deccheck.py Mon Jun 14 11:17:57 2010 @@ -274,12 +274,12 @@ dpresult = getattr(op, funcname)(context=tmpctx) mpddiff = abs(dpresult - mpdresult) if mpddiff >= deculp: - print("deculp: %d dpresult: %s mpdresult: %s" % + print("deculp: %s dpresult: %s mpdresult: %s" % (deculp, dpresult, mpdresult)) return False # not simply a disagreement, but wrong decdiff = abs(dpresult - decresult) if decdiff >= deculp: - print("deculp: %d dpresult: %s mpdresult: %s" % + print("deculp: %s dpresult: %s mpdresult: %s" % (deculp, dpresult, mpdresult)) return False # not simply a disagreement, but wrong self.ulpdiff += 1 @@ -301,12 +301,12 @@ dpresult = getattr(op1, funcname)(op2, context=tmpctx) mpddiff = abs(dpresult - mpdresult) if mpddiff >= deculp: - print("deculp: %d dpresult: %s mpdresult: %s" % + print("deculp: %s dpresult: %s mpdresult: %s" % (deculp, dpresult, mpdresult)) return False # not simply a disagreement, but wrong decdiff = abs(dpresult - decresult) if decdiff >= deculp: - print("deculp: %d dpresult: %s mpdresult: %s" % + print("deculp: %s dpresult: %s mpdresult: %s" % (deculp, dpresult, mpdresult)) return False # not simply a disagreement, but wrong self.ulpdiff += 1 From python-checkins at python.org Mon Jun 14 11:25:17 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 14 Jun 2010 11:25:17 +0200 (CEST) Subject: [Python-checkins] r81979 - python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.sh Message-ID: <20100614092517.B9CECEEA8F@mail.python.org> Author: stefan.krah Date: Mon Jun 14 11:25:17 2010 New Revision: 81979 Log: Fix shell syntax + portability. Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.sh Modified: python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.sh ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.sh (original) +++ python/branches/py3k-cdecimal/Lib/test/decimal_extended_tests/c_tests/runallconfigs.sh Mon Jun 14 11:25:17 2010 @@ -1,4 +1,4 @@ -#/bin/sh +#!/bin/sh VALGRIND= @@ -8,7 +8,7 @@ fi export VALGRIND -if [ X"$@" != X"" ]; then +if [ -n "$1" ]; then CONFIGS="$@" else CONFIGS="x64 ansi64 ansi64c32 ppro ansi32 ansi-legacy" From python-checkins at python.org Mon Jun 14 11:30:16 2010 From: python-checkins at python.org (stefan.krah) Date: Mon, 14 Jun 2010 11:30:16 +0200 (CEST) Subject: [Python-checkins] r81980 - in python/branches/py3k-cdecimal: Doc/c-api/arg.rst Doc/c-api/buffer.rst Doc/library/datetime.rst Doc/library/decimal.rst Doc/library/doctest.rst Doc/library/os.rst Doc/library/struct.rst Doc/library/tarfile.rst Doc/library/xml.dom.minidom.rst Doc/whatsnew/3.2.rst Include/longobject.h Lib/ctypes/test/test_bytes.py Lib/ctypes/test/test_structures.py Lib/decimal.py Lib/doctest.py Lib/logging/config.py Lib/os.py Lib/struct.py Lib/sunau.py Lib/tarfile.py Lib/test/math_testcases.txt Lib/test/regrtest.py Lib/test/test_capi.py Lib/test/test_codecs.py Lib/test/test_curses.py Lib/test/test_doctest.py Lib/test/test_fractions.py Lib/test/test_getargs2.py Lib/test/test_math.py Lib/test/test_minidom.py Lib/test/test_numeric_tower.py Lib/test/test_ssl.py Lib/test/test_struct.py Lib/test/test_sunau.py Lib/test/test_sundry.py Lib/test/test_sys.py Lib/test/test_unicode.py Lib/unittest/case.py Lib/unittest/suite.py Lib/unittest/test/test_runner.py Lib/unittest/test/test_setups.py Lib/xml/dom/minidom.py Misc/ACKS Misc/NEWS Misc/maintainers.rst Modules/_codecsmodule.c Modules/_ctypes/_ctypes.c Modules/_ctypes/cfield.c Modules/_localemodule.c Modules/_struct.c Modules/_testcapimodule.c Modules/datetimemodule.c Modules/itertoolsmodule.c Modules/mathmodule.c Modules/readline.c Objects/bytearrayobject.c Objects/bytesobject.c Objects/exceptions.c Objects/longobject.c Objects/stringlib/formatter.h Objects/stringlib/string_format.h Objects/unicodeobject.c PC/winreg.c Parser/asdl_c.py Python/Python-ast.c Python/errors.c Python/getargs.c Python/modsupport.c Python/pythonrun.c Python/symtable.c Python/sysmodule.c setup.py Message-ID: <20100614093016.BDBD3EEAB8@mail.python.org> Author: stefan.krah Date: Mon Jun 14 11:30:15 2010 New Revision: 81980 Log: Merged revisions 81806-81807,81809,81811,81814,81816,81818,81821,81823,81826-81827,81829-81832,81835,81838,81840-81841,81843-81844,81849,81851,81854,81856-81857,81862,81865,81869,81871,81873-81875,81877,81879,81883,81885,81891,81893-81898,81901-81902,81905,81908,81911-81912,81914,81916,81918,81920,81923,81925,81927,81929-81930,81936-81938,81944,81946-81952,81954-81956,81958,81961,81965,81968,81970,81972-81974 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81806 | mark.dickinson | 2010-06-07 20:47:09 +0200 (Mon, 07 Jun 2010) | 1 line Fix naming inconsistency. ................ r81807 | victor.stinner | 2010-06-07 21:57:46 +0200 (Mon, 07 Jun 2010) | 2 lines Issue #8848: U / U# formats of Py_BuildValue() are just alias to s / s# ................ r81809 | victor.stinner | 2010-06-07 22:14:04 +0200 (Mon, 07 Jun 2010) | 3 lines Issue #8897: Fix sunau module, use bytes to write the header. Patch written by Thomas Jollans. ................ r81811 | victor.stinner | 2010-06-07 23:20:41 +0200 (Mon, 07 Jun 2010) | 9 lines Issue #8925: fix types of Py_Parse*() and Py_BuildValue() functions * Add links to Python types * Replace "string" by bytes or str * Replace "long" by "int" * Specify the default encoding * Fix reST syntax ("..note ::") * etc. ................ r81814 | benjamin.peterson | 2010-06-07 23:41:35 +0200 (Mon, 07 Jun 2010) | 9 lines Merged revisions 81813 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81813 | benjamin.peterson | 2010-06-07 16:37:09 -0500 (Mon, 07 Jun 2010) | 2 lines locale grouping strings should end in '\0' ........ ................ r81816 | ezio.melotti | 2010-06-07 23:57:18 +0200 (Mon, 07 Jun 2010) | 8 lines Blocked revisions 81769 via svnmerge ........ r81769 | ezio.melotti | 2010-06-06 01:28:10 +0300 (Sun, 06 Jun 2010) | 1 line Replace deprecated fail* methods with the equivalent assert* ones. ........ ................ r81818 | ezio.melotti | 2010-06-08 00:02:50 +0200 (Tue, 08 Jun 2010) | 8 lines Blocked revisions 81817 via svnmerge ........ r81817 | ezio.melotti | 2010-06-08 01:00:18 +0300 (Tue, 08 Jun 2010) | 1 line Silence deprecation warning in test___all__ caused by an import bsddb. ........ ................ r81821 | benjamin.peterson | 2010-06-08 00:24:18 +0200 (Tue, 08 Jun 2010) | 1 line use the 's' format code instead of 'U' ................ r81823 | benjamin.peterson | 2010-06-08 00:31:26 +0200 (Tue, 08 Jun 2010) | 9 lines Merged revisions 81820 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81820 | benjamin.peterson | 2010-06-07 17:23:23 -0500 (Mon, 07 Jun 2010) | 1 line correctly overflow when indexes are too large ........ ................ r81826 | benjamin.peterson | 2010-06-08 00:35:08 +0200 (Tue, 08 Jun 2010) | 9 lines Merged revisions 81824 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81824 | benjamin.peterson | 2010-06-07 17:32:44 -0500 (Mon, 07 Jun 2010) | 1 line remove extra byte and fix comment ........ ................ r81827 | benjamin.peterson | 2010-06-08 00:36:44 +0200 (Tue, 08 Jun 2010) | 8 lines Blocked revisions 81825 via svnmerge ........ r81825 | benjamin.peterson | 2010-06-07 17:33:09 -0500 (Mon, 07 Jun 2010) | 1 line use unicode literals ........ ................ r81829 | stefan.krah | 2010-06-08 15:26:49 +0200 (Tue, 08 Jun 2010) | 21 lines Blocked revisions 81669,81672,81683 via svnmerge ........ r81669 | stefan.krah | 2010-06-03 14:39:50 +0200 (Thu, 03 Jun 2010) | 9 lines Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. Thanks Thomas Dickey for answering questions about ncurses/ncursesw and readline! ........ r81672 | stefan.krah | 2010-06-03 16:25:16 +0200 (Thu, 03 Jun 2010) | 3 lines Use compiler rather than compiler_obj. Thanks Michael Foord for noticing. ........ r81683 | stefan.krah | 2010-06-04 11:49:20 +0200 (Fri, 04 Jun 2010) | 1 line Detect missing ldd on all systems. ........ ................ r81830 | stefan.krah | 2010-06-08 15:41:44 +0200 (Tue, 08 Jun 2010) | 9 lines Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. Thanks Thomas Dickey for answering questions about ncurses/ncursesw and readline! ................ r81831 | stefan.krah | 2010-06-08 16:00:52 +0200 (Tue, 08 Jun 2010) | 1 line Add note for r81830. ................ r81832 | r.david.murray | 2010-06-08 16:41:45 +0200 (Tue, 08 Jun 2010) | 2 lines Now that sunau has some tests, remove it from test_sundry. ................ r81835 | benjamin.peterson | 2010-06-08 16:57:22 +0200 (Tue, 08 Jun 2010) | 9 lines Merged revisions 81834 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81834 | benjamin.peterson | 2010-06-08 09:53:29 -0500 (Tue, 08 Jun 2010) | 1 line kill extra word ........ ................ r81838 | alexander.belopolsky | 2010-06-08 19:06:48 +0200 (Tue, 08 Jun 2010) | 1 line Added myself as a maintainer of time and datetime modules. ................ r81840 | alexander.belopolsky | 2010-06-08 20:59:20 +0200 (Tue, 08 Jun 2010) | 9 lines Merged revisions 81489 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81489 | georg.brandl | 2010-05-23 17:29:29 -0400 (Sun, 23 May 2010) | 1 line #1436346: make it more obvious that timetuple[7] is yday. ........ ................ r81841 | victor.stinner | 2010-06-08 22:46:00 +0200 (Tue, 08 Jun 2010) | 6 lines sys_pyfile_write() does nothing if file is NULL mywrite() falls back to the C file object if sys_pyfile_write() returns an error. This patch fixes a segfault is Py_FatalError() is called in an early stage of Python initialization. ................ r81843 | brian.curtin | 2010-06-08 22:57:52 +0200 (Tue, 08 Jun 2010) | 3 lines Fix a compile warning missed during porting (wchar_t/char) and move a variable declaration outside of a loop. #2810 was when this first went in. ................ r81844 | victor.stinner | 2010-06-08 23:00:13 +0200 (Tue, 08 Jun 2010) | 6 lines Py_FatalError(): don't sys sys.last_xxx variables Call PyErr_PrintEx(0) instead of PyErr_Print() to avoid a crash if Py_FatalError() is called in an early stage of Python initialization (if PySys is not yet initialized). ................ r81849 | victor.stinner | 2010-06-08 23:45:51 +0200 (Tue, 08 Jun 2010) | 7 lines PyArg_Parse*("Z#") raises an error for unknown type instead of ignoring the error and leave the pointer to the string and the size unchanged (not initialized). Fix also the type in the error message of "Z", "Z#" and "Y" formats. ................ r81851 | brian.curtin | 2010-06-09 00:27:07 +0200 (Wed, 09 Jun 2010) | 2 lines Fix #8946. Extra PyObject* parameter documented which doesn't exist. ................ r81854 | victor.stinner | 2010-06-09 00:54:19 +0200 (Wed, 09 Jun 2010) | 5 lines Issue #8838, #8339: Remove codecs.charbuffer_encode() and "t#" parsing format Remove last references to the "char buffer" of the buffer protocol from Python3. ................ r81856 | kristjan.jonsson | 2010-06-09 10:13:42 +0200 (Wed, 09 Jun 2010) | 2 lines http://bugs.python.org/issue8832 Issue minidom.unlink with a context manager ................ r81857 | stefan.krah | 2010-06-09 10:56:28 +0200 (Wed, 09 Jun 2010) | 3 lines Issue #8932: Skip required when compiled --without-threads. ................ r81862 | antoine.pitrou | 2010-06-09 18:38:55 +0200 (Wed, 09 Jun 2010) | 9 lines Merged revisions 81860 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81860 | antoine.pitrou | 2010-06-09 18:24:00 +0200 (mer., 09 juin 2010) | 3 lines Issue #8930: fix some C code indentation ........ ................ r81865 | alexander.belopolsky | 2010-06-09 19:11:01 +0200 (Wed, 09 Jun 2010) | 9 lines Merged revisions 81864 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81864 | alexander.belopolsky | 2010-06-09 13:08:11 -0400 (Wed, 09 Jun 2010) | 1 line Fixed markup of tm_isdst attribute. ........ ................ r81869 | victor.stinner | 2010-06-10 14:00:55 +0200 (Thu, 10 Jun 2010) | 4 lines Issue #8922: Normalize the encoding name in PyUnicode_AsEncodedString() to enable shortcuts for upper case encoding name. Add also a shortcut for "iso-8859-1" in PyUnicode_AsEncodedString() and PyUnicode_Decode(). ................ r81871 | victor.stinner | 2010-06-10 15:36:23 +0200 (Thu, 10 Jun 2010) | 4 lines Fix r81869: ISO-8859-15 was seen as an alias to ISO-8859-1 Don't use normalize_encoding() result if it is truncated. ................ r81873 | mark.dickinson | 2010-06-10 18:05:10 +0200 (Thu, 10 Jun 2010) | 4 lines Issue #8950: Make PyArg_Parse* with 'L' code raise for float inputs, instead of warning. This makes it consistent with the other integer codes. ................ r81874 | michael.foord | 2010-06-10 18:16:08 +0200 (Thu, 10 Jun 2010) | 9 lines Merged revisions 81853 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81853 | michael.foord | 2010-06-08 23:44:52 +0100 (Tue, 08 Jun 2010) | 1 line Issue 8948. cleanup functions are not run by unittest.TestCase.debug(), plus class and module teardowns are not run by unittest.TestSuite.debug(). ........ ................ r81875 | michael.foord | 2010-06-10 18:17:07 +0200 (Thu, 10 Jun 2010) | 9 lines Merged revisions 81859 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81859 | michael.foord | 2010-06-09 13:29:56 +0100 (Wed, 09 Jun 2010) | 1 line Typo correction. ........ ................ r81877 | michael.foord | 2010-06-10 18:33:34 +0200 (Thu, 10 Jun 2010) | 8 lines Blocked revisions 81876 via svnmerge ........ r81876 | michael.foord | 2010-06-10 17:32:00 +0100 (Thu, 10 Jun 2010) | 1 line NEWS update for issue 8948. ........ ................ r81879 | michael.foord | 2010-06-10 22:41:54 +0200 (Thu, 10 Jun 2010) | 9 lines Merged revisions 81878 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81878 | michael.foord | 2010-06-10 21:40:21 +0100 (Thu, 10 Jun 2010) | 2 lines Fix issue with nested test suites debug method and module setups. (unittest) ........ ................ r81883 | victor.stinner | 2010-06-11 02:36:33 +0200 (Fri, 11 Jun 2010) | 5 lines Issue #8965: initfsencoding() doesn't change the encoding on Mac OS X File system encoding have to be hardcoded to "utf-8" on Mac OS X. r81190 introduced a regression: the encoding was changed depending on the locale. ................ r81885 | victor.stinner | 2010-06-11 02:41:41 +0200 (Fri, 11 Jun 2010) | 2 lines test_sys: add a test on the file system encoding for darwin ................ r81891 | ezio.melotti | 2010-06-11 04:26:42 +0200 (Fri, 11 Jun 2010) | 9 lines Merged revisions 81889 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81889 | ezio.melotti | 2010-06-11 05:21:25 +0300 (Fri, 11 Jun 2010) | 1 line Remove extra ] from itertools.count docstring. ........ ................ r81893 | mark.dickinson | 2010-06-11 12:44:52 +0200 (Fri, 11 Jun 2010) | 3 lines Issue #8188: Comparisons between Decimal objects and other numeric objects (Fraction, float, complex, int) now all function as expected. ................ r81894 | mark.dickinson | 2010-06-11 12:46:57 +0200 (Fri, 11 Jun 2010) | 1 line Fix issue number typo. ................ r81895 | alexander.belopolsky | 2010-06-11 18:04:59 +0200 (Fri, 11 Jun 2010) | 2 lines Issue #3129: Trailing digits in format string are no longer ignored. ................ r81896 | mark.dickinson | 2010-06-11 18:49:20 +0200 (Fri, 11 Jun 2010) | 1 line Fix typo in docstring. ................ r81897 | mark.dickinson | 2010-06-11 18:56:34 +0200 (Fri, 11 Jun 2010) | 1 line Avoid possible undefined behaviour from signed overflow. ................ r81898 | mark.dickinson | 2010-06-11 21:05:08 +0200 (Fri, 11 Jun 2010) | 1 line Fix an incorrect return type. ................ r81901 | victor.stinner | 2010-06-11 21:24:36 +0200 (Fri, 11 Jun 2010) | 8 lines Blocked revisions 81899 via svnmerge ........ r81899 | victor.stinner | 2010-06-11 21:22:28 +0200 (ven., 11 juin 2010) | 2 lines Issue #8362: Add Misc/maintainers.rst: list of module maintainers ........ ................ r81902 | mark.dickinson | 2010-06-11 21:50:30 +0200 (Fri, 11 Jun 2010) | 1 line Fix more undefined-behaviour inducing overflow checks in struct module. ................ r81905 | mark.dickinson | 2010-06-11 22:29:09 +0200 (Fri, 11 Jun 2010) | 10 lines Blocked revisions 81904 via svnmerge ........ r81904 | mark.dickinson | 2010-06-11 21:27:05 +0100 (Fri, 11 Jun 2010) | 4 lines Fix possible undefined behaviour from signed overflow in struct module. Backport of revisions 81897, 81898 and 81902 from py3k. ........ ................ r81908 | antoine.pitrou | 2010-06-11 23:46:32 +0200 (Fri, 11 Jun 2010) | 11 lines Merged revisions 81907 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81907 | antoine.pitrou | 2010-06-11 23:42:26 +0200 (ven., 11 juin 2010) | 5 lines Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). ........ ................ r81911 | victor.stinner | 2010-06-11 23:50:30 +0200 (Fri, 11 Jun 2010) | 3 lines Issue #8966: If a ctypes structure field is an array of c_char, convert its value to bytes instead of str (as done for c_char and c_char_p). ................ r81912 | benjamin.peterson | 2010-06-11 23:53:07 +0200 (Fri, 11 Jun 2010) | 9 lines Merged revisions 81906 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81906 | benjamin.peterson | 2010-06-11 16:40:37 -0500 (Fri, 11 Jun 2010) | 1 line different spellings are just unacceptable ........ ................ r81914 | victor.stinner | 2010-06-12 00:09:51 +0200 (Sat, 12 Jun 2010) | 2 lines locale.bindtextdomain(): use PyUnicode_FSConverter() to parse the filename ................ r81916 | victor.stinner | 2010-06-12 00:17:52 +0200 (Sat, 12 Jun 2010) | 2 lines Issue #8965: Add a regression test to test_sys with LANG=C ................ r81918 | victor.stinner | 2010-06-12 00:27:14 +0200 (Sat, 12 Jun 2010) | 2 lines readline: use PyUnicode_FSConverter() to parse filenames ................ r81920 | victor.stinner | 2010-06-12 01:06:13 +0200 (Sat, 12 Jun 2010) | 2 lines Issue #8965: Write more tests for sys.getfilesystemencoding() ................ r81923 | victor.stinner | 2010-06-12 01:30:12 +0200 (Sat, 12 Jun 2010) | 16 lines Fix some bugs in c-api/arg.rst documentation * replace "the default encoding" by "'utf-8' encoding" * fix "w" / "w*" / "w#" doc: similar to "y" / "y*" / "y#" and not "s" / "s*" / "s#" * "u#": remove "Non-Unicode objects are handled by interpreting their read-buffer pointer ...", it's no more true * "es", "es#": remove "... and objects convertible to Unicode into a character buffer", it's no more true * Py_BuildValue(), "K" and "L" formats: specify the name of the C type on Windows (_int64 / unsigned _int64) as done for PyArg_Parse*() long long types --CETTE ligne, et les suivantes ci-dessous, seront ignor?es-- M Doc/c-api/arg.rst ................ r81925 | victor.stinner | 2010-06-12 01:46:47 +0200 (Sat, 12 Jun 2010) | 4 lines Issue #8784: Set tarfile default encoding to 'utf-8' on Windows. Note: file system encoding cannot be None anymore (since r81190, issue #8610). ................ r81927 | victor.stinner | 2010-06-12 01:56:51 +0200 (Sat, 12 Jun 2010) | 3 lines Issue #8969: On Windows, use mbcs codec in strict mode to encode and decode filenames and enable os.fsencode(). ................ r81929 | brett.cannon | 2010-06-12 02:38:29 +0200 (Sat, 12 Jun 2010) | 5 lines When dealing with __import__ for detecting a global state change made by a test, make sure to check if __builtins__ is a dict or not. Discovered when running importlib.test.regrtest. ................ r81930 | brett.cannon | 2010-06-12 02:39:28 +0200 (Sat, 12 Jun 2010) | 4 lines Calling __import__ as a method technically works, but really should be wrapped in a staticmethod. This is important for when __import__ is set to a function defined in Python instead of C. ................ r81936 | mark.dickinson | 2010-06-12 11:10:14 +0200 (Sat, 12 Jun 2010) | 2 lines Silence 'unused variable' gcc warning. Patch by ?ric Araujo. ................ r81937 | mark.dickinson | 2010-06-12 11:24:01 +0200 (Sat, 12 Jun 2010) | 2 lines Issue #8981: Remove _struct.__version__. ................ r81938 | mark.dickinson | 2010-06-12 11:25:13 +0200 (Sat, 12 Jun 2010) | 1 line Remove unused variable. ................ r81944 | nick.coghlan | 2010-06-12 15:42:46 +0200 (Sat, 12 Jun 2010) | 9 lines Merged revisions 80578 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r80578 | nick.coghlan | 2010-04-29 00:29:06 +1000 (Thu, 29 Apr 2010) | 1 line Issue 7490: make IGNORE_EXCEPTION_DETAIL also ignore details of the module containing the exception under test (original patch by Lennart Regebro) ........ ................ r81946 | nick.coghlan | 2010-06-12 15:46:56 +0200 (Sat, 12 Jun 2010) | 8 lines Blocked revisions 81945 via svnmerge ........ r81945 | nick.coghlan | 2010-06-12 23:45:37 +1000 (Sat, 12 Jun 2010) | 1 line Backport a fix from Py3k for a potentially misleading example ........ ................ r81947 | mark.dickinson | 2010-06-12 17:17:02 +0200 (Sat, 12 Jun 2010) | 3 lines Issue #8973: Add __all__ to struct module, so that help(struct) correctly displays information for the struct.Struct class. ................ r81948 | mark.dickinson | 2010-06-12 17:19:23 +0200 (Sat, 12 Jun 2010) | 1 line Remove accidental (yet-to-be-reviewed) docstring changes included in r81947. ................ r81949 | mark.dickinson | 2010-06-12 17:43:45 +0200 (Sat, 12 Jun 2010) | 1 line Issue #8973: Improve struct module docstrings. ................ r81950 | mark.dickinson | 2010-06-12 18:30:53 +0200 (Sat, 12 Jun 2010) | 1 line More struct module docs and docstring tweaks. ................ r81951 | mark.dickinson | 2010-06-12 18:37:53 +0200 (Sat, 12 Jun 2010) | 1 line Fix mild type confusion in decimal module docstring. ................ r81952 | alexander.belopolsky | 2010-06-12 19:18:45 +0200 (Sat, 12 Jun 2010) | 1 line Added acknowlegement for Issue #3129 ................ r81954 | benjamin.peterson | 2010-06-12 19:54:44 +0200 (Sat, 12 Jun 2010) | 9 lines Merged revisions 81953 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81953 | benjamin.peterson | 2010-06-12 12:47:06 -0500 (Sat, 12 Jun 2010) | 1 line fix warning with ucs4 ........ ................ r81955 | mark.dickinson | 2010-06-12 20:20:47 +0200 (Sat, 12 Jun 2010) | 1 line Issue #8469: add standard sizes to struct docs table. ................ r81956 | mark.dickinson | 2010-06-12 20:37:54 +0200 (Sat, 12 Jun 2010) | 2 lines Issue #8469: Reorder struct module sections for clarity; other minor tweaks. ................ r81958 | mark.dickinson | 2010-06-12 20:54:20 +0200 (Sat, 12 Jun 2010) | 11 lines Blocked revisions 81957 via svnmerge ........ r81957 | mark.dickinson | 2010-06-12 19:50:34 +0100 (Sat, 12 Jun 2010) | 5 lines Issue #8469: Add standard sizes to table in struct documentation; additional clarifications and documentation tweaks. Backport of revisions 81955-81956 from py3k. ........ ................ r81961 | alexander.belopolsky | 2010-06-12 21:36:28 +0200 (Sat, 12 Jun 2010) | 1 line Issue #8973: Expanded Struct.__doc__. ................ r81965 | mark.dickinson | 2010-06-13 11:17:13 +0200 (Sun, 13 Jun 2010) | 1 line Remove unnecessary brackets from docstring optional arguments. ................ r81968 | mark.dickinson | 2010-06-13 12:52:38 +0200 (Sun, 13 Jun 2010) | 11 lines Merged revisions 81967 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81967 | mark.dickinson | 2010-06-13 11:50:29 +0100 (Sun, 13 Jun 2010) | 4 lines Issue #8986: erfc was raising OverflowError on Linux for arguments in the (approximate) range (-27.3, 30.0), as a result of an escaped errno value. ........ ................ r81970 | mark.dickinson | 2010-06-13 13:07:57 +0200 (Sun, 13 Jun 2010) | 9 lines Merged revisions 81969 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81969 | mark.dickinson | 2010-06-13 12:07:00 +0100 (Sun, 13 Jun 2010) | 1 line Add ?ric Araujo to Misc/ACKS for doc work and many patch and commit reviews. ........ ................ r81972 | mark.dickinson | 2010-06-13 14:02:07 +0200 (Sun, 13 Jun 2010) | 9 lines Merged revisions 81971 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81971 | mark.dickinson | 2010-06-13 13:01:34 +0100 (Sun, 13 Jun 2010) | 1 line Ezio Melotti was missing from Misc/ACKS. ........ ................ r81973 | victor.stinner | 2010-06-13 20:21:50 +0200 (Sun, 13 Jun 2010) | 4 lines Issue #8592: PyArg_Parse*() functions raise a TypeError for "y", "u" and "Z" formats if the string contains a null byte/character. Write unit tests for string formats. ................ r81974 | victor.stinner | 2010-06-13 22:31:26 +0200 (Sun, 13 Jun 2010) | 4 lines getargs.c: remove last reference to "t#" format "t#" format was removed from convertitem() (convertsimple) but not skipitem(). ................ Added: python/branches/py3k-cdecimal/Lib/test/test_sunau.py - copied unchanged from r81974, /python/branches/py3k/Lib/test/test_sunau.py Modified: python/branches/py3k-cdecimal/ (props changed) python/branches/py3k-cdecimal/Doc/c-api/arg.rst python/branches/py3k-cdecimal/Doc/c-api/buffer.rst python/branches/py3k-cdecimal/Doc/library/datetime.rst python/branches/py3k-cdecimal/Doc/library/decimal.rst python/branches/py3k-cdecimal/Doc/library/doctest.rst python/branches/py3k-cdecimal/Doc/library/os.rst python/branches/py3k-cdecimal/Doc/library/struct.rst python/branches/py3k-cdecimal/Doc/library/tarfile.rst python/branches/py3k-cdecimal/Doc/library/xml.dom.minidom.rst python/branches/py3k-cdecimal/Doc/whatsnew/3.2.rst python/branches/py3k-cdecimal/Include/longobject.h python/branches/py3k-cdecimal/Lib/ctypes/test/test_bytes.py python/branches/py3k-cdecimal/Lib/ctypes/test/test_structures.py python/branches/py3k-cdecimal/Lib/decimal.py python/branches/py3k-cdecimal/Lib/doctest.py python/branches/py3k-cdecimal/Lib/logging/config.py python/branches/py3k-cdecimal/Lib/os.py python/branches/py3k-cdecimal/Lib/struct.py python/branches/py3k-cdecimal/Lib/sunau.py python/branches/py3k-cdecimal/Lib/tarfile.py python/branches/py3k-cdecimal/Lib/test/math_testcases.txt python/branches/py3k-cdecimal/Lib/test/regrtest.py python/branches/py3k-cdecimal/Lib/test/test_capi.py python/branches/py3k-cdecimal/Lib/test/test_codecs.py python/branches/py3k-cdecimal/Lib/test/test_curses.py python/branches/py3k-cdecimal/Lib/test/test_doctest.py python/branches/py3k-cdecimal/Lib/test/test_fractions.py python/branches/py3k-cdecimal/Lib/test/test_getargs2.py python/branches/py3k-cdecimal/Lib/test/test_math.py python/branches/py3k-cdecimal/Lib/test/test_minidom.py python/branches/py3k-cdecimal/Lib/test/test_numeric_tower.py python/branches/py3k-cdecimal/Lib/test/test_ssl.py python/branches/py3k-cdecimal/Lib/test/test_struct.py python/branches/py3k-cdecimal/Lib/test/test_sundry.py python/branches/py3k-cdecimal/Lib/test/test_sys.py python/branches/py3k-cdecimal/Lib/test/test_unicode.py python/branches/py3k-cdecimal/Lib/unittest/case.py python/branches/py3k-cdecimal/Lib/unittest/suite.py python/branches/py3k-cdecimal/Lib/unittest/test/test_runner.py python/branches/py3k-cdecimal/Lib/unittest/test/test_setups.py python/branches/py3k-cdecimal/Lib/xml/dom/minidom.py python/branches/py3k-cdecimal/Misc/ACKS python/branches/py3k-cdecimal/Misc/NEWS python/branches/py3k-cdecimal/Misc/maintainers.rst python/branches/py3k-cdecimal/Modules/_codecsmodule.c python/branches/py3k-cdecimal/Modules/_ctypes/_ctypes.c python/branches/py3k-cdecimal/Modules/_ctypes/cfield.c python/branches/py3k-cdecimal/Modules/_localemodule.c python/branches/py3k-cdecimal/Modules/_struct.c python/branches/py3k-cdecimal/Modules/_testcapimodule.c python/branches/py3k-cdecimal/Modules/datetimemodule.c python/branches/py3k-cdecimal/Modules/itertoolsmodule.c python/branches/py3k-cdecimal/Modules/mathmodule.c python/branches/py3k-cdecimal/Modules/readline.c python/branches/py3k-cdecimal/Objects/bytearrayobject.c python/branches/py3k-cdecimal/Objects/bytesobject.c python/branches/py3k-cdecimal/Objects/exceptions.c python/branches/py3k-cdecimal/Objects/longobject.c python/branches/py3k-cdecimal/Objects/stringlib/formatter.h python/branches/py3k-cdecimal/Objects/stringlib/string_format.h python/branches/py3k-cdecimal/Objects/unicodeobject.c python/branches/py3k-cdecimal/PC/winreg.c python/branches/py3k-cdecimal/Parser/asdl_c.py python/branches/py3k-cdecimal/Python/Python-ast.c python/branches/py3k-cdecimal/Python/errors.c python/branches/py3k-cdecimal/Python/getargs.c python/branches/py3k-cdecimal/Python/modsupport.c python/branches/py3k-cdecimal/Python/pythonrun.c python/branches/py3k-cdecimal/Python/symtable.c python/branches/py3k-cdecimal/Python/sysmodule.c python/branches/py3k-cdecimal/setup.py Modified: python/branches/py3k-cdecimal/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/c-api/arg.rst (original) +++ python/branches/py3k-cdecimal/Doc/c-api/arg.rst Mon Jun 14 11:30:15 2010 @@ -53,13 +53,13 @@ drop int support. It is best to always define :cmacro:`PY_SSIZE_T_CLEAN`. -``s`` (Unicode object) [const char \*] +``s`` (:class:`str`) [const char \*] Convert a Unicode object to a C pointer to a character string. A pointer to an existing string is stored in the character pointer variable whose address you pass. The C string is NUL-terminated. The Python string must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. Unicode objects are converted - to C strings using the default encoding. If this conversion fails, a + to C strings using ``'utf-8'`` encoding. If this conversion fails, a :exc:`UnicodeError` is raised. .. note:: @@ -68,118 +68,111 @@ preferrable to use the ``O&`` format with :cfunc:`PyUnicode_FSConverter` as *converter*. -``s*`` (Unicode object or any buffer compatible object) [Py_buffer] +``s*`` (:class:`str`, :class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer] This format accepts Unicode objects as well as objects supporting the - buffer protocol (such as :class:`bytes` or :class:`bytearray` objects). + buffer protocol. It fills a :ctype:`Py_buffer` structure provided by the caller. - Unicode objects are converted to C strings using the default encoding. In this case the resulting C string may contain embedded NUL bytes. + Unicode objects are converted to C strings using ``'utf-8'`` encoding. -``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int or :ctype:`Py_ssize_t`] +``s#`` (:class:`str`, :class:`bytes` or read-only buffer compatible object) [const char \*, int or :ctype:`Py_ssize_t`] Like ``s*``, except that it doesn't accept mutable buffer-like objects such as :class:`bytearray`. The result is stored into two C variables, the first one a pointer to a C string, the second one its length. - The string may contain embedded null bytes. + The string may contain embedded null bytes. Unicode objects are converted + to C strings using ``'utf-8'`` encoding. -``z`` (Unicode object or ``None``) [const char \*] +``z`` (:class:`str` or ``None``) [const char \*] Like ``s``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``z*`` (Unicode object or ``None`` or any buffer compatible object) [Py_buffer] +``z*`` (:class:`str`, :class:`bytes`, :class:`bytearray`, buffer compatible object or ``None``) [Py_buffer] Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :ctype:`Py_buffer` structure is set to *NULL*. -``z#`` (Unicode object or ``None`` or any read buffer compatible object) [const char \*, int] +``z#`` (:class:`str`, :class:`bytes`, read-only buffer compatible object or ``None``) [const char \*, int] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``y`` (bytes object) [const char \*] +``y`` (:class:`bytes`) [const char \*] This format converts a bytes-like object to a C pointer to a character string; it does not accept Unicode objects. The bytes buffer must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. -``y*`` (any buffer compatible object) [Py_buffer \*] +``y*`` (:class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer \*] This variant on ``s*`` doesn't accept Unicode objects, only objects supporting the buffer protocol. **This is the recommended way to accept binary data.** -``y#`` (bytes object) [const char \*, int] +``y#`` (:class:`bytes`) [const char \*, int] This variant on ``s#`` doesn't accept Unicode objects, only bytes-like objects. -``S`` (bytes object) [PyBytesObject \*] +``S`` (:class:`bytes`) [PyBytesObject \*] Requires that the Python object is a :class:`bytes` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a bytes object. The C variable may also be declared as :ctype:`PyObject\*`. -``Y`` (bytearray object) [PyByteArrayObject \*] +``Y`` (:class:`bytearray`) [PyByteArrayObject \*] Requires that the Python object is a :class:`bytearray` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not - a bytearray object. The C variable may also be declared as :ctype:`PyObject\*`. + a :class:`bytearray` object. The C variable may also be declared as :ctype:`PyObject\*`. -``u`` (Unicode object) [Py_UNICODE \*] +``u`` (:class:`str`) [Py_UNICODE \*] Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of Unicode characters. You must pass the address of a :ctype:`Py_UNICODE` pointer variable, which will be filled with the pointer to an existing Unicode buffer. Please note that the width of a :ctype:`Py_UNICODE` character depends on compilation options (it is either 16 or 32 bits). + The Python string must not contain embedded NUL characters; if it does, + a :exc:`TypeError` exception is raised. - ..note :: + .. note:: Since ``u`` doesn't give you back the length of the string, and it may contain embedded NUL characters, it is recommended to use ``u#`` or ``U`` instead. -``u#`` (Unicode object) [Py_UNICODE \*, int] +``u#`` (:class:`str`) [Py_UNICODE \*, int] This variant on ``u`` stores into two C variables, the first one a pointer to a - Unicode data buffer, the second one its length. Non-Unicode objects are handled - by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` - array. + Unicode data buffer, the second one its length. -``Z`` (Unicode or ``None``) [Py_UNICODE \*] +``Z`` (:class:`str` or ``None``) [Py_UNICODE \*] Like ``u``, but the Python object may also be ``None``, in which case the :ctype:`Py_UNICODE` pointer is set to *NULL*. -``Z#`` (Unicode or ``None``) [Py_UNICODE \*, int] +``Z#`` (:class:`str` or ``None``) [Py_UNICODE \*, int] Like ``u#``, but the Python object may also be ``None``, in which case the :ctype:`Py_UNICODE` pointer is set to *NULL*. -``U`` (Unicode object) [PyUnicodeObject \*] +``U`` (:class:`str`) [PyUnicodeObject \*] Requires that the Python object is a Unicode object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a Unicode object. The C variable may also be declared as :ctype:`PyObject\*`. -``t#`` (read-only character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-only buffer - interface. The :ctype:`char\*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. - -``w`` (read-write character buffer) [char \*] - Similar to ``s``, but accepts any object which implements the read-write buffer +``w`` (:class:`bytearray` or read-write character buffer) [char \*] + Similar to ``y``, but accepts any object which implements the read-write buffer interface. The caller must determine the length of the buffer by other means, or use ``w#`` instead. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``w*`` (read-write byte-oriented buffer) [Py_buffer] - This is to ``w`` what ``s*`` is to ``s``. +``w*`` (:class:`bytearray` or read-write byte-oriented buffer) [Py_buffer] + This is to ``w`` what ``y*`` is to ``y``. -``w#`` (read-write character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-write buffer +``w#`` (:class:`bytearray` or read-write character buffer) [char \*, int] + Like ``y#``, but accepts any object which implements the read-write buffer interface. The :ctype:`char \*` variable is set to point to the first byte of the buffer, and the :ctype:`int` is set to the length of the buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - This variant on ``s`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. It only works for encoded data without embedded - NUL bytes. +``es`` (:class:`str`) [const char \*encoding, char \*\*buffer] + This variant on ``s`` is used for encoding Unicode into a character buffer. + It only works for encoded data without embedded NUL bytes. This format requires two arguments. The first is only used as input, and must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. + NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a :ctype:`char\*\*`; the value of the pointer it references will be set to a buffer with the contents of the argument text. @@ -190,19 +183,19 @@ allocated storage. The caller is responsible for calling :cfunc:`PyMem_Free` to free the allocated buffer after use. -``et`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es`` except that 8-bit string objects are passed through without - recoding them. Instead, the implementation assumes that the string object uses +``et`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer] + Same as ``es`` except that byte string objects are passed through without + recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. -``es#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - This variant on ``s#`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. Unlike the ``es`` format, this variant allows - input data which contains NUL characters. +``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] + This variant on ``s#`` is used for encoding Unicode into a character buffer. + Unlike the ``es`` format, this variant allows input data which contains NUL + characters. It requires three arguments. The first is only used as input, and must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. + NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a :ctype:`char\*\*`; the value of the pointer it references will be set to a buffer with the contents of the argument text. @@ -226,71 +219,71 @@ In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. -``et#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - Same as ``es#`` except that string objects are passed through without recoding - them. Instead, the implementation assumes that the string object uses the +``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length] + Same as ``es#`` except that byte string objects are passed through without recoding + them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. Numbers ------- -``b`` (integer) [unsigned char] +``b`` (:class:`int`) [unsigned char] Convert a nonnegative Python integer to an unsigned tiny int, stored in a C :ctype:`unsigned char`. -``B`` (integer) [unsigned char] +``B`` (:class:`int`) [unsigned char] Convert a Python integer to a tiny int without overflow checking, stored in a C :ctype:`unsigned char`. -``h`` (integer) [short int] +``h`` (:class:`int`) [short int] Convert a Python integer to a C :ctype:`short int`. -``H`` (integer) [unsigned short int] +``H`` (:class:`int`) [unsigned short int] Convert a Python integer to a C :ctype:`unsigned short int`, without overflow checking. -``i`` (integer) [int] +``i`` (:class:`int`) [int] Convert a Python integer to a plain C :ctype:`int`. -``I`` (integer) [unsigned int] +``I`` (:class:`int`) [unsigned int] Convert a Python integer to a C :ctype:`unsigned int`, without overflow checking. -``l`` (integer) [long int] +``l`` (:class:`int`) [long int] Convert a Python integer to a C :ctype:`long int`. -``k`` (integer) [unsigned long] +``k`` (:class:`int`) [unsigned long] Convert a Python integer to a C :ctype:`unsigned long` without overflow checking. -``L`` (integer) [PY_LONG_LONG] +``L`` (:class:`int`) [PY_LONG_LONG] Convert a Python integer to a C :ctype:`long long`. This format is only available on platforms that support :ctype:`long long` (or :ctype:`_int64` on Windows). -``K`` (integer) [unsigned PY_LONG_LONG] +``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a Python integer to a C :ctype:`unsigned long long` without overflow checking. This format is only available on platforms that support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows). -``n`` (integer) [Py_ssize_t] +``n`` (:class:`int`) [Py_ssize_t] Convert a Python integer to a C :ctype:`Py_ssize_t`. -``c`` (bytes object of length 1) [char] +``c`` (:class:`bytes` of length 1) [char] Convert a Python byte, represented as a :class:`bytes` object of length 1, to a C :ctype:`char`. -``C`` (Unicode object of length 1) [int] - Convert a Python character, represented as a :class:`str`: object of +``C`` (:class:`str` of length 1) [int] + Convert a Python character, represented as a :class:`str` object of length 1, to a C :ctype:`int`. -``f`` (float) [float] +``f`` (:class:`float`) [float] Convert a Python floating point number to a C :ctype:`float`. -``d`` (float) [double] +``d`` (:class:`float`) [double] Convert a Python floating point number to a C :ctype:`double`. -``D`` (complex) [Py_complex] +``D`` (:class:`complex`) [Py_complex] Convert a Python complex number to a C :ctype:`Py_complex` structure. Other objects @@ -330,7 +323,7 @@ .. versionchanged:: 3.1 Py_CLEANUP_SUPPORTED was added. -``(items)`` (tuple) [*matching-items*] +``(items)`` (:class:`tuple`) [*matching-items*] The object must be a Python sequence whose length is the number of format units in *items*. The C arguments must correspond to the individual format units in *items*. Format units for sequences may be nested. @@ -498,95 +491,96 @@ not within format units such as ``s#``). This can be used to make long format strings a tad more readable. - ``s`` (string) [char \*] - Convert a null-terminated C string to a Python object. If the C string pointer - is *NULL*, ``None`` is used. - - ``s#`` (string) [char \*, int] - Convert a C string and its length to a Python object. If the C string pointer - is *NULL*, the length is ignored and ``None`` is returned. + ``s`` (:class:`str` or ``None``) [char \*] + Convert a null-terminated C string to a Python object using ``'utf-8'`` + encoding. If the C string pointer is *NULL*, ``None`` is used. + + ``s#`` (:class:`str` or ``None``) [char \*, int] + Convert a C string and its length to a Python object using ``'utf-8'`` + encoding. If the C string pointer is *NULL*, the length is ignored and + ``None`` is returned. - ``y`` (bytes) [char \*] + ``y`` (:class:`bytes`) [char \*] This converts a C string to a Python :func:`bytes` object. If the C string pointer is *NULL*, ``None`` is returned. - ``y#`` (bytes) [char \*, int] + ``y#`` (:class:`bytes`) [char \*, int] This converts a C string and its lengths to a Python object. If the C string pointer is *NULL*, ``None`` is returned. - ``z`` (string or ``None``) [char \*] + ``z`` (:class:`str` or ``None``) [char \*] Same as ``s``. - ``z#`` (string or ``None``) [char \*, int] + ``z#`` (:class:`str` or ``None``) [char \*, int] Same as ``s#``. - ``u`` (Unicode string) [Py_UNICODE \*] + ``u`` (:class:`str`) [Py_UNICODE \*] Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned. - ``u#`` (Unicode string) [Py_UNICODE \*, int] + ``u#`` (:class:`str`) [Py_UNICODE \*, int] Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored and ``None`` is returned. - ``U`` (string) [char \*] - Convert a null-terminated C string to a Python unicode object. If the C string - pointer is *NULL*, ``None`` is used. - - ``U#`` (string) [char \*, int] - Convert a C string and its length to a Python unicode object. If the C string - pointer is *NULL*, the length is ignored and ``None`` is returned. + ``U`` (:class:`str` or ``None``) [char \*] + Same as ``s``. + + ``U#`` (:class:`str` or ``None``) [char \*, int] + Same as ``s#``. - ``i`` (integer) [int] + ``i`` (:class:`int`) [int] Convert a plain C :ctype:`int` to a Python integer object. - ``b`` (integer) [char] + ``b`` (:class:`int`) [char] Convert a plain C :ctype:`char` to a Python integer object. - ``h`` (integer) [short int] + ``h`` (:class:`int`) [short int] Convert a plain C :ctype:`short int` to a Python integer object. - ``l`` (integer) [long int] + ``l`` (:class:`int`) [long int] Convert a C :ctype:`long int` to a Python integer object. - ``B`` (integer) [unsigned char] + ``B`` (:class:`int`) [unsigned char] Convert a C :ctype:`unsigned char` to a Python integer object. - ``H`` (integer) [unsigned short int] + ``H`` (:class:`int`) [unsigned short int] Convert a C :ctype:`unsigned short int` to a Python integer object. - ``I`` (integer) [unsigned int] + ``I`` (:class:`int`) [unsigned int] Convert a C :ctype:`unsigned int` to a Python integer object. - ``k`` (integer) [unsigned long] + ``k`` (:class:`int`) [unsigned long] Convert a C :ctype:`unsigned long` to a Python integer object. - ``L`` (long) [PY_LONG_LONG] + ``L`` (:class:`int`) [PY_LONG_LONG] Convert a C :ctype:`long long` to a Python integer object. Only available - on platforms that support :ctype:`long long`. + on platforms that support :ctype:`long long` (or :ctype:`_int64` on + Windows). - ``K`` (long) [unsigned PY_LONG_LONG] + ``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a C :ctype:`unsigned long long` to a Python integer object. Only - available on platforms that support :ctype:`unsigned long long`. + available on platforms that support :ctype:`unsigned long long` (or + :ctype:`unsigned _int64` on Windows). - ``n`` (int) [Py_ssize_t] + ``n`` (:class:`int`) [Py_ssize_t] Convert a C :ctype:`Py_ssize_t` to a Python integer. - ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a byte to a Python byte string of + ``c`` (:class:`bytes` of length 1) [char] + Convert a C :ctype:`int` representing a byte to a Python :class:`bytes` object of length 1. - ``C`` (string of length 1) [int] - Convert a C :ctype:`int` representing a character to Python unicode - string of length 1. + ``C`` (:class:`str` of length 1) [int] + Convert a C :ctype:`int` representing a character to Python :class:`str` + object of length 1. - ``d`` (float) [double] + ``d`` (:class:`float`) [double] Convert a C :ctype:`double` to a Python floating point number. - ``f`` (float) [float] - Same as ``d``. + ``f`` (:class:`float`) [float] + Convert a C :ctype:`float` to a Python floating point number. - ``D`` (complex) [Py_complex \*] + ``D`` (:class:`complex`) [Py_complex \*] Convert a C :ctype:`Py_complex` structure to a Python complex number. ``O`` (object) [PyObject \*] @@ -611,13 +605,13 @@ \*`) as its argument and should return a "new" Python object, or *NULL* if an error occurred. - ``(items)`` (tuple) [*matching-items*] + ``(items)`` (:class:`tuple`) [*matching-items*] Convert a sequence of C values to a Python tuple with the same number of items. - ``[items]`` (list) [*matching-items*] + ``[items]`` (:class:`list`) [*matching-items*] Convert a sequence of C values to a Python list with the same number of items. - ``{items}`` (dictionary) [*matching-items*] + ``{items}`` (:class:`dict`) [*matching-items*] Convert a sequence of C values to a Python dictionary. Each pair of consecutive C values adds one item to the dictionary, serving as key and value, respectively. Modified: python/branches/py3k-cdecimal/Doc/c-api/buffer.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/c-api/buffer.rst (original) +++ python/branches/py3k-cdecimal/Doc/c-api/buffer.rst Mon Jun 14 11:30:15 2010 @@ -249,10 +249,10 @@ +------------------------------+---------------------------------------------------+ -.. cfunction:: void PyBuffer_Release(PyObject *obj, Py_buffer *view) +.. cfunction:: void PyBuffer_Release(Py_buffer *view) - Release the buffer *view* over *obj*. This should be called when the buffer - is no longer being used as it may free memory from it. + Release the buffer *view*. This should be called when the buffer is no + longer being used as it may free memory from it. .. cfunction:: Py_ssize_t PyBuffer_SizeFromFormat(const char *) Modified: python/branches/py3k-cdecimal/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/datetime.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/datetime.rst Mon Jun 14 11:30:15 2010 @@ -480,7 +480,9 @@ Return a :class:`time.struct_time` such as returned by :func:`time.localtime`. The hours, minutes and seconds are 0, and the DST flag is -1. ``d.timetuple()`` is equivalent to ``time.struct_time((d.year, d.month, d.day, 0, 0, 0, - d.weekday(), d.toordinal() - date(d.year, 1, 1).toordinal() + 1, -1))`` + d.weekday(), yday, -1))``, where ``yday = d.toordinal() - date(d.year, 1, + 1).toordinal() + 1`` is the day number within the current year starting with + ``1`` for January 1st. .. method:: date.toordinal() @@ -944,12 +946,13 @@ Return a :class:`time.struct_time` such as returned by :func:`time.localtime`. ``d.timetuple()`` is equivalent to ``time.struct_time((d.year, d.month, d.day, - d.hour, d.minute, d.second, d.weekday(), d.toordinal() - date(d.year, 1, - 1).toordinal() + 1, dst))`` The :attr:`tm_isdst` flag of the result is set - according to the :meth:`dst` method: :attr:`tzinfo` is ``None`` or :meth:`dst` - returns ``None``, :attr:`tm_isdst` is set to ``-1``; else if :meth:`dst` - returns a non-zero value, :attr:`tm_isdst` is set to ``1``; else ``tm_isdst`` is - set to ``0``. + d.hour, d.minute, d.second, d.weekday(), yday, dst))``, where ``yday = + d.toordinal() - date(d.year, 1, 1).toordinal() + 1`` is the day number within + the current year starting with ``1`` for January 1st. The :attr:`tm_isdst` flag + of the result is set according to the :meth:`dst` method: :attr:`tzinfo` is + ``None`` or :meth:`dst`` returns ``None``, :attr:`tm_isdst` is set to ``-1``; + else if :meth:`dst` returns a non-zero value, :attr:`tm_isdst` is set to ``1``; + else :attr:`tm_isdst` is set to ``0``. .. method:: datetime.utctimetuple() Modified: python/branches/py3k-cdecimal/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/decimal.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/decimal.rst Mon Jun 14 11:30:15 2010 @@ -363,23 +363,17 @@ compared, sorted, and coerced to another type (such as :class:`float` or :class:`int`). - Decimal objects cannot generally be combined with floats in - arithmetic operations: an attempt to add a :class:`Decimal` to a - :class:`float`, for example, will raise a :exc:`TypeError`. - There's one exception to this rule: it's possible to use Python's - comparison operators to compare a :class:`float` instance ``x`` - with a :class:`Decimal` instance ``y``. Without this exception, - comparisons between :class:`Decimal` and :class:`float` instances - would follow the general rules for comparing objects of different - types described in the :ref:`expressions` section of the reference - manual, leading to confusing results. + Decimal objects cannot generally be combined with floats or + instances of :class:`fractions.Fraction` in arithmetic operations: + an attempt to add a :class:`Decimal` to a :class:`float`, for + example, will raise a :exc:`TypeError`. However, it is possible to + use Python's comparison operators to compare a :class:`Decimal` + instance ``x`` with another number ``y``. This avoids confusing results + when doing equality comparisons between numbers of different types. .. versionchanged:: 3.2 - A comparison between a :class:`float` instance ``x`` and a - :class:`Decimal` instance ``y`` now returns a result based on - the values of ``x`` and ``y``. In earlier versions ``x < y`` - returned the same (arbitrary) result for any :class:`Decimal` - instance ``x`` and any :class:`float` instance ``y``. + Mixed-type comparisons between :class:`Decimal` instances and + other numeric types are now fully supported. In addition to the standard numeric properties, decimal floating point objects also have a number of specialized methods: Modified: python/branches/py3k-cdecimal/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/doctest.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/doctest.rst Mon Jun 14 11:30:15 2010 @@ -444,8 +444,9 @@ with an alphanumeric is taken to be the start of the exception detail. Of course this does the right thing for genuine tracebacks. -* When the :const:`IGNORE_EXCEPTION_DETAIL` doctest option is is specified, - everything following the leftmost colon is ignored. +* When the :const:`IGNORE_EXCEPTION_DETAIL` doctest option is specified, + everything following the leftmost colon and any module information in the + exception name is ignored. * The interactive shell omits the traceback header line for some :exc:`SyntaxError`\ s. But doctest uses the traceback header line to @@ -535,20 +536,38 @@ exception raised is ``ValueError: 3*14``, but will fail, e.g., if :exc:`TypeError` is raised. - Note that a similar effect can be obtained using :const:`ELLIPSIS`, and - :const:`IGNORE_EXCEPTION_DETAIL` may go away when Python releases prior to 2.4 - become uninteresting. Until then, :const:`IGNORE_EXCEPTION_DETAIL` is the only - clear way to write a doctest that doesn't care about the exception detail yet - continues to pass under Python releases prior to 2.4 (doctest directives appear - to be comments to them). For example, :: + It will also ignore the module name used in Python 3 doctest reports. Hence + both these variations will work regardless of whether the test is run under + Python 2.7 or Python 3.2 (or later versions): + + >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + CustomError: message + + >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + my_module.CustomError: message + + Note that :const:`ELLIPSIS` can also be used to ignore the + details of the exception message, but such a test may still fail based + on whether or not the module details are printed as part of the + exception name. Using :const:`IGNORE_EXCEPTION_DETAIL` and the details + from Python 2.3 is also the only clear way to write a doctest that doesn't + care about the exception detail yet continues to pass under Python 2.3 or + earlier (those releases do not support doctest directives and ignore them + as irrelevant comments). For example, :: >>> (1, 2)[3] = 'moo' #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): File "", line 1, in ? TypeError: object doesn't support item assignment - passes under Python 2.4 and Python 2.3. The detail changed in 2.4, to say "does - not" instead of "doesn't". + passes under Python 2.3 and later Python versions, even though the detail + changed in Python 2.4 to say "does not" instead of "doesn't". + + .. versionchanged:: 3.2 + :const:`IGNORE_EXCEPTION_DETAIL` now also ignores any information + relating to the module containing the exception under test .. data:: SKIP @@ -663,7 +682,6 @@ functions that run doctests, establishing different defaults. In such cases, disabling an option via ``-`` in a directive can be useful. - There's also a way to register new option flag names, although this isn't useful unless you intend to extend :mod:`doctest` internals via subclassing: Modified: python/branches/py3k-cdecimal/Doc/library/os.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/os.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/os.rst Mon Jun 14 11:30:15 2010 @@ -159,10 +159,10 @@ .. function:: fsencode(value) Encode *value* to bytes for use in the file system, environment variables or - the command line. Uses :func:`sys.getfilesystemencoding` and - ``'surrogateescape'`` error handler for strings and returns bytes unchanged. - - Availability: Unix. + the command line. Use :func:`sys.getfilesystemencoding` and + ``'surrogateescape'`` error handler for strings and return bytes unchanged. + On Windows, use ``'strict'`` error handler for strings if the file system + encoding is ``'mbcs'`` (which is the default encoding). .. versionadded:: 3.2 Modified: python/branches/py3k-cdecimal/Doc/library/struct.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/struct.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/struct.rst Mon Jun 14 11:30:15 2010 @@ -38,38 +38,38 @@ .. function:: pack(fmt, v1, v2, ...) - Return a bytes containing the values ``v1, v2, ...`` packed according to the - given format. The arguments must match the values required by the format - exactly. + Return a bytes object containing the values *v1*, *v2*, ... packed according + to the format string *fmt*. The arguments must match the values required by + the format exactly. .. function:: pack_into(fmt, buffer, offset, v1, v2, ...) - Pack the values ``v1, v2, ...`` according to the given format, write the - packed bytes into the writable *buffer* starting at *offset*. Note that the - offset is a required argument. + Pack the values *v1*, *v2*, ... according to the format string *fmt* and + write the packed bytes into the writable buffer *buffer* starting at + position *offset*. Note that *offset* is a required argument. -.. function:: unpack(fmt, bytes) +.. function:: unpack(fmt, buffer) - Unpack the bytes (presumably packed by ``pack(fmt, ...)``) according to the - given format. The result is a tuple even if it contains exactly one item. - The bytes must contain exactly the amount of data required by the format - (``len(bytes)`` must equal ``calcsize(fmt)``). + Unpack from the buffer *buffer* (presumably packed by ``pack(fmt, ...)``) + according to the format string *fmt*. The result is a tuple even if it + contains exactly one item. The buffer must contain exactly the amount of + data required by the format (``len(bytes)`` must equal ``calcsize(fmt)``). .. function:: unpack_from(fmt, buffer, offset=0) - Unpack the *buffer* according to the given format. The result is a tuple even - if it contains exactly one item. The *buffer* must contain at least the - amount of data required by the format (``len(buffer[offset:])`` must be at - least ``calcsize(fmt)``). + Unpack from *buffer* starting at position *offset*, according to the format + string *fmt*. The result is a tuple even if it contains exactly one + item. *buffer* must contain at least the amount of data required by the + format (``len(buffer[offset:])`` must be at least ``calcsize(fmt)``). .. function:: calcsize(fmt) - Return the size of the struct (and hence of the bytes) corresponding to the - given format. + Return the size of the struct (and hence of the bytes object produced by + ``pack(fmt, ...)``) corresponding to the format string *fmt*. .. _struct-format-strings: @@ -77,9 +77,84 @@ -------------- Format strings are the mechanism used to specify the expected layout when -packing and unpacking data. They are built up from format characters, which -specify the type of data being packed/unpacked. In addition, there are -special characters for controlling the byte order, size, and alignment. +packing and unpacking data. They are built up from :ref:`format-characters`, +which specify the type of data being packed/unpacked. In addition, there are +special characters for controlling the :ref:`struct-alignment`. + + +.. _struct-alignment: + +Byte Order, Size, and Alignment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, C types are represented in the machine's native format and byte +order, and properly aligned by skipping pad bytes if necessary (according to the +rules used by the C compiler). + +Alternatively, the first character of the format string can be used to indicate +the byte order, size and alignment of the packed data, according to the +following table: + ++-----------+------------------------+--------------------+ +| Character | Byte order | Size and alignment | ++===========+========================+====================+ +| ``@`` | native | native | ++-----------+------------------------+--------------------+ +| ``=`` | native | standard | ++-----------+------------------------+--------------------+ +| ``<`` | little-endian | standard | ++-----------+------------------------+--------------------+ +| ``>`` | big-endian | standard | ++-----------+------------------------+--------------------+ +| ``!`` | network (= big-endian) | standard | ++-----------+------------------------+--------------------+ + +If the first character is not one of these, ``'@'`` is assumed. + +Native byte order is big-endian or little-endian, depending on the host +system. For example, Intel x86 and AMD64 (x86-64) are little-endian; +Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature +switchable endianness (bi-endian). Use ``sys.byteorder`` to check the +endianness of your system. + +Native size and alignment are determined using the C compiler's +``sizeof`` expression. This is always combined with native byte order. + +Standard size and alignment are as follows: no alignment is required for any +type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and +:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 +bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating +point numbers, respectively. :ctype:`_Bool` is 1 byte. + +Note the difference between ``'@'`` and ``'='``: both use native byte order, but +the size and alignment of the latter is standardized. + +The form ``'!'`` is available for those poor souls who claim they can't remember +whether network byte order is big-endian or little-endian. + +There is no way to indicate non-native byte order (force byte-swapping); use the +appropriate choice of ``'<'`` or ``'>'``. + +The ``'P'`` format character is only available for the native byte ordering +(selected as the default or with the ``'@'`` byte order character). The byte +order character ``'='`` chooses to use little- or big-endian ordering based on +the host system. The struct module does not interpret this as native ordering, +so the ``'P'`` format is not available. + +Notes: + +(1) Padding is only automatically added between successive structure members. + No padding is added at the beginning or the end of the encoded struct. + +(2) No padding is added when using non-native size and alignment, e.g. + with '<', '>', '=', and '!'. + +(3) To align the end of a structure to the alignment requirement of a + particular type, end the format with the code for that type with a repeat + count of zero. See :ref:`struct-examples`. + + +.. _format-characters: Format Characters ^^^^^^^^^^^^^^^^^ @@ -87,46 +162,46 @@ Format characters have the following meaning; the conversion between C and Python values should be obvious given their types: -+--------+-------------------------+--------------------+------------+ -| Format | C Type | Python | Notes | -+========+=========================+====================+============+ -| ``x`` | pad byte | no value | | -+--------+-------------------------+--------------------+------------+ -| ``c`` | :ctype:`char` | bytes of length 1 | | -+--------+-------------------------+--------------------+------------+ -| ``b`` | :ctype:`signed char` | integer | \(1),\(4) | -+--------+-------------------------+--------------------+------------+ -| ``B`` | :ctype:`unsigned char` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``?`` | :ctype:`_Bool` | bool | \(2) | -+--------+-------------------------+--------------------+------------+ -| ``h`` | :ctype:`short` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``H`` | :ctype:`unsigned short` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``i`` | :ctype:`int` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``I`` | :ctype:`unsigned int` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``l`` | :ctype:`long` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``L`` | :ctype:`unsigned long` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``q`` | :ctype:`long long` | integer | \(3), \(4) | -+--------+-------------------------+--------------------+------------+ -| ``Q`` | :ctype:`unsigned long | integer | \(3), \(4) | -| | long` | | | -+--------+-------------------------+--------------------+------------+ -| ``f`` | :ctype:`float` | float | | -+--------+-------------------------+--------------------+------------+ -| ``d`` | :ctype:`double` | float | | -+--------+-------------------------+--------------------+------------+ -| ``s`` | :ctype:`char[]` | bytes | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``p`` | :ctype:`char[]` | bytes | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | -+--------+-------------------------+--------------------+------------+ ++--------+-------------------------+--------------------+----------------+------------+ +| Format | C Type | Python type | Standard size | Notes | ++========+=========================+====================+================+============+ +| ``x`` | pad byte | no value | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``c`` | :ctype:`char` | bytes of length 1 | 1 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``b`` | :ctype:`signed char` | integer | 1 | \(1),\(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``B`` | :ctype:`unsigned char` | integer | 1 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``?`` | :ctype:`_Bool` | bool | 1 | \(2) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``h`` | :ctype:`short` | integer | 2 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``H`` | :ctype:`unsigned short` | integer | 2 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``i`` | :ctype:`int` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``I`` | :ctype:`unsigned int` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``l`` | :ctype:`long` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``L`` | :ctype:`unsigned long` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``q`` | :ctype:`long long` | integer | 8 | \(3), \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``Q`` | :ctype:`unsigned long | integer | 8 | \(3), \(4) | +| | long` | | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``f`` | :ctype:`float` | float | 4 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``d`` | :ctype:`double` | float | 8 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``s`` | :ctype:`char[]` | bytes | | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``p`` | :ctype:`char[]` | bytes | | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``P`` | :ctype:`void \*` | integer | | | ++--------+-------------------------+--------------------+----------------+------------+ Notes: @@ -196,77 +271,6 @@ any non-zero value will be True when unpacking. -.. _struct-alignment: - -Byte Order, Size, and Alignment -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -By default, C types are represented in the machine's native format and byte -order, and properly aligned by skipping pad bytes if necessary (according to the -rules used by the C compiler). - -Alternatively, the first character of the format string can be used to indicate -the byte order, size and alignment of the packed data, according to the -following table: - -+-----------+------------------------+--------------------+ -| Character | Byte order | Size and alignment | -+===========+========================+====================+ -| ``@`` | native | native | -+-----------+------------------------+--------------------+ -| ``=`` | native | standard | -+-----------+------------------------+--------------------+ -| ``<`` | little-endian | standard | -+-----------+------------------------+--------------------+ -| ``>`` | big-endian | standard | -+-----------+------------------------+--------------------+ -| ``!`` | network (= big-endian) | standard | -+-----------+------------------------+--------------------+ - -If the first character is not one of these, ``'@'`` is assumed. - -Native byte order is big-endian or little-endian, depending on the host -system. For example, Intel x86 and AMD64 (x86-64) are little-endian; -Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature -switchable endianness (bi-endian). Use ``sys.byteorder`` to check the -endianness of your system. - -Native size and alignment are determined using the C compiler's -``sizeof`` expression. This is always combined with native byte order. - -Standard size and alignment are as follows: no alignment is required for any -type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and -:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 -bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating -point numbers, respectively. :ctype:`_Bool` is 1 byte. - -Note the difference between ``'@'`` and ``'='``: both use native byte order, but -the size and alignment of the latter is standardized. - -The form ``'!'`` is available for those poor souls who claim they can't remember -whether network byte order is big-endian or little-endian. - -There is no way to indicate non-native byte order (force byte-swapping); use the -appropriate choice of ``'<'`` or ``'>'``. - -The ``'P'`` format character is only available for the native byte ordering -(selected as the default or with the ``'@'`` byte order character). The byte -order character ``'='`` chooses to use little- or big-endian ordering based on -the host system. The struct module does not interpret this as native ordering, -so the ``'P'`` format is not available. - -Notes: - -(1) Padding is only automatically added between successive structure members. - No padding is added at the beginning or the end of the encoded struct. - -(2) No padding is added when using non-native size and alignment, e.g. - with '<', '>', '=', and '!'. - -(3) To align the end of a structure to the alignment requirement of a - particular type, end the format with the code for that type with a repeat - count of zero. See :ref:`struct-examples`. - .. _struct-examples: @@ -331,7 +335,7 @@ .. _struct-objects: -Objects +Classes ------- The :mod:`struct` module also defines the following type: @@ -358,10 +362,10 @@ Identical to the :func:`pack_into` function, using the compiled format. - .. method:: unpack(bytes) + .. method:: unpack(buffer) Identical to the :func:`unpack` function, using the compiled format. - (``len(bytes)`` must equal :attr:`self.size`). + (``len(buffer)`` must equal :attr:`self.size`). .. method:: unpack_from(buffer, offset=0) @@ -376,6 +380,6 @@ .. attribute:: size - The calculated size of the struct (and hence of the bytes) corresponding - to :attr:`format`. + The calculated size of the struct (and hence of the bytes object produced + by the :meth:`pack` method) corresponding to :attr:`format`. Modified: python/branches/py3k-cdecimal/Doc/library/tarfile.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/tarfile.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/tarfile.rst Mon Jun 14 11:30:15 2010 @@ -185,8 +185,8 @@ .. data:: ENCODING - The default character encoding i.e. the value from either - :func:`sys.getfilesystemencoding` or :func:`sys.getdefaultencoding`. + The default character encoding: ``'utf-8'`` on Windows, + :func:`sys.getfilesystemencoding` otherwise. .. seealso:: Modified: python/branches/py3k-cdecimal/Doc/library/xml.dom.minidom.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/library/xml.dom.minidom.rst (original) +++ python/branches/py3k-cdecimal/Doc/library/xml.dom.minidom.rst Mon Jun 14 11:30:15 2010 @@ -114,6 +114,13 @@ to be called on the :class:`Document` object, but may be called on child nodes to discard children of that node. + You can avoid calling this method explicitly by using the :keyword:`with` + statement. The following code will automatically unlink *dom* when the + :keyword:`with` block is exited:: + + with xml.dom.minidom.parse(datasource) as dom: + ... # Work with dom. + .. method:: Node.writexml(writer, indent="", addindent="", newl="", encoding="") Modified: python/branches/py3k-cdecimal/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k-cdecimal/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k-cdecimal/Doc/whatsnew/3.2.rst Mon Jun 14 11:30:15 2010 @@ -173,4 +173,7 @@ * bytearray objects cannot be used anymore as filenames: convert them to bytes +* "t#" format of PyArg_Parse*() functions has been removed: use "s#" or "s*" + instead + * Stub Modified: python/branches/py3k-cdecimal/Include/longobject.h ============================================================================== --- python/branches/py3k-cdecimal/Include/longobject.h (original) +++ python/branches/py3k-cdecimal/Include/longobject.h Mon Jun 14 11:30:15 2010 @@ -101,13 +101,13 @@ */ PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); -/* _PyLong_Divmod_Near. Given integers a and b, compute the nearest +/* _PyLong_DivmodNear. Given integers a and b, compute the nearest integer q to the exact quotient a / b, rounding to the nearest even integer in the case of a tie. Return (q, r), where r = a - q*b. The remainder r will satisfy abs(r) <= abs(b)/2, with equality possible only if q is even. */ -PyAPI_FUNC(PyObject *) _PyLong_Divmod_Near(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *); /* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in base 256, and return a Python long with the same numeric value. Modified: python/branches/py3k-cdecimal/Lib/ctypes/test/test_bytes.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/ctypes/test/test_bytes.py (original) +++ python/branches/py3k-cdecimal/Lib/ctypes/test/test_bytes.py Mon Jun 14 11:30:15 2010 @@ -30,8 +30,8 @@ X("abc") x = X(b"abc") - self.assertEqual(x.a, "abc") - self.assertEqual(type(x.a), str) + self.assertEqual(x.a, b"abc") + self.assertEqual(type(x.a), bytes) def test_struct_W(self): class X(Structure): Modified: python/branches/py3k-cdecimal/Lib/ctypes/test/test_structures.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/ctypes/test/test_structures.py (original) +++ python/branches/py3k-cdecimal/Lib/ctypes/test/test_structures.py Mon Jun 14 11:30:15 2010 @@ -209,9 +209,9 @@ self.assertRaises(TypeError, Person, "Name", "HI") # short enough - self.assertEqual(Person("12345", 5).name, "12345") + self.assertEqual(Person("12345", 5).name, b"12345") # exact fit - self.assertEqual(Person("123456", 5).name, "123456") + self.assertEqual(Person("123456", 5).name, b"123456") # too long self.assertRaises(ValueError, Person, "1234567", 5) @@ -269,9 +269,9 @@ p = Person("Someone", ("1234", "5678"), 5) - self.assertEqual(p.name, "Someone") - self.assertEqual(p.phone.areacode, "1234") - self.assertEqual(p.phone.number, "5678") + self.assertEqual(p.name, b"Someone") + self.assertEqual(p.phone.areacode, b"1234") + self.assertEqual(p.phone.number, b"5678") self.assertEqual(p.age, 5) def test_structures_with_wchar(self): Modified: python/branches/py3k-cdecimal/Lib/decimal.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/decimal.py (original) +++ python/branches/py3k-cdecimal/Lib/decimal.py Mon Jun 14 11:30:15 2010 @@ -31,7 +31,8 @@ useful for financial applications or for contexts where users have expectations that are at odds with binary floating point (for instance, in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead -of the expected Decimal('0.00') returned by decimal floating point). +of 0.0; Decimal('1.00') % Decimal('0.1') returns the expected +Decimal('0.00')). Here are some examples of using the decimal module: @@ -862,7 +863,7 @@ # that specified by IEEE 754. def __eq__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other, equality_op=True) if other is NotImplemented: return other if self._check_nans(other, context): @@ -870,7 +871,7 @@ return self._cmp(other) == 0 def __ne__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other, equality_op=True) if other is NotImplemented: return other if self._check_nans(other, context): @@ -879,7 +880,7 @@ def __lt__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -888,7 +889,7 @@ return self._cmp(other) < 0 def __le__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -897,7 +898,7 @@ return self._cmp(other) <= 0 def __gt__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -906,7 +907,7 @@ return self._cmp(other) > 0 def __ge__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -5860,6 +5861,37 @@ raise TypeError("Unable to convert %s to Decimal" % other) return NotImplemented +def _convert_for_comparison(self, other, equality_op=False): + """Given a Decimal instance self and a Python object other, return + a pair (s, o) of Decimal instances such that "s op o" is + equivalent to "self op other" for any of the 6 comparison + operators "op". + + """ + if isinstance(other, Decimal): + return self, other + + # Comparison with a Rational instance (also includes integers): + # self op n/d <=> self*d op n (for n and d integers, d positive). + # A NaN or infinity can be left unchanged without affecting the + # comparison result. + if isinstance(other, _numbers.Rational): + if not self._is_special: + self = _dec_from_triple(self._sign, + str(int(self._int) * other.denominator), + self._exp) + return self, Decimal(other.numerator) + + # Comparisons with float and complex types. == and != comparisons + # with complex numbers should succeed, returning either True or False + # as appropriate. Other comparisons return NotImplemented. + if equality_op and isinstance(other, _numbers.Complex) and other.imag == 0: + other = other.real + if isinstance(other, float): + return self, Decimal.from_float(other) + return NotImplemented, NotImplemented + + ##### Setup Specific Contexts ############################################ # The default context prototype used by Context() Modified: python/branches/py3k-cdecimal/Lib/doctest.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/doctest.py (original) +++ python/branches/py3k-cdecimal/Lib/doctest.py Mon Jun 14 11:30:15 2010 @@ -1277,9 +1277,9 @@ # Another chance if they didn't care about the detail. elif self.optionflags & IGNORE_EXCEPTION_DETAIL: - m1 = re.match(r'[^:]*:', example.exc_msg) - m2 = re.match(r'[^:]*:', exc_msg) - if m1 and m2 and check(m1.group(0), m2.group(0), + m1 = re.match(r'(?:[^:]*\.)?([^:]*:)', example.exc_msg) + m2 = re.match(r'(?:[^:]*\.)?([^:]*:)', exc_msg) + if m1 and m2 and check(m1.group(1), m2.group(1), self.optionflags): outcome = SUCCESS Modified: python/branches/py3k-cdecimal/Lib/logging/config.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/logging/config.py (original) +++ python/branches/py3k-cdecimal/Lib/logging/config.py Mon Jun 14 11:30:15 2010 @@ -373,7 +373,7 @@ } # We might want to use a different one, e.g. importlib - importer = __import__ + importer = staticmethod(__import__) def __init__(self, config): self.config = ConvertingDict(config) Modified: python/branches/py3k-cdecimal/Lib/os.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/os.py (original) +++ python/branches/py3k-cdecimal/Lib/os.py Mon Jun 14 11:30:15 2010 @@ -533,16 +533,19 @@ return environb.get(key, default) __all__.append("getenvb") -if name != 'nt': - def fsencode(value): - """Encode value for use in the file system, environment variables - or the command line.""" - if isinstance(value, bytes): - return value - elif isinstance(value, str): - return value.encode(sys.getfilesystemencoding(), 'surrogateescape') +def fsencode(value): + """Encode value for use in the file system, environment variables + or the command line.""" + if isinstance(value, bytes): + return value + elif isinstance(value, str): + encoding = sys.getfilesystemencoding() + if encoding == 'mbcs': + return value.encode(encoding) else: - raise TypeError("expect bytes or str, not %s" % type(value).__name__) + return value.encode(encoding, 'surrogateescape') + else: + raise TypeError("expect bytes or str, not %s" % type(value).__name__) def _exists(name): return name in globals() Modified: python/branches/py3k-cdecimal/Lib/struct.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/struct.py (original) +++ python/branches/py3k-cdecimal/Lib/struct.py Mon Jun 14 11:30:15 2010 @@ -1,3 +1,14 @@ +__all__ = [ + # Functions + 'calcsize', 'pack', 'unpack', 'unpack', 'unpack_from', + + # Classes + 'Struct', + + # Exceptions + 'error' + ] + from _struct import * from _struct import _clearcache from _struct import __doc__ Modified: python/branches/py3k-cdecimal/Lib/sunau.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/sunau.py (original) +++ python/branches/py3k-cdecimal/Lib/sunau.py Mon Jun 14 11:30:15 2010 @@ -299,7 +299,7 @@ self._nframeswritten = 0 self._datawritten = 0 self._datalength = 0 - self._info = '' + self._info = b'' self._comptype = 'ULAW' # default is U-law def setnchannels(self, nchannels): Modified: python/branches/py3k-cdecimal/Lib/tarfile.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/tarfile.py (original) +++ python/branches/py3k-cdecimal/Lib/tarfile.py Mon Jun 14 11:30:15 2010 @@ -159,9 +159,10 @@ #--------------------------------------------------------- # initialization #--------------------------------------------------------- -ENCODING = sys.getfilesystemencoding() -if ENCODING is None: - ENCODING = "ascii" +if os.name in ("nt", "ce"): + ENCODING = "utf-8" +else: + ENCODING = sys.getfilesystemencoding() #--------------------------------------------------------- # Some useful functions Modified: python/branches/py3k-cdecimal/Lib/test/math_testcases.txt ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/math_testcases.txt (original) +++ python/branches/py3k-cdecimal/Lib/test/math_testcases.txt Mon Jun 14 11:30:15 2010 @@ -84,6 +84,25 @@ erf0042 erf -1e150 -> -1.0 erf0043 erf 1.7e308 -> 1.0 +-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold +-- incorrectly signalled overflow on some platforms. +erf0100 erf 26.2 -> 1.0 +erf0101 erf 26.4 -> 1.0 +erf0102 erf 26.6 -> 1.0 +erf0103 erf 26.8 -> 1.0 +erf0104 erf 27.0 -> 1.0 +erf0105 erf 27.2 -> 1.0 +erf0106 erf 27.4 -> 1.0 +erf0107 erf 27.6 -> 1.0 + +erf0110 erf -26.2 -> -1.0 +erf0111 erf -26.4 -> -1.0 +erf0112 erf -26.6 -> -1.0 +erf0113 erf -26.8 -> -1.0 +erf0114 erf -27.0 -> -1.0 +erf0115 erf -27.2 -> -1.0 +erf0116 erf -27.4 -> -1.0 +erf0117 erf -27.6 -> -1.0 ---------------------------------------- -- erfc: complementary error function -- @@ -127,6 +146,25 @@ erfc0052 erfc -1e150 -> 2.0 erfc0053 erfc 1.7e308 -> 0.0 +-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold +-- incorrectly signalled overflow on some platforms. +erfc0100 erfc 26.2 -> 1.6432507924389461e-300 +erfc0101 erfc 26.4 -> 4.4017768588035426e-305 +erfc0102 erfc 26.6 -> 1.0885125885442269e-309 +erfc0103 erfc 26.8 -> 2.4849621571966629e-314 +erfc0104 erfc 27.0 -> 5.2370464393526292e-319 +erfc0105 erfc 27.2 -> 9.8813129168249309e-324 +erfc0106 erfc 27.4 -> 0.0 +erfc0107 erfc 27.6 -> 0.0 + +erfc0110 erfc -26.2 -> 2.0 +erfc0111 erfc -26.4 -> 2.0 +erfc0112 erfc -26.6 -> 2.0 +erfc0113 erfc -26.8 -> 2.0 +erfc0114 erfc -27.0 -> 2.0 +erfc0115 erfc -27.2 -> 2.0 +erfc0116 erfc -27.4 -> 2.0 +erfc0117 erfc -27.6 -> 2.0 --------------------------------------------------------- -- lgamma: log of absolute value of the gamma function -- Modified: python/branches/py3k-cdecimal/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/regrtest.py (original) +++ python/branches/py3k-cdecimal/Lib/test/regrtest.py Mon Jun 14 11:30:15 2010 @@ -859,9 +859,15 @@ sys.path_hooks[:] = saved_hooks[2] def get___import__(self): - return __builtins__.__import__ + if isinstance(__builtins__, dict): + return __builtins__['__import__'] + else: + return __builtins__.__import__ def restore___import__(self, import_): - __builtins__.__import__ = import_ + if isinstance(__builtins__, dict): + __builtins__['__import__'] = import_ + else: + __builtins__.__import__ = import_ def get_warnings_filters(self): return id(warnings.filters), warnings.filters, warnings.filters[:] Modified: python/branches/py3k-cdecimal/Lib/test/test_capi.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_capi.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_capi.py Mon Jun 14 11:30:15 2010 @@ -36,6 +36,7 @@ self.assertEqual(testfunction.attribute, "test") self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test") + @unittest.skipUnless(threading, 'Threading required for this test.') def test_no_FatalError_infinite_loop(self): p = subprocess.Popen([sys.executable, "-c", 'import _testcapi;' Modified: python/branches/py3k-cdecimal/Lib/test/test_codecs.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_codecs.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_codecs.py Mon Jun 14 11:30:15 2010 @@ -72,7 +72,6 @@ # check that there's nothing left in the buffers self.assertEqual(r.read(), "") self.assertEqual(r.bytebuffer, b"") - self.assertEqual(r.charbuffer, "") # do the check again, this time using a incremental decoder d = codecs.getincrementaldecoder(self.encoding)() @@ -354,6 +353,16 @@ self.check_state_handling_decode(self.encoding, "spamspam", self.spambe) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded_le = b'\xff\xfe\x00\x00' + b'\x00\x00\x01\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_decode(encoded_le)[0]) + encoded_be = b'\x00\x00\xfe\xff' + b'\x00\x01\x00\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_decode(encoded_be)[0]) + class UTF32LETest(ReadTest): encoding = "utf-32-le" @@ -387,6 +396,13 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_le_decode, b"\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = b'\x00\x00\x01\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_le_decode(encoded)[0]) + class UTF32BETest(ReadTest): encoding = "utf-32-be" @@ -420,6 +436,14 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_be_decode, b"\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = b'\x00\x01\x00\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_be_decode(encoded)[0]) + + class UTF16Test(ReadTest): encoding = "utf-16" @@ -628,18 +652,6 @@ self.assertRaises(TypeError, codecs.readbuffer_encode) self.assertRaises(TypeError, codecs.readbuffer_encode, 42) -class CharBufferTest(unittest.TestCase): - - def test_string(self): - self.assertEqual(codecs.charbuffer_encode(b"spam"), (b"spam", 4)) - - def test_empty(self): - self.assertEqual(codecs.charbuffer_encode(b""), (b"", 0)) - - def test_bad_args(self): - self.assertRaises(TypeError, codecs.charbuffer_encode) - self.assertRaises(TypeError, codecs.charbuffer_encode, 42) - class UTF8SigTest(ReadTest): encoding = "utf-8-sig" @@ -1663,7 +1675,6 @@ UTF7Test, UTF16ExTest, ReadBufferTest, - CharBufferTest, RecodingTest, PunycodeTest, UnicodeInternalTest, Modified: python/branches/py3k-cdecimal/Lib/test/test_curses.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_curses.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_curses.py Mon Jun 14 11:30:15 2010 @@ -23,11 +23,6 @@ curses = import_module('curses') curses.panel = import_module('curses.panel') -# skip all these tests on FreeBSD: test_curses currently hangs the -# FreeBSD buildbots, preventing other tests from running. See issue -# #7384. -if 'freebsd' in sys.platform: - raise unittest.SkipTest('The curses module is broken on FreeBSD. See http://bugs.python.org/issue7384.') # XXX: if newterm was supported we could use it instead of initscr and not exit term = os.environ.get('TERM') Modified: python/branches/py3k-cdecimal/Lib/test/test_doctest.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_doctest.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_doctest.py Mon Jun 14 11:30:15 2010 @@ -864,6 +864,77 @@ >>> doctest.DocTestRunner(verbose=False).run(test) TestResults(failed=0, attempted=1) +IGNORE_EXCEPTION_DETAIL also ignores difference in exception formatting +between Python versions. For example, in Python 2.x, the module path of +the exception is not in the output, but this will fail under Python 3: + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') + ... Traceback (most recent call last): + ... HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 4, in f + Failed example: + raise HTTPException('message') + Expected: + Traceback (most recent call last): + HTTPException: message + Got: + Traceback (most recent call last): + ... + http.client.HTTPException: message + TestResults(failed=1, attempted=2) + +But in Python 3 the module path is included, and therefore a test must look +like the following test to succeed in Python 3. But that test will fail under +Python 2. + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') + ... Traceback (most recent call last): + ... http.client.HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + +However, with IGNORE_EXCEPTION_DETAIL, the module name of the exception +(or its unexpected absence) will be ignored: + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + +The module path will be completely ignored, so two different module paths will +still pass if IGNORE_EXCEPTION_DETAIL is given. This is intentional, so it can +be used when exceptions have changed module. + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... foo.bar.HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type: >>> def f(x): Modified: python/branches/py3k-cdecimal/Lib/test/test_fractions.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_fractions.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_fractions.py Mon Jun 14 11:30:15 2010 @@ -395,12 +395,11 @@ self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10)) def testMixingWithDecimal(self): - # Decimal refuses mixed comparisons. + # Decimal refuses mixed arithmetic (but not mixed comparisons) self.assertRaisesMessage( TypeError, "unsupported operand type(s) for +: 'Fraction' and 'Decimal'", operator.add, F(3,11), Decimal('3.1415926')) - self.assertNotEquals(F(5, 2), Decimal('2.5')) def testComparisons(self): self.assertTrue(F(1, 2) < F(2, 3)) Modified: python/branches/py3k-cdecimal/Lib/test/test_getargs2.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_getargs2.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_getargs2.py Mon Jun 14 11:30:15 2010 @@ -1,7 +1,6 @@ import unittest from test import support from _testcapi import getargs_keywords -import warnings """ > How about the following counterproposal. This also changes some of @@ -190,21 +189,7 @@ from _testcapi import getargs_L # L returns 'long long', and does range checking (LLONG_MIN # ... LLONG_MAX) - with warnings.catch_warnings(): - warnings.filterwarnings( - "ignore", - category=DeprecationWarning, - message=".*integer argument expected, got float", - module=__name__) - self.assertEqual(3, getargs_L(3.14)) - with warnings.catch_warnings(): - warnings.filterwarnings( - "error", - category=DeprecationWarning, - message=".*integer argument expected, got float", - module="unittest") - self.assertRaises(DeprecationWarning, getargs_L, 3.14) - + self.assertRaises(TypeError, getargs_L, 3.14) self.assertRaises(TypeError, getargs_L, "Hello") self.assertEqual(99, getargs_L(Int())) @@ -308,8 +293,136 @@ else: self.fail('TypeError should have been raised') +class Bytes_TestCase(unittest.TestCase): + def test_s(self): + from _testcapi import getargs_s + self.assertEqual(getargs_s('abc\xe9'), b'abc\xc3\xa9') + self.assertRaises(TypeError, getargs_s, 'nul:\0') + self.assertRaises(TypeError, getargs_s, b'bytes') + self.assertRaises(TypeError, getargs_s, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_s, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_s, None) + + def test_s_star(self): + from _testcapi import getargs_s_star + self.assertEqual(getargs_s_star('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_s_star('nul:\0'), b'nul:\0') + self.assertEqual(getargs_s_star(b'bytes'), b'bytes') + self.assertEqual(getargs_s_star(bytearray(b'bytearray')), b'bytearray') + self.assertEqual(getargs_s_star(memoryview(b'memoryview')), b'memoryview') + self.assertRaises(TypeError, getargs_s_star, None) + + def test_s_hash(self): + from _testcapi import getargs_s_hash + self.assertEqual(getargs_s_hash('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_s_hash('nul:\0'), b'nul:\0') + self.assertEqual(getargs_s_hash(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_s_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_s_hash, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_s_hash, None) + + def test_z(self): + from _testcapi import getargs_z + self.assertEqual(getargs_z('abc\xe9'), b'abc\xc3\xa9') + self.assertRaises(TypeError, getargs_z, 'nul:\0') + self.assertEqual(getargs_z(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_z, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_z, memoryview(b'memoryview')) + self.assertIsNone(getargs_z(None)) + + def test_z_star(self): + from _testcapi import getargs_z_star + self.assertEqual(getargs_z_star('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_z_star('nul:\0'), b'nul:\0') + self.assertEqual(getargs_z_star(b'bytes'), b'bytes') + self.assertEqual(getargs_z_star(bytearray(b'bytearray')), b'bytearray') + self.assertEqual(getargs_z_star(memoryview(b'memoryview')), b'memoryview') + self.assertIsNone(getargs_z_star(None)) + + def test_z_hash(self): + from _testcapi import getargs_z_hash + self.assertEqual(getargs_z_hash('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_z_hash('nul:\0'), b'nul:\0') + self.assertEqual(getargs_z_hash(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_z_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_z_hash, memoryview(b'memoryview')) + self.assertIsNone(getargs_z_hash(None)) + + def test_y(self): + from _testcapi import getargs_y + self.assertRaises(TypeError, getargs_y, 'abc\xe9') + self.assertEqual(getargs_y(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_y, b'nul:\0') + self.assertRaises(TypeError, getargs_y, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_y, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_y, None) + + def test_y_star(self): + from _testcapi import getargs_y_star + self.assertRaises(TypeError, getargs_y_star, 'abc\xe9') + self.assertEqual(getargs_y_star(b'bytes'), b'bytes') + self.assertEqual(getargs_y_star(b'nul:\0'), b'nul:\0') + self.assertEqual(getargs_y_star(bytearray(b'bytearray')), b'bytearray') + self.assertEqual(getargs_y_star(memoryview(b'memoryview')), b'memoryview') + self.assertRaises(TypeError, getargs_y_star, None) + + def test_y_hash(self): + from _testcapi import getargs_y_hash + self.assertRaises(TypeError, getargs_y_hash, 'abc\xe9') + self.assertEqual(getargs_y_hash(b'bytes'), b'bytes') + self.assertEqual(getargs_y_hash(b'nul:\0'), b'nul:\0') + self.assertRaises(TypeError, getargs_y_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_y_hash, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_y_hash, None) + + +class Unicode_TestCase(unittest.TestCase): + def test_u(self): + from _testcapi import getargs_u + self.assertEqual(getargs_u('abc\xe9'), 'abc\xe9') + self.assertRaises(TypeError, getargs_u, 'nul:\0') + self.assertRaises(TypeError, getargs_u, b'bytes') + self.assertRaises(TypeError, getargs_u, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_u, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_u, None) + + def test_u_hash(self): + from _testcapi import getargs_u_hash + self.assertEqual(getargs_u_hash('abc\xe9'), 'abc\xe9') + self.assertEqual(getargs_u_hash('nul:\0'), 'nul:\0') + self.assertRaises(TypeError, getargs_u_hash, b'bytes') + self.assertRaises(TypeError, getargs_u_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_u_hash, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_u_hash, None) + + def test_Z(self): + from _testcapi import getargs_Z + self.assertEqual(getargs_Z('abc\xe9'), 'abc\xe9') + self.assertRaises(TypeError, getargs_Z, 'nul:\0') + self.assertRaises(TypeError, getargs_Z, b'bytes') + self.assertRaises(TypeError, getargs_Z, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_Z, memoryview(b'memoryview')) + self.assertIsNone(getargs_Z(None)) + + def test_Z_hash(self): + from _testcapi import getargs_Z_hash + self.assertEqual(getargs_Z_hash('abc\xe9'), 'abc\xe9') + self.assertEqual(getargs_Z_hash('nul:\0'), 'nul:\0') + self.assertRaises(TypeError, getargs_Z_hash, b'bytes') + self.assertRaises(TypeError, getargs_Z_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_Z_hash, memoryview(b'memoryview')) + self.assertIsNone(getargs_Z_hash(None)) + + def test_main(): - tests = [Signed_TestCase, Unsigned_TestCase, Tuple_TestCase, Keywords_TestCase] + tests = [ + Signed_TestCase, + Unsigned_TestCase, + Tuple_TestCase, + Keywords_TestCase, + Bytes_TestCase, + Unicode_TestCase, + ] try: from _testcapi import getargs_L, getargs_K except ImportError: Modified: python/branches/py3k-cdecimal/Lib/test/test_math.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_math.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_math.py Mon Jun 14 11:30:15 2010 @@ -1042,6 +1042,15 @@ accuracy_failure = acc_check(expected, got, rel_err = 5e-15, abs_err = 5e-15) + elif fn == 'erfc': + # erfc has less-than-ideal accuracy for large + # arguments (x ~ 25 or so), mainly due to the + # error involved in computing exp(-x*x). + # + # XXX Would be better to weaken this test only + # for large x, instead of for all x. + accuracy_failure = ulps_check(expected, got, 2000) + else: accuracy_failure = ulps_check(expected, got, 20) if accuracy_failure is None: Modified: python/branches/py3k-cdecimal/Lib/test/test_minidom.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_minidom.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_minidom.py Mon Jun 14 11:30:15 2010 @@ -228,7 +228,14 @@ def testUnlink(self): dom = parse(tstfile) + self.assertTrue(dom.childNodes) dom.unlink() + self.assertFalse(dom.childNodes) + + def testContext(self): + with parse(tstfile) as dom: + self.assertTrue(dom.childNodes) + self.assertFalse(dom.childNodes) def testElement(self): dom = Document() Modified: python/branches/py3k-cdecimal/Lib/test/test_numeric_tower.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_numeric_tower.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_numeric_tower.py Mon Jun 14 11:30:15 2010 @@ -143,9 +143,64 @@ x = {'halibut', HalibutProxy()} self.assertEqual(len(x), 1) +class ComparisonTest(unittest.TestCase): + def test_mixed_comparisons(self): + + # ordered list of distinct test values of various types: + # int, float, Fraction, Decimal + test_values = [ + float('-inf'), + D('-1e999999999'), + -1e308, + F(-22, 7), + -3.14, + -2, + 0.0, + 1e-320, + True, + F('1.2'), + D('1.3'), + float('1.4'), + F(275807, 195025), + D('1.414213562373095048801688724'), + F(114243, 80782), + F(473596569, 84615), + 7e200, + D('infinity'), + ] + for i, first in enumerate(test_values): + for second in test_values[i+1:]: + self.assertLess(first, second) + self.assertLessEqual(first, second) + self.assertGreater(second, first) + self.assertGreaterEqual(second, first) + + def test_complex(self): + # comparisons with complex are special: equality and inequality + # comparisons should always succeed, but order comparisons should + # raise TypeError. + z = 1.0 + 0j + w = -3.14 + 2.7j + + for v in 1, 1.0, F(1), D(1), complex(1): + self.assertEqual(z, v) + self.assertEqual(v, z) + + for v in 2, 2.0, F(2), D(2), complex(2): + self.assertNotEqual(z, v) + self.assertNotEqual(v, z) + self.assertNotEqual(w, v) + self.assertNotEqual(v, w) + + for v in (1, 1.0, F(1), D(1), complex(1), + 2, 2.0, F(2), D(2), complex(2), w): + for op in operator.le, operator.lt, operator.ge, operator.gt: + self.assertRaises(TypeError, op, z, v) + self.assertRaises(TypeError, op, v, z) + def test_main(): - run_unittest(HashTest) + run_unittest(HashTest, ComparisonTest) if __name__ == '__main__': test_main() Modified: python/branches/py3k-cdecimal/Lib/test/test_ssl.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_ssl.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_ssl.py Mon Jun 14 11:30:15 2010 @@ -33,16 +33,15 @@ HOST = support.HOST data_file = lambda name: os.path.join(os.path.dirname(__file__), name) -fsencode = lambda name: name.encode(sys.getfilesystemencoding(), "surrogateescape") CERTFILE = data_file("keycert.pem") -BYTES_CERTFILE = fsencode(CERTFILE) +BYTES_CERTFILE = os.fsencode(CERTFILE) ONLYCERT = data_file("ssl_cert.pem") ONLYKEY = data_file("ssl_key.pem") -BYTES_ONLYCERT = fsencode(ONLYCERT) -BYTES_ONLYKEY = fsencode(ONLYKEY) +BYTES_ONLYCERT = os.fsencode(ONLYCERT) +BYTES_ONLYKEY = os.fsencode(ONLYKEY) CAPATH = data_file("capath") -BYTES_CAPATH = fsencode(CAPATH) +BYTES_CAPATH = os.fsencode(CAPATH) SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem") Modified: python/branches/py3k-cdecimal/Lib/test/test_struct.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_struct.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_struct.py Mon Jun 14 11:30:15 2010 @@ -443,7 +443,7 @@ # Test bogus offset (issue 3694) sb = small_buf - self.assertRaises(TypeError, struct.pack_into, b'1', sb, None) + self.assertRaises(TypeError, struct.pack_into, b'', sb, None) def test_pack_into_fn(self): test_string = b'Reykjavik rocks, eow!' @@ -506,10 +506,43 @@ for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']: self.assertTrue(struct.unpack('>?', c)[0]) + def test_count_overflow(self): + hugecount = '{}b'.format(sys.maxsize+1) + self.assertRaises(struct.error, struct.calcsize, hugecount) + + hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2) + self.assertRaises(struct.error, struct.calcsize, hugecount2) + if IS32BIT: def test_crasher(self): self.assertRaises(MemoryError, struct.pack, "357913941b", "a") + def test_trailing_counter(self): + store = array.array('b', b' '*100) + + # format lists containing only count spec should result in an error + self.assertRaises(struct.error, struct.pack, '12345') + self.assertRaises(struct.error, struct.unpack, '12345', '') + self.assertRaises(struct.error, struct.pack_into, '12345', store, 0) + self.assertRaises(struct.error, struct.unpack_from, '12345', store, 0) + + # Format lists with trailing count spec should result in an error + self.assertRaises(struct.error, struct.pack, 'c12345', 'x') + self.assertRaises(struct.error, struct.unpack, 'c12345', 'x') + self.assertRaises(struct.error, struct.pack_into, 'c12345', store, 0, + 'x') + self.assertRaises(struct.error, struct.unpack_from, 'c12345', store, + 0) + + # Mixed format tests + self.assertRaises(struct.error, struct.pack, '14s42', 'spam and eggs') + self.assertRaises(struct.error, struct.unpack, '14s42', + 'spam and eggs') + self.assertRaises(struct.error, struct.pack_into, '14s42', store, 0, + 'spam and eggs') + self.assertRaises(struct.error, struct.unpack_from, '14s42', store, 0) + + def test_main(): run_unittest(StructTest) Modified: python/branches/py3k-cdecimal/Lib/test/test_sundry.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_sundry.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_sundry.py Mon Jun 14 11:30:15 2010 @@ -60,7 +60,6 @@ import rlcompleter import sched import sndhdr - import sunau import symbol import tabnanny import timeit Modified: python/branches/py3k-cdecimal/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_sys.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_sys.py Mon Jun 14 11:30:15 2010 @@ -863,6 +863,35 @@ # sys.flags check(sys.flags, size(vh) + self.P * len(sys.flags)) + def test_getfilesystemencoding(self): + import codecs + + def check_fsencoding(fs_encoding): + self.assertIsNotNone(fs_encoding) + if sys.platform == 'darwin': + self.assertEqual(fs_encoding, 'utf-8') + codecs.lookup(fs_encoding) + + fs_encoding = sys.getfilesystemencoding() + check_fsencoding(fs_encoding) + + # Even in C locale + try: + sys.executable.encode('ascii') + except UnicodeEncodeError: + # Python doesn't start with ASCII locale if its path is not ASCII, + # see issue #8611 + pass + else: + env = os.environ.copy() + env['LANG'] = 'C' + output = subprocess.check_output( + [sys.executable, "-c", + "import sys; print(sys.getfilesystemencoding())"], + env=env) + fs_encoding = output.rstrip().decode('ascii') + check_fsencoding(fs_encoding) + def test_setfilesystemencoding(self): old = sys.getfilesystemencoding() try: Modified: python/branches/py3k-cdecimal/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/test/test_unicode.py (original) +++ python/branches/py3k-cdecimal/Lib/test/test_unicode.py Mon Jun 14 11:30:15 2010 @@ -681,6 +681,9 @@ self.assertRaises(IndexError, "{:}".format) self.assertRaises(IndexError, "{:s}".format) self.assertRaises(IndexError, "{}".format) + big = "23098475029384702983476098230754973209482573" + self.assertRaises(ValueError, ("{" + big + "}").format) + self.assertRaises(ValueError, ("{[" + big + "]}").format, [0]) # issue 6089 self.assertRaises(ValueError, "{0[0]x}".format, [None]) Modified: python/branches/py3k-cdecimal/Lib/unittest/case.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/case.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/case.py Mon Jun 14 11:30:15 2010 @@ -172,7 +172,7 @@ longMessage = False - # This attribute sets the maximum length of a diff in failure messsages + # This attribute sets the maximum length of a diff in failure messages # by assert methods using difflib. It is looked up as an instance attribute # so can be configured by individual tests if required. @@ -389,6 +389,9 @@ self.setUp() getattr(self, self._testMethodName)() self.tearDown() + while self._cleanups: + function, args, kwargs = self._cleanups.pop(-1) + function(*args, **kwargs) def skipTest(self, reason): """Skip this test.""" Modified: python/branches/py3k-cdecimal/Lib/unittest/suite.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/suite.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/suite.py Mon Jun 14 11:30:15 2010 @@ -84,9 +84,16 @@ self._handleModuleTearDown(result) return result + def debug(self): + """Run the tests without collecting errors in a TestResult""" + debug = _DebugResult() + self._wrapped_run(debug, True) + self._tearDownPreviousClass(None, debug) + self._handleModuleTearDown(debug) + ################################ # private methods - def _wrapped_run(self, result): + def _wrapped_run(self, result, debug=False): for test in self: if result.shouldStop: break @@ -102,9 +109,11 @@ continue if hasattr(test, '_wrapped_run'): - test._wrapped_run(result) - else: + test._wrapped_run(result, debug) + elif not debug: test(result) + else: + test.debug() def _handleClassSetUp(self, test, result): previousClass = getattr(result, '_previousTestClass', None) @@ -128,6 +137,8 @@ try: setUpClass() except Exception as e: + if isinstance(result, _DebugResult): + raise currentClass._classSetupFailed = True className = util.strclass(currentClass) errorName = 'setUpClass (%s)' % className @@ -160,6 +171,8 @@ try: setUpModule() except Exception as e: + if isinstance(result, _DebugResult): + raise result._moduleSetUpFailed = True errorName = 'setUpModule (%s)' % currentModule self._addClassOrModuleLevelException(result, e, errorName) @@ -189,6 +202,8 @@ try: tearDownModule() except Exception as e: + if isinstance(result, _DebugResult): + raise errorName = 'tearDownModule (%s)' % previousModule self._addClassOrModuleLevelException(result, e, errorName) @@ -209,6 +224,8 @@ try: tearDownClass() except Exception as e: + if isinstance(result, _DebugResult): + raise className = util.strclass(previousClass) errorName = 'tearDownClass (%s)' % className self._addClassOrModuleLevelException(result, e, errorName) @@ -260,3 +277,10 @@ except TypeError: return True return False + + +class _DebugResult(object): + "Used by the TestSuite to hold previous class when running in debug." + _previousTestClass = None + _moduleSetUpFailed = False + shouldStop = False Modified: python/branches/py3k-cdecimal/Lib/unittest/test/test_runner.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/test/test_runner.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/test/test_runner.py Mon Jun 14 11:30:15 2010 @@ -110,6 +110,31 @@ test.run(result) self.assertEqual(ordering, ['setUp', 'cleanup1']) + def testTestCaseDebugExecutesCleanups(self): + ordering = [] + + class TestableTest(unittest.TestCase): + def setUp(self): + ordering.append('setUp') + self.addCleanup(cleanup1) + + def testNothing(self): + ordering.append('test') + + def tearDown(self): + ordering.append('tearDown') + + test = TestableTest('testNothing') + + def cleanup1(): + ordering.append('cleanup1') + test.addCleanup(cleanup2) + def cleanup2(): + ordering.append('cleanup2') + + test.debug() + self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2']) + class Test_TextTestRunner(unittest.TestCase): """Tests for TextTestRunner.""" Modified: python/branches/py3k-cdecimal/Lib/unittest/test/test_setups.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/unittest/test/test_setups.py (original) +++ python/branches/py3k-cdecimal/Lib/unittest/test/test_setups.py Mon Jun 14 11:30:15 2010 @@ -438,6 +438,70 @@ skipped = result.skipped[0][0] self.assertEqual(str(skipped), 'setUpModule (Module)') + def test_suite_debug_executes_setups_and_teardowns(self): + ordering = [] + + class Module(object): + @staticmethod + def setUpModule(): + ordering.append('setUpModule') + @staticmethod + def tearDownModule(): + ordering.append('tearDownModule') + + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + @classmethod + def tearDownClass(cls): + ordering.append('tearDownClass') + def test_something(self): + ordering.append('test_something') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + suite.debug() + expectedOrder = ['setUpModule', 'setUpClass', 'test_something', 'tearDownClass', 'tearDownModule'] + self.assertEqual(ordering, expectedOrder) + + def test_suite_debug_propagates_exceptions(self): + class Module(object): + @staticmethod + def setUpModule(): + if phase == 0: + raise Exception('setUpModule') + @staticmethod + def tearDownModule(): + if phase == 1: + raise Exception('tearDownModule') + + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + if phase == 2: + raise Exception('setUpClass') + @classmethod + def tearDownClass(cls): + if phase == 3: + raise Exception('tearDownClass') + def test_something(self): + if phase == 4: + raise Exception('test_something') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + _suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + suite = unittest.TestSuite() + suite.addTest(_suite) + + messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something') + for phase, msg in enumerate(messages): + with self.assertRaisesRegexp(Exception, msg): + suite.debug() if __name__ == '__main__': unittest.main() Modified: python/branches/py3k-cdecimal/Lib/xml/dom/minidom.py ============================================================================== --- python/branches/py3k-cdecimal/Lib/xml/dom/minidom.py (original) +++ python/branches/py3k-cdecimal/Lib/xml/dom/minidom.py Mon Jun 14 11:30:15 2010 @@ -268,6 +268,14 @@ self.previousSibling = None self.nextSibling = None + # A Node is its own context manager, to ensure that an unlink() call occurs. + # This is similar to how a file object works. + def __enter__(self): + return self + + def __exit__(self, et, ev, tb): + self.unlink() + defproperty(Node, "firstChild", doc="First child node, or None.") defproperty(Node, "lastChild", doc="Last child node, or None.") defproperty(Node, "localName", doc="Namespace-local name of this node.") Modified: python/branches/py3k-cdecimal/Misc/ACKS ============================================================================== --- python/branches/py3k-cdecimal/Misc/ACKS (original) +++ python/branches/py3k-cdecimal/Misc/ACKS Mon Jun 14 11:30:15 2010 @@ -25,6 +25,7 @@ Erik Anders?n Oliver Andrich Ross Andrus +?ric Araujo Jason Asbahr David Ascher Chris AtLee @@ -153,6 +154,7 @@ Jeffery Collins Robert Collins Paul Colomiets +Geremy Condra Juan Jos? Conti Matt Conway David M. Cooke @@ -188,6 +190,7 @@ Erik Demaine Roger Dev Raghuram Devarakonda +Caleb Deveraux Toby Dickenson Mark Dickinson Jack Diederich @@ -389,6 +392,7 @@ Fredrik Johansson Gregory K. Johnson Simon Johnston +Thomas Jollans Evan Jones Jeremy Jones Richard Jones @@ -517,6 +521,7 @@ Lambert Meertens Bill van Melle Lucas Prado Melo +Ezio Melotti Brian Merrell Luke Mewburn Mike Meyer @@ -637,6 +642,7 @@ John Redford Terry Reedy Steve Reeves +Lennart Regebro Ofir Reichenberg Sean Reifschneider Michael P. Reilly Modified: python/branches/py3k-cdecimal/Misc/NEWS ============================================================================== --- python/branches/py3k-cdecimal/Misc/NEWS (original) +++ python/branches/py3k-cdecimal/Misc/NEWS Mon Jun 14 11:30:15 2010 @@ -12,9 +12,43 @@ Core and Builtins ----------------- +- Issue #8592: PyArg_Parse*() functions raise a TypeError for "y", "u" and "Z" + formats if the string contains a null byte/character. Write unit tests for + string formats. + +- Issue #7490: to facilitate sharing of doctests between 2.x and 3.x test + suites, the IGNORE_EXCEPTION_DETAIL directive now also ignores the module + location of the raised exception. + +- Issue #8969: On Windows, use mbcs codec in strict mode to encode and decode + filenames and enable os.fsencode(). + +- Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash + the interpreter with characters outside the Basic Multilingual Plane + (higher than 0x10000). + +- Issue #8950: (See also issue #5080). Py_ArgParse*() functions now + raise TypeError instead of giving a DeprecationWarning when a float + is parsed using the 'L' code (for long long). (All other integer + codes already raise TypeError in this case.) + +- Issue #8922: Normalize the encoding name in PyUnicode_AsEncodedString() to + enable shortcuts for upper case encoding name. Add also a shortcut for + "iso-8859-1" in PyUnicode_AsEncodedString() and PyUnicode_Decode(). + +- Issue #8838: Remove codecs.charbuffer_encode() function. The buffer protocol + doesn't support "char buffer" anymore in Python3. + +- Issue #8339: Remove "t#" format of PyArg_Parse*() functions, use "s#" or "s*" + instead. codecs.charbuffer_encode() now accepts modifiable buffer objects + like bytearray. + - Issue #8837: Remove "O?" format of PyArg_Parse*() functions. The format is no used anymore and it was never documented. +- In the str.format(), raise a ValueError when indexes to arguments are too + large. + - Issue #2844: Make int('42', n) consistently raise ValueError for invalid integers n (including n = -909). @@ -398,6 +432,24 @@ Library ------- +- Issue #8986: math.erfc was incorrectly raising OverflowError for + values between -27.3 and -30.0 on some platforms. + +- Issue #8784: Set tarfile default encoding to 'utf-8' on Windows. + +- Issue #8966: If a ctypes structure field is an array of c_char, convert its + value to bytes instead of str (as done for c_char and c_char_p). + +- Issue #8188: Comparisons between Decimal and Fraction objects are + now permitted, returning a result based on the exact numerical + values of the operands. This builds on issue #2531, which allowed + Decimal-to-float comparisons; all comparisons involving numeric + types (bool, int, float, complex, Decimal, Fraction) should now + act as expected. + +- Issue #8897: Fix sunau module, use bytes to write the header. Patch written + by Thomas Jollans. + - Issue #8899: time.struct_time now has class and atribute docstrings. - Issue #6470: Drop UNC prefix in FixTk. @@ -692,7 +744,8 @@ - Issue #2531: Comparison operations between floats and Decimal instances now return a result based on the numeric values of the operands; previously they returned an arbitrary result based on - the relative ordering of id(float) and id(Decimal). + the relative ordering of id(float) and id(Decimal). See also + issue #8188, which adds Decimal-to-Fraction comparisons. - Added a subtract() method to collections.Counter(). @@ -1253,6 +1306,17 @@ Extension Modules ----------------- +- Issue #8973: Add __all__ to struct module; this ensures that + help(struct) includes documentation for the struct.Struct class. + +- Issue #3129: Trailing digits in struct format string are no longer ignored. + For example, "1" or "ilib123" are now invalid formats and cause + ``struct.error`` to be raised. Patch by Caleb Deveraux. + +- Issue #7384: If the system readline library is linked against ncurses, + the curses module must be linked against ncurses as well. Otherwise it + is not safe to load both the readline and curses modules in an application. + - Issue #2810: Fix cases where the Windows registry API returns ERROR_MORE_DATA, requiring a re-try in order to get the complete result. Modified: python/branches/py3k-cdecimal/Misc/maintainers.rst ============================================================================== --- python/branches/py3k-cdecimal/Misc/maintainers.rst (original) +++ python/branches/py3k-cdecimal/Misc/maintainers.rst Mon Jun 14 11:30:15 2010 @@ -80,7 +80,7 @@ csv ctypes theller curses andrew.kuchling -datetime +datetime alexander.belopolsky dbm decimal facundobatista, rhettinger, mark.dickinson difflib tim_one @@ -207,7 +207,7 @@ test textwrap threading -time +time alexander.belopolsky timeit tkinter gpolo token georg.brandl Modified: python/branches/py3k-cdecimal/Modules/_codecsmodule.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/_codecsmodule.c (original) +++ python/branches/py3k-cdecimal/Modules/_codecsmodule.c Mon Jun 14 11:30:15 2010 @@ -162,62 +162,62 @@ escape_encode(PyObject *self, PyObject *args) { - static const char *hexdigits = "0123456789abcdef"; - PyObject *str; - Py_ssize_t size; - Py_ssize_t newsize; - const char *errors = NULL; - PyObject *v; - - if (!PyArg_ParseTuple(args, "O!|z:escape_encode", - &PyBytes_Type, &str, &errors)) - return NULL; - - size = PyBytes_GET_SIZE(str); - newsize = 4*size; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { - PyErr_SetString(PyExc_OverflowError, - "string is too large to encode"); - return NULL; - } - v = PyBytes_FromStringAndSize(NULL, newsize); + static const char *hexdigits = "0123456789abcdef"; + PyObject *str; + Py_ssize_t size; + Py_ssize_t newsize; + const char *errors = NULL; + PyObject *v; + + if (!PyArg_ParseTuple(args, "O!|z:escape_encode", + &PyBytes_Type, &str, &errors)) + return NULL; + + size = PyBytes_GET_SIZE(str); + newsize = 4*size; + if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { + PyErr_SetString(PyExc_OverflowError, + "string is too large to encode"); + return NULL; + } + v = PyBytes_FromStringAndSize(NULL, newsize); - if (v == NULL) { - return NULL; + if (v == NULL) { + return NULL; + } + else { + register Py_ssize_t i; + register char c; + register char *p = PyBytes_AS_STRING(v); + + for (i = 0; i < size; i++) { + /* There's at least enough room for a hex escape */ + assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); + c = PyBytes_AS_STRING(str)[i]; + if (c == '\'' || c == '\\') + *p++ = '\\', *p++ = c; + else if (c == '\t') + *p++ = '\\', *p++ = 't'; + else if (c == '\n') + *p++ = '\\', *p++ = 'n'; + else if (c == '\r') + *p++ = '\\', *p++ = 'r'; + else if (c < ' ' || c >= 0x7f) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = hexdigits[(c & 0xf0) >> 4]; + *p++ = hexdigits[c & 0xf]; + } + else + *p++ = c; } - else { - register Py_ssize_t i; - register char c; - register char *p = PyBytes_AS_STRING(v); - - for (i = 0; i < size; i++) { - /* There's at least enough room for a hex escape */ - assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); - c = PyBytes_AS_STRING(str)[i]; - if (c == '\'' || c == '\\') - *p++ = '\\', *p++ = c; - else if (c == '\t') - *p++ = '\\', *p++ = 't'; - else if (c == '\n') - *p++ = '\\', *p++ = 'n'; - else if (c == '\r') - *p++ = '\\', *p++ = 'r'; - else if (c < ' ' || c >= 0x7f) { - *p++ = '\\'; - *p++ = 'x'; - *p++ = hexdigits[(c & 0xf0) >> 4]; - *p++ = hexdigits[c & 0xf]; - } - else - *p++ = c; - } - *p = '\0'; - if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { - return NULL; - } + *p = '\0'; + if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { + return NULL; } + } - return codec_tuple(v, size); + return codec_tuple(v, size); } /* --- Decoder ------------------------------------------------------------ */ @@ -252,7 +252,7 @@ utf_7_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -265,7 +265,7 @@ decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -275,7 +275,7 @@ utf_8_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -288,7 +288,7 @@ decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -298,7 +298,7 @@ utf_16_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -311,7 +311,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -321,7 +321,7 @@ utf_16_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -335,7 +335,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -345,7 +345,7 @@ utf_16_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -359,7 +359,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -377,7 +377,7 @@ utf_16_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -390,7 +390,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -402,7 +402,7 @@ utf_32_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -415,7 +415,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -425,7 +425,7 @@ utf_32_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -438,7 +438,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -448,7 +448,7 @@ utf_32_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -461,7 +461,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -479,7 +479,7 @@ utf_32_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -492,7 +492,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -504,7 +504,7 @@ unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; PyObject *unicode; @@ -512,68 +512,68 @@ &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * raw_unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; - PyObject *unicode; + PyObject *unicode; if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * latin_1_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:latin_1_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * ascii_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:ascii_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * charmap_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; PyObject *mapping = NULL; @@ -583,9 +583,9 @@ if (mapping == Py_None) mapping = NULL; - unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) @@ -594,7 +594,7 @@ mbcs_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -607,7 +607,7 @@ decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -639,21 +639,6 @@ } static PyObject * -charbuffer_encode(PyObject *self, - PyObject *args) -{ - const char *data; - Py_ssize_t size; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "t#|z:charbuffer_encode", - &data, &size, &errors)) - return NULL; - - return codec_tuple(PyBytes_FromStringAndSize(data, size), size); -} - -static PyObject * unicode_internal_encode(PyObject *self, PyObject *args) { @@ -1116,7 +1101,6 @@ {"charmap_decode", charmap_decode, METH_VARARGS}, {"charmap_build", charmap_build, METH_VARARGS}, {"readbuffer_encode", readbuffer_encode, METH_VARARGS}, - {"charbuffer_encode", charbuffer_encode, METH_VARARGS}, #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) {"mbcs_encode", mbcs_encode, METH_VARARGS}, {"mbcs_decode", mbcs_decode, METH_VARARGS}, Modified: python/branches/py3k-cdecimal/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-cdecimal/Modules/_ctypes/_ctypes.c Mon Jun 14 11:30:15 2010 @@ -4467,7 +4467,7 @@ #endif result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type, - "U(O){s:n,s:O}", + "s(O){s:n,s:O}", name, &PyCArray_Type, "_length_", Modified: python/branches/py3k-cdecimal/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k-cdecimal/Modules/_ctypes/cfield.c Mon Jun 14 11:30:15 2010 @@ -1333,7 +1333,7 @@ break; } - return PyUnicode_FromStringAndSize((char *)ptr, (Py_ssize_t)i); + return PyBytes_FromStringAndSize((char *)ptr, (Py_ssize_t)i); } static PyObject * Modified: python/branches/py3k-cdecimal/Modules/_localemodule.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/_localemodule.c (original) +++ python/branches/py3k-cdecimal/Modules/_localemodule.c Mon Jun 14 11:30:15 2010 @@ -572,19 +572,31 @@ static PyObject* PyIntl_bindtextdomain(PyObject* self,PyObject*args) { - char *domain, *dirname; - if (!PyArg_ParseTuple(args, "sz", &domain, &dirname)) + char *domain, *dirname, *current_dirname; + PyObject *dirname_obj, *dirname_bytes = NULL, *result; + if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj)) return 0; if (!strlen(domain)) { PyErr_SetString(Error, "domain must be a non-empty string"); return 0; } - dirname = bindtextdomain(domain, dirname); - if (!dirname) { + if (dirname_obj != Py_None) { + if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes)) + return NULL; + dirname = PyBytes_AsString(dirname_bytes); + } else { + dirname_bytes = NULL; + dirname = NULL; + } + current_dirname = bindtextdomain(domain, dirname); + if (current_dirname == NULL) { + Py_XDECREF(dirname_bytes); PyErr_SetFromErrno(PyExc_OSError); return NULL; } - return str2uni(dirname); + result = str2uni(current_dirname); + Py_XDECREF(dirname_bytes); + return result; } #ifdef HAVE_BIND_TEXTDOMAIN_CODESET Modified: python/branches/py3k-cdecimal/Modules/_struct.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/_struct.c (original) +++ python/branches/py3k-cdecimal/Modules/_struct.c Mon Jun 14 11:30:15 2010 @@ -1143,16 +1143,19 @@ } -/* Align a size according to a format code */ +/* Align a size according to a format code. Return -1 on overflow. */ -static int +static Py_ssize_t align(Py_ssize_t size, char c, const formatdef *e) { + Py_ssize_t extra; + if (e->format == c) { - if (e->alignment) { - size = ((size + e->alignment - 1) - / e->alignment) - * e->alignment; + if (e->alignment && size > 0) { + extra = (e->alignment - 1) - (size - 1) % (e->alignment); + if (extra > PY_SSIZE_T_MAX - size) + return -1; + size += extra; } } return size; @@ -1171,7 +1174,7 @@ const char *s; const char *fmt; char c; - Py_ssize_t size, len, num, itemsize, x; + Py_ssize_t size, len, num, itemsize; fmt = PyBytes_AS_STRING(self->s_format); @@ -1186,17 +1189,19 @@ if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { - x = num*10 + (c - '0'); - if (x/10 != num) { - PyErr_SetString( - StructError, - "overflow in item count"); - return -1; - } - num = x; + /* overflow-safe version of + if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ + if (num >= PY_SSIZE_T_MAX / 10 && ( + num > PY_SSIZE_T_MAX / 10 || + (c - '0') > PY_SSIZE_T_MAX % 10)) + goto overflow; + num = num*10 + (c - '0'); + } + if (c == '\0') { + PyErr_SetString(StructError, + "repeat count given without format specifier"); + return -1; } - if (c == '\0') - break; } else num = 1; @@ -1214,13 +1219,13 @@ itemsize = e->size; size = align(size, c, e); - x = num * itemsize; - size += x; - if (x/itemsize != num || size < 0) { - PyErr_SetString(StructError, - "total struct size too long"); - return -1; - } + if (size == -1) + goto overflow; + + /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ + if (num > (PY_SSIZE_T_MAX - size) / itemsize) + goto overflow; + size += num * itemsize; } /* check for overflow */ @@ -1279,6 +1284,11 @@ codes->size = 0; return 0; + + overflow: + PyErr_SetString(StructError, + "total struct size too long"); + return -1; } static PyObject * @@ -1388,9 +1398,9 @@ PyDoc_STRVAR(s_unpack__doc__, "S.unpack(buffer) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\ -strings."); +Return a tuple containing values unpacked according to the format\n\ +string S.format. Requires len(buffer) == S.size. See help(struct)\n\ +for more on format strings."); static PyObject * s_unpack(PyObject *self, PyObject *input) @@ -1416,12 +1426,11 @@ } PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\ +"S.unpack_from(buffer, offset=0) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Unlike unpack, unpack_from can unpack values from any object supporting\n\ -the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\ -See struct.__doc__ for more on format strings."); +Return a tuple containing values unpacked according to the format\n\ +string S.format. Requires len(buffer[offset:]) >= S.size. See\n\ +help(struct) for more on format strings."); static PyObject * s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds) @@ -1556,8 +1565,9 @@ PyDoc_STRVAR(s_pack__doc__, "S.pack(v1, v2, ...) -> bytes\n\ \n\ -Return a bytes containing values v1, v2, ... packed according to this\n\ -Struct's format. See struct.__doc__ for more on format strings."); +Return a bytes object containing values v1, v2, ... packed according\n\ +to the format string S.format. See help(struct) for more on format\n\ +strings."); static PyObject * s_pack(PyObject *self, PyObject *args) @@ -1593,10 +1603,10 @@ PyDoc_STRVAR(s_pack_into__doc__, "S.pack_into(buffer, offset, v1, v2, ...)\n\ \n\ -Pack the values v1, v2, ... according to this Struct's format, write \n\ -the packed bytes into the writable buffer buf starting at offset. Note\n\ -that the offset is not an optional argument. See struct.__doc__ for \n\ -more on format strings."); +Pack the values v1, v2, ... according to the format string S.format\n\ +and write the packed bytes into the writable buffer buf starting at\n\ +offset. Note that the offset is a required argument. See\n\ +help(struct) for more on format strings."); static PyObject * s_pack_into(PyObject *self, PyObject *args) @@ -1673,7 +1683,11 @@ {NULL, NULL} /* sentinel */ }; -PyDoc_STRVAR(s__doc__, "Compiled struct object"); +PyDoc_STRVAR(s__doc__, +"Struct(fmt) --> compiled struct object\n" +"\n" +"Return a new Struct object which writes and reads binary data according to\n" +"the format string fmt. See help(struct) for more on format strings."); #define OFF(x) offsetof(PyStructObject, x) @@ -1771,7 +1785,9 @@ } PyDoc_STRVAR(calcsize_doc, -"Return size of C struct described by format string fmt."); +"calcsize(fmt) -> integer\n\ +\n\ +Return size in bytes of the struct described by the format string fmt."); static PyObject * calcsize(PyObject *self, PyObject *fmt) @@ -1786,7 +1802,10 @@ } PyDoc_STRVAR(pack_doc, -"Return bytes containing values v1, v2, ... packed according to fmt."); +"pack(fmt, v1, v2, ...) -> bytes\n\ +\n\ +Return a bytes object containing the values v1, v2, ... packed according\n\ +to the format string fmt. See help(struct) for more on format strings."); static PyObject * pack(PyObject *self, PyObject *args) @@ -1815,8 +1834,12 @@ } PyDoc_STRVAR(pack_into_doc, -"Pack the values v1, v2, ... according to fmt.\n\ -Write the packed bytes into the writable buffer buf starting at offset."); +"pack_into(fmt, buffer, offset, v1, v2, ...)\n\ +\n\ +Pack the values v1, v2, ... according to the format string fmt and write\n\ +the packed bytes into the writable buffer buf starting at offset. Note\n\ +that the offset is a required argument. See help(struct) for more\n\ +on format strings."); static PyObject * pack_into(PyObject *self, PyObject *args) @@ -1845,8 +1868,11 @@ } PyDoc_STRVAR(unpack_doc, -"Unpack the bytes containing packed C structure data, according to fmt.\n\ -Requires len(bytes) == calcsize(fmt)."); +"unpack(fmt, buffer) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to the format string\n\ +fmt. Requires len(buffer) == calcsize(fmt). See help(struct) for more\n\ +on format strings."); static PyObject * unpack(PyObject *self, PyObject *args) @@ -1865,8 +1891,11 @@ } PyDoc_STRVAR(unpack_from_doc, -"Unpack the buffer, containing packed C structure data, according to\n\ -fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt)."); +"unpack_from(fmt, buffer, offset=0) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to the format string\n\ +fmt. Requires len(buffer[offset:]) >= calcsize(fmt). See help(struct)\n\ +for more on format strings."); static PyObject * unpack_from(PyObject *self, PyObject *args, PyObject *kwds) @@ -1953,11 +1982,7 @@ PyMODINIT_FUNC PyInit__struct(void) { - PyObject *ver, *m; - - ver = PyBytes_FromString("0.3"); - if (ver == NULL) - return NULL; + PyObject *m; m = PyModule_Create(&_structmodule); if (m == NULL) @@ -2019,7 +2044,5 @@ Py_INCREF((PyObject*)&PyStructType); PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType); - PyModule_AddObject(m, "__version__", ver); - return m; } Modified: python/branches/py3k-cdecimal/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/_testcapimodule.c (original) +++ python/branches/py3k-cdecimal/Modules/_testcapimodule.c Mon Jun 14 11:30:15 2010 @@ -1011,6 +1011,157 @@ return Py_None; } +static PyObject * +getargs_s(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "s", &str)) + return NULL; + return PyBytes_FromString(str); +} + +static PyObject * +getargs_s_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "s*", &buffer)) + return NULL; + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_s_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &str, &size)) + return NULL; + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_z(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "z", &str)) + return NULL; + if (str != NULL) + return PyBytes_FromString(str); + else + Py_RETURN_NONE; +} + +static PyObject * +getargs_z_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "z*", &buffer)) + return NULL; + if (buffer.buf != NULL) + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + else { + Py_INCREF(Py_None); + bytes = Py_None; + } + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_z_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "z#", &str, &size)) + return NULL; + if (str != NULL) + return PyBytes_FromStringAndSize(str, size); + else + Py_RETURN_NONE; +} + +static PyObject * +getargs_y(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "y", &str)) + return NULL; + return PyBytes_FromString(str); +} + +static PyObject * +getargs_y_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "y*", &buffer)) + return NULL; + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_y_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "y#", &str, &size)) + return NULL; + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_u(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "u", &str)) + return NULL; + size = Py_UNICODE_strlen(str); + return PyUnicode_FromUnicode(str, size); +} + +static PyObject * +getargs_u_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "u#", &str, &size)) + return NULL; + return PyUnicode_FromUnicode(str, size); +} + +static PyObject * +getargs_Z(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Z", &str)) + return NULL; + if (str != NULL) { + size = Py_UNICODE_strlen(str); + return PyUnicode_FromUnicode(str, size); + } else + Py_RETURN_NONE; +} + +static PyObject * +getargs_Z_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Z#", &str, &size)) + return NULL; + if (str != NULL) + return PyUnicode_FromUnicode(str, size); + else + Py_RETURN_NONE; +} /* Test the s and z codes for PyArg_ParseTuple. */ @@ -2062,11 +2213,24 @@ {"test_long_long_and_overflow", (PyCFunction)test_long_long_and_overflow, METH_NOARGS}, {"test_L_code", (PyCFunction)test_L_code, METH_NOARGS}, +#endif + {"getargs_s", getargs_s, METH_VARARGS}, + {"getargs_s_star", getargs_s_star, METH_VARARGS}, + {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, + {"getargs_z", getargs_z, METH_VARARGS}, + {"getargs_z_star", getargs_z_star, METH_VARARGS}, + {"getargs_z_hash", getargs_z_hash, METH_VARARGS}, + {"getargs_y", getargs_y, METH_VARARGS}, + {"getargs_y_star", getargs_y_star, METH_VARARGS}, + {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, + {"getargs_u", getargs_u, METH_VARARGS}, + {"getargs_u_hash", getargs_u_hash, METH_VARARGS}, + {"getargs_Z", getargs_Z, METH_VARARGS}, + {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, {"codec_incrementalencoder", (PyCFunction)codec_incrementalencoder, METH_VARARGS}, {"codec_incrementaldecoder", (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, -#endif {"test_s_code", (PyCFunction)test_s_code, METH_NOARGS}, {"test_u_code", (PyCFunction)test_u_code, METH_NOARGS}, {"test_Z_code", (PyCFunction)test_Z_code, METH_NOARGS}, Modified: python/branches/py3k-cdecimal/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/datetimemodule.c (original) +++ python/branches/py3k-cdecimal/Modules/datetimemodule.c Mon Jun 14 11:30:15 2010 @@ -161,7 +161,7 @@ PyObject *result; PyObject *temp; - temp = _PyLong_Divmod_Near(m, n); + temp = _PyLong_DivmodNear(m, n); if (temp == NULL) return NULL; result = PyTuple_GET_ITEM(temp, 0); Modified: python/branches/py3k-cdecimal/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/itertoolsmodule.c (original) +++ python/branches/py3k-cdecimal/Modules/itertoolsmodule.c Mon Jun 14 11:30:15 2010 @@ -3066,7 +3066,7 @@ }; PyDoc_STRVAR(count_doc, - "count(start=0, step=1]) --> count object\n\ + "count(start=0, step=1) --> count object\n\ \n\ Return a count object whose .__next__() method returns consecutive values.\n\ Equivalent to:\n\n\ Modified: python/branches/py3k-cdecimal/Modules/mathmodule.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/mathmodule.c (original) +++ python/branches/py3k-cdecimal/Modules/mathmodule.c Mon Jun 14 11:30:15 2010 @@ -428,8 +428,8 @@ static double m_erf_series(double x) { - double x2, acc, fk; - int i; + double x2, acc, fk, result; + int i, saved_errno; x2 = x * x; acc = 0.0; @@ -438,7 +438,12 @@ acc = 2.0 + x2 * acc / fk; fk -= 1.0; } - return acc * x * exp(-x2) / sqrtpi; + /* Make sure the exp call doesn't affect errno; + see m_erfc_contfrac for more. */ + saved_errno = errno; + result = acc * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; } /* @@ -453,8 +458,8 @@ static double m_erfc_contfrac(double x) { - double x2, a, da, p, p_last, q, q_last, b; - int i; + double x2, a, da, p, p_last, q, q_last, b, result; + int i, saved_errno; if (x >= ERFC_CONTFRAC_CUTOFF) return 0.0; @@ -472,7 +477,12 @@ 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; + /* Issue #8986: On some platforms, exp sets errno on underflow to zero; + save the current errno value so that we can restore it later. */ + saved_errno = errno; + result = p / q * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; } /* Error function erf(x), for general x */ Modified: python/branches/py3k-cdecimal/Modules/readline.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/readline.c (original) +++ python/branches/py3k-cdecimal/Modules/readline.c Mon Jun 14 11:30:15 2010 @@ -98,10 +98,16 @@ static PyObject * read_init_file(PyObject *self, PyObject *args) { - char *s = NULL; - if (!PyArg_ParseTuple(args, "|z:read_init_file", &s)) + PyObject *filename_obj = Py_None, *filename_bytes; + if (!PyArg_ParseTuple(args, "|O:read_init_file", &filename_obj)) return NULL; - errno = rl_read_init_file(s); + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + errno = rl_read_init_file(PyBytes_AsString(filename_bytes)); + Py_DECREF(filename_bytes); + } else + errno = rl_read_init_file(NULL); if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; @@ -118,10 +124,16 @@ static PyObject * read_history_file(PyObject *self, PyObject *args) { - char *s = NULL; - if (!PyArg_ParseTuple(args, "|z:read_history_file", &s)) + PyObject *filename_obj = Py_None, *filename_bytes; + if (!PyArg_ParseTuple(args, "|O:read_history_file", &filename_obj)) return NULL; - errno = read_history(s); + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + errno = read_history(PyBytes_AsString(filename_bytes)); + Py_DECREF(filename_bytes); + } else + errno = read_history(NULL); if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; @@ -139,12 +151,22 @@ static PyObject * write_history_file(PyObject *self, PyObject *args) { - char *s = NULL; - if (!PyArg_ParseTuple(args, "|z:write_history_file", &s)) + PyObject *filename_obj = Py_None, *filename_bytes; + char *filename; + if (!PyArg_ParseTuple(args, "|O:write_history_file", &filename_obj)) return NULL; - errno = write_history(s); + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + filename = PyBytes_AsString(filename_bytes); + } else { + filename_bytes = NULL; + filename = NULL; + } + errno = write_history(filename); if (!errno && _history_length >= 0) - history_truncate_file(s, _history_length); + history_truncate_file(filename, _history_length); + Py_XDECREF(filename_bytes); if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; Modified: python/branches/py3k-cdecimal/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/bytearrayobject.c (original) +++ python/branches/py3k-cdecimal/Objects/bytearrayobject.c Mon Jun 14 11:30:15 2010 @@ -1650,43 +1650,43 @@ char from_c, char to_c, Py_ssize_t maxcount) { - char *self_s, *result_s, *start, *end, *next; - Py_ssize_t self_len; - PyByteArrayObject *result; - - /* The result string will be the same size */ - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); - - next = findchar(self_s, self_len, from_c); - - if (next == NULL) { - /* No matches; return the original bytes */ - return return_self(self); - } + char *self_s, *result_s, *start, *end, *next; + Py_ssize_t self_len; + PyByteArrayObject *result; - /* Need to make a new bytes */ - result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - Py_MEMCPY(result_s, self_s, self_len); + /* The result string will be the same size */ + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); - /* change everything in-place, starting with this one */ - start = result_s + (next-self_s); - *start = to_c; - start++; - end = result_s + self_len; - - while (--maxcount > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - *next = to_c; - start = next+1; - } + next = findchar(self_s, self_len, from_c); + + if (next == NULL) { + /* No matches; return the original bytes */ + return return_self(self); + } + + /* Need to make a new bytes */ + result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); + if (result == NULL) + return NULL; + result_s = PyByteArray_AS_STRING(result); + Py_MEMCPY(result_s, self_s, self_len); + + /* change everything in-place, starting with this one */ + start = result_s + (next-self_s); + *start = to_c; + start++; + end = result_s + self_len; - return result; + while (--maxcount > 0) { + next = findchar(start, end-start, from_c); + if (next == NULL) + break; + *next = to_c; + start = next+1; + } + + return result; } /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ Modified: python/branches/py3k-cdecimal/Objects/bytesobject.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/bytesobject.c (original) +++ python/branches/py3k-cdecimal/Objects/bytesobject.c Mon Jun 14 11:30:15 2010 @@ -14,10 +14,10 @@ if (buffer == NULL || buffer->bf_getbuffer == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't support the buffer API", + Py_TYPE(obj)->tp_name); + return -1; } if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) @@ -776,19 +776,19 @@ { Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) { - Py_buffer varg; - int pos; - PyErr_Clear(); - if (_getbuffer(arg, &varg) < 0) - return -1; - pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), - varg.buf, varg.len, 0); - PyBuffer_Release(&varg); - return pos >= 0; + Py_buffer varg; + int pos; + PyErr_Clear(); + if (_getbuffer(arg, &varg) < 0) + return -1; + pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), + varg.buf, varg.len, 0); + PyBuffer_Release(&varg); + return pos >= 0; } if (ival < 0 || ival >= 256) { - PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); - return -1; + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return -1; } return memchr(PyBytes_AS_STRING(self), ival, Py_SIZE(self)) != NULL; @@ -2345,12 +2345,12 @@ int keepends = 0; if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) - return NULL; + return NULL; return stringlib_splitlines( - (PyObject*) self, PyBytes_AS_STRING(self), - PyBytes_GET_SIZE(self), keepends - ); + (PyObject*) self, PyBytes_AS_STRING(self), + PyBytes_GET_SIZE(self), keepends + ); } Modified: python/branches/py3k-cdecimal/Objects/exceptions.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/exceptions.c (original) +++ python/branches/py3k-cdecimal/Objects/exceptions.c Mon Jun 14 11:30:15 2010 @@ -1510,7 +1510,7 @@ const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason) { - return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU", + return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns", encoding, object, length, start, end, reason); } @@ -1625,7 +1625,7 @@ assert(length < INT_MAX); assert(start < INT_MAX); assert(end < INT_MAX); - return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU", + return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns", encoding, object, length, start, end, reason); } Modified: python/branches/py3k-cdecimal/Objects/longobject.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/longobject.c (original) +++ python/branches/py3k-cdecimal/Objects/longobject.c Mon Jun 14 11:30:15 2010 @@ -4218,7 +4218,7 @@ round-half-to-even. */ PyObject * -_PyLong_Divmod_Near(PyObject *a, PyObject *b) +_PyLong_DivmodNear(PyObject *a, PyObject *b) { PyLongObject *quo = NULL, *rem = NULL; PyObject *one = NULL, *twice_rem, *result, *temp; @@ -4363,7 +4363,7 @@ if (result == NULL) return NULL; - temp = _PyLong_Divmod_Near(self, result); + temp = _PyLong_DivmodNear(self, result); Py_DECREF(result); result = temp; if (result == NULL) Modified: python/branches/py3k-cdecimal/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-cdecimal/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-cdecimal/Objects/stringlib/formatter.h Mon Jun 14 11:30:15 2010 @@ -649,8 +649,8 @@ case LT_DEFAULT_LOCALE: locale_info->decimal_point = "."; locale_info->thousands_sep = ","; - locale_info->grouping = "\3"; /* Group every 3 characters, - trailing 0 means repeat + locale_info->grouping = "\3"; /* Group every 3 characters. The + (implicit) trailing 0 means repeat infinitely. */ break; case LT_NO_LOCALE: Modified: python/branches/py3k-cdecimal/Objects/stringlib/string_format.h ============================================================================== --- python/branches/py3k-cdecimal/Objects/stringlib/string_format.h (original) +++ python/branches/py3k-cdecimal/Objects/stringlib/string_format.h Mon Jun 14 11:30:15 2010 @@ -373,6 +373,8 @@ if (_FieldNameIterator_item(self, name) == 0) return 0; *name_idx = get_integer(name); + if (*name_idx == -1 && PyErr_Occurred()) + return 0; break; default: /* Invalid character follows ']' */ @@ -429,6 +431,8 @@ /* see if "first" is an integer, in which case it's used as an index */ *first_idx = get_integer(first); + if (*first_idx == -1 && PyErr_Occurred()) + return 0; field_name_is_empty = first->ptr >= first->end; Modified: python/branches/py3k-cdecimal/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k-cdecimal/Objects/unicodeobject.c (original) +++ python/branches/py3k-cdecimal/Objects/unicodeobject.c Mon Jun 14 11:30:15 2010 @@ -1293,25 +1293,24 @@ return NULL; } -PyObject *PyUnicode_Decode(const char *s, - Py_ssize_t size, - const char *encoding, - const char *errors) +/* Convert encoding to lower case and replace '_' with '-' in order to + catch e.g. UTF_8. Return 0 on error (encoding is longer than lower_len-1), + 1 on success. */ +static int +normalize_encoding(const char *encoding, + char *lower, + size_t lower_len) { - PyObject *buffer = NULL, *unicode; - Py_buffer info; - char lower[20]; /* Enough for any encoding name we recognize */ - char *l; const char *e; + char *l; + char *l_end; - if (encoding == NULL) - encoding = PyUnicode_GetDefaultEncoding(); - - /* Convert encoding to lower case and replace '_' with '-' in order to - catch e.g. UTF_8 */ e = encoding; l = lower; - while (*e && l < &lower[(sizeof lower) - 2]) { + l_end = &lower[lower_len - 1]; + while (*e) { + if (l == l_end) + return 0; if (ISUPPER(*e)) { *l++ = TOLOWER(*e++); } @@ -1324,23 +1323,39 @@ } } *l = '\0'; + return 1; +} + +PyObject *PyUnicode_Decode(const char *s, + Py_ssize_t size, + const char *encoding, + const char *errors) +{ + PyObject *buffer = NULL, *unicode; + Py_buffer info; + char lower[11]; /* Enough for any encoding shortcut */ + + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - if (strcmp(lower, "utf-8") == 0) - return PyUnicode_DecodeUTF8(s, size, errors); - else if ((strcmp(lower, "latin-1") == 0) || - (strcmp(lower, "iso-8859-1") == 0)) - return PyUnicode_DecodeLatin1(s, size, errors); + if (normalize_encoding(encoding, lower, sizeof(lower))) { + if (strcmp(lower, "utf-8") == 0) + return PyUnicode_DecodeUTF8(s, size, errors); + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) + return PyUnicode_DecodeLatin1(s, size, errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(lower, "mbcs") == 0) - return PyUnicode_DecodeMBCS(s, size, errors); + else if (strcmp(lower, "mbcs") == 0) + return PyUnicode_DecodeMBCS(s, size, errors); #endif - else if (strcmp(lower, "ascii") == 0) - return PyUnicode_DecodeASCII(s, size, errors); - else if (strcmp(lower, "utf-16") == 0) - return PyUnicode_DecodeUTF16(s, size, errors, 0); - else if (strcmp(lower, "utf-32") == 0) - return PyUnicode_DecodeUTF32(s, size, errors, 0); + else if (strcmp(lower, "ascii") == 0) + return PyUnicode_DecodeASCII(s, size, errors); + else if (strcmp(lower, "utf-16") == 0) + return PyUnicode_DecodeUTF16(s, size, errors, 0); + else if (strcmp(lower, "utf-32") == 0) + return PyUnicode_DecodeUTF32(s, size, errors, 0); + } /* Decode via the codec registry */ buffer = NULL; @@ -1463,11 +1478,17 @@ PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) { - if (Py_FileSystemDefaultEncoding) + if (Py_FileSystemDefaultEncoding) { +#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) + if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + NULL); +#endif return PyUnicode_AsEncodedString(unicode, Py_FileSystemDefaultEncoding, "surrogateescape"); - else + } else return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), "surrogateescape"); @@ -1478,6 +1499,7 @@ const char *errors) { PyObject *v; + char lower[11]; /* Enough for any encoding shortcut */ if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); @@ -1488,24 +1510,27 @@ encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - if (strcmp(encoding, "utf-8") == 0) - return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); - else if (strcmp(encoding, "latin-1") == 0) - return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + if (normalize_encoding(encoding, lower, sizeof(lower))) { + if (strcmp(lower, "utf-8") == 0) + return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) + return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(encoding, "mbcs") == 0) - return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + else if (strcmp(lower, "mbcs") == 0) + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #endif - else if (strcmp(encoding, "ascii") == 0) - return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + else if (strcmp(lower, "ascii") == 0) + return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + } /* During bootstrap, we may need to find the encodings package, to load the file system encoding, and require the file system encoding in order to load the encodings @@ -1515,7 +1540,7 @@ the encodings module is ASCII-only. XXX could try wcstombs instead, if the file system encoding is the locale's encoding. */ - else if (Py_FileSystemDefaultEncoding && + if (Py_FileSystemDefaultEncoding && strcmp(encoding, Py_FileSystemDefaultEncoding) == 0 && !PyThreadState_GET()->interp->codecs_initialized) return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), @@ -1620,7 +1645,7 @@ if (Py_FileSystemDefaultEncoding) { #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) { - return PyUnicode_DecodeMBCS(s, size, "surrogateescape"); + return PyUnicode_DecodeMBCS(s, size, NULL); } #elif defined(__APPLE__) if (strcmp(Py_FileSystemDefaultEncoding, "utf-8") == 0) { @@ -2711,7 +2736,8 @@ PyUnicodeObject *unicode; Py_UNICODE *p; #ifndef Py_UNICODE_WIDE - int i, pairs; + int pairs = 0; + const unsigned char *qq; #else const int pairs = 0; #endif @@ -2726,23 +2752,7 @@ #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* On narrow builds we split characters outside the BMP into two - codepoints => count how much extra space we need. */ -#ifndef Py_UNICODE_WIDE - for (i = pairs = 0; i < size/4; i++) - if (((Py_UCS4 *)s)[i] >= 0x10000) - pairs++; -#endif - /* This might be one to much, because of a BOM */ - unicode = _PyUnicode_New((size+3)/4+pairs); - if (!unicode) - return NULL; - if (size == 0) - return (PyObject *)unicode; - - /* Unpack UTF-32 encoded data */ - p = unicode->str; q = (unsigned char *)s; e = q + size; @@ -2794,6 +2804,24 @@ iorder[3] = 0; } + /* On narrow builds we split characters outside the BMP into two + codepoints => count how much extra space we need. */ +#ifndef Py_UNICODE_WIDE + for (qq = q; qq < e; qq += 4) + if (qq[iorder[2]] != 0 || qq[iorder[3]] != 0) + pairs++; +#endif + + /* This might be one to much, because of a BOM */ + unicode = _PyUnicode_New((size+3)/4+pairs); + if (!unicode) + return NULL; + if (size == 0) + return (PyObject *)unicode; + + /* Unpack UTF-32 encoded data */ + p = unicode->str; + while (q < e) { Py_UCS4 ch; /* remaining bytes at the end? (size should be divisible by 4) */ Modified: python/branches/py3k-cdecimal/PC/winreg.c ============================================================================== --- python/branches/py3k-cdecimal/PC/winreg.c (original) +++ python/branches/py3k-cdecimal/PC/winreg.c Mon Jun 14 11:30:15 2010 @@ -1129,6 +1129,7 @@ int index; long rc; wchar_t *retValueBuf; + wchar_t *tmpBuf; BYTE *retDataBuf; DWORD retValueSize, bufValueSize; DWORD retDataSize, bufDataSize; @@ -1161,7 +1162,6 @@ } while (1) { - wchar_t *tmp; Py_BEGIN_ALLOW_THREADS rc = RegEnumValueW(hKey, index, @@ -1177,13 +1177,13 @@ break; bufDataSize *= 2; - tmp = (char *)PyMem_Realloc(retDataBuf, bufDataSize); - if (tmp == NULL) { + tmpBuf = (wchar_t *)PyMem_Realloc(retDataBuf, bufDataSize); + if (tmpBuf == NULL) { PyErr_NoMemory(); retVal = NULL; goto fail; } - retDataBuf = tmp; + retDataBuf = tmpBuf; retDataSize = bufDataSize; retValueSize = bufValueSize; } Modified: python/branches/py3k-cdecimal/Parser/asdl_c.py ============================================================================== --- python/branches/py3k-cdecimal/Parser/asdl_c.py (original) +++ python/branches/py3k-cdecimal/Parser/asdl_c.py Mon Jun 14 11:30:15 2010 @@ -722,7 +722,7 @@ } PyTuple_SET_ITEM(fnames, i, field); } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "U(O){sOss}", + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sOss}", type, base, "_fields", fnames, "__module__", "_ast"); Py_DECREF(fnames); return (PyTypeObject*)result; Modified: python/branches/py3k-cdecimal/Python/Python-ast.c ============================================================================== --- python/branches/py3k-cdecimal/Python/Python-ast.c (original) +++ python/branches/py3k-cdecimal/Python/Python-ast.c Mon Jun 14 11:30:15 2010 @@ -527,7 +527,7 @@ } PyTuple_SET_ITEM(fnames, i, field); } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "U(O){sOss}", + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sOss}", type, base, "_fields", fnames, "__module__", "_ast"); Py_DECREF(fnames); return (PyTypeObject*)result; Modified: python/branches/py3k-cdecimal/Python/errors.c ============================================================================== --- python/branches/py3k-cdecimal/Python/errors.c (original) +++ python/branches/py3k-cdecimal/Python/errors.c Mon Jun 14 11:30:15 2010 @@ -679,7 +679,7 @@ goto failure; } /* Create a real new-style class. */ - result = PyObject_CallFunction((PyObject *)&PyType_Type, "UOO", + result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO", dot+1, bases, dict); failure: Py_XDECREF(bases); Modified: python/branches/py3k-cdecimal/Python/getargs.c ============================================================================== --- python/branches/py3k-cdecimal/Python/getargs.c (original) +++ python/branches/py3k-cdecimal/Python/getargs.c Mon Jun 14 11:30:15 2010 @@ -582,19 +582,6 @@ #define CONV_UNICODE "(unicode conversion error)" -/* explicitly check for float arguments when integers are expected. For now - * signal a warning. Returns true if an exception was raised. */ -static int -float_argument_warning(PyObject *arg) -{ - if (PyFloat_Check(arg) && - PyErr_Warn(PyExc_DeprecationWarning, - "integer argument expected, got float" )) - return 1; - else - return 0; -} - /* Explicitly check for float arguments when integers are expected. Return 1 for error, 0 if ok. */ static int @@ -791,14 +778,13 @@ case 'L': {/* PY_LONG_LONG */ PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * ); PY_LONG_LONG ival; - if (float_argument_warning(arg)) + if (float_argument_error(arg)) return converterr("long", arg, msgbuf, bufsize); ival = PyLong_AsLongLong(arg); - if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) { + if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred()) return converterr("long", arg, msgbuf, bufsize); - } else { + else *p = ival; - } break; } @@ -864,7 +850,7 @@ break; } - /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w', 't' codes all + /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all need to be cleaned up! */ case 's': {/* text string */ @@ -949,10 +935,15 @@ count = convertbuffer(arg, p, &buf); if (count < 0) return converterr(buf, arg, msgbuf, bufsize); - else if (*format == '#') { + if (*format == '#') { FETCH_SIZE; STORE_SIZE(count); format++; + } else { + if (strlen(*p) != count) + return converterr( + "bytes without null bytes", + arg, msgbuf, bufsize); } break; } @@ -1051,17 +1042,22 @@ *p = PyUnicode_AS_UNICODE(arg); STORE_SIZE(PyUnicode_GET_SIZE(arg)); } + else + return converterr("str or None", arg, msgbuf, bufsize); format++; } else { Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); if (arg == Py_None) *p = 0; - else if (PyUnicode_Check(arg)) + else if (PyUnicode_Check(arg)) { *p = PyUnicode_AS_UNICODE(arg); - else - return converterr("string or None", - arg, msgbuf, bufsize); + if (Py_UNICODE_strlen(*p) != PyUnicode_GET_SIZE(arg)) + return converterr( + "str without null character or None", + arg, msgbuf, bufsize); + } else + return converterr("str or None", arg, msgbuf, bufsize); } break; } @@ -1240,6 +1236,11 @@ FETCH_SIZE; STORE_SIZE(PyUnicode_GET_SIZE(arg)); format++; + } else { + if (Py_UNICODE_strlen(*p) != PyUnicode_GET_SIZE(arg)) + return converterr( + "str without null character", + arg, msgbuf, bufsize); } break; } @@ -1258,7 +1259,7 @@ if (PyByteArray_Check(arg)) *p = arg; else - return converterr("buffer", arg, msgbuf, bufsize); + return converterr("bytearray", arg, msgbuf, bufsize); break; } @@ -1361,45 +1362,6 @@ break; } - /*TEO: This can be eliminated --- here only for backward - compatibility */ - case 't': { /* 8-bit character buffer, read-only access */ - char **p = va_arg(*p_va, char **); - PyBufferProcs *pb = arg->ob_type->tp_as_buffer; - Py_ssize_t count; - Py_buffer view; - - if (*format++ != '#') - return converterr( - "invalid use of 't' format character", - arg, msgbuf, bufsize); - if (pb == NULL || pb->bf_getbuffer == NULL) - return converterr( - "bytes or read-only character buffer", - arg, msgbuf, bufsize); - - if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0) - return converterr("string or single-segment read-only buffer", - arg, msgbuf, bufsize); - - count = view.len; - *p = view.buf; - if (pb->bf_releasebuffer) - return converterr( - "string or pinned buffer", - arg, msgbuf, bufsize); - - PyBuffer_Release(&view); - - if (count < 0) - return converterr("(unspecified)", arg, msgbuf, bufsize); - { - FETCH_SIZE; - STORE_SIZE(count); - } - break; - } - default: return converterr("impossible", arg, msgbuf, bufsize); @@ -1806,7 +1768,6 @@ case 'z': /* string or None */ case 'y': /* bytes */ case 'u': /* unicode string */ - case 't': /* buffer, read-only */ case 'w': /* buffer, read-write */ { (void) va_arg(*p_va, char **); Modified: python/branches/py3k-cdecimal/Python/modsupport.c ============================================================================== --- python/branches/py3k-cdecimal/Python/modsupport.c (original) +++ python/branches/py3k-cdecimal/Python/modsupport.c Mon Jun 14 11:30:15 2010 @@ -302,39 +302,7 @@ case 's': case 'z': - { - PyObject *v; - char *str = va_arg(*p_va, char *); - Py_ssize_t n; - if (**p_format == '#') { - ++*p_format; - if (flags & FLAG_SIZE_T) - n = va_arg(*p_va, Py_ssize_t); - else - n = va_arg(*p_va, int); - } - else - n = -1; - if (str == NULL) { - v = Py_None; - Py_INCREF(v); - } - else { - if (n < 0) { - size_t m = strlen(str); - if (m > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "string too long for Python string"); - return NULL; - } - n = (Py_ssize_t)m; - } - v = PyUnicode_FromStringAndSize(str, n); - } - return v; - } - - case 'U': + case 'U': /* XXX deprecated alias */ { PyObject *v; char *str = va_arg(*p_va, char *); Modified: python/branches/py3k-cdecimal/Python/pythonrun.c ============================================================================== --- python/branches/py3k-cdecimal/Python/pythonrun.c (original) +++ python/branches/py3k-cdecimal/Python/pythonrun.c Mon Jun 14 11:30:15 2010 @@ -703,24 +703,26 @@ #if defined(HAVE_LANGINFO_H) && defined(CODESET) char *codeset; - /* On Unix, set the file system encoding according to the - user's preference, if the CODESET names a well-known - Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - codeset = get_codeset(); - if (codeset != NULL) { - Py_FileSystemDefaultEncoding = codeset; - Py_HasFileSystemDefaultEncoding = 0; - return; - } + if (Py_FileSystemDefaultEncoding == NULL) { + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. Also set the encoding of + stdin and stdout if these are terminals. */ + codeset = get_codeset(); + if (codeset != NULL) { + Py_FileSystemDefaultEncoding = codeset; + Py_HasFileSystemDefaultEncoding = 0; + return; + } - PyErr_Clear(); - fprintf(stderr, - "Unable to get the locale encoding: " - "fallback to utf-8\n"); - Py_FileSystemDefaultEncoding = "utf-8"; - Py_HasFileSystemDefaultEncoding = 1; + PyErr_Clear(); + fprintf(stderr, + "Unable to get the locale encoding: " + "fallback to utf-8\n"); + Py_FileSystemDefaultEncoding = "utf-8"; + Py_HasFileSystemDefaultEncoding = 1; + } #endif /* the encoding is mbcs, utf-8 or ascii */ @@ -2055,7 +2057,7 @@ fprintf(stderr, "Fatal Python error: %s\n", msg); fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { - PyErr_Print(); + PyErr_PrintEx(0); } #ifdef MS_WINDOWS { Modified: python/branches/py3k-cdecimal/Python/symtable.c ============================================================================== --- python/branches/py3k-cdecimal/Python/symtable.c (original) +++ python/branches/py3k-cdecimal/Python/symtable.c Mon Jun 14 11:30:15 2010 @@ -1533,7 +1533,7 @@ symtable_visit_alias(struct symtable *st, alias_ty a) { /* Compute store_name, the name actually bound by the import - operation. It is diferent than a->name when a->name is a + operation. It is different than a->name when a->name is a dotted package name (e.g. spam.eggs) */ PyObject *store_name; Modified: python/branches/py3k-cdecimal/Python/sysmodule.c ============================================================================== --- python/branches/py3k-cdecimal/Python/sysmodule.c (original) +++ python/branches/py3k-cdecimal/Python/sysmodule.c Mon Jun 14 11:30:15 2010 @@ -1510,7 +1510,7 @@ PyLong_FromLong(PY_VERSION_HEX)); svnversion_init(); SET_SYS_FROM_STRING("subversion", - Py_BuildValue("(UUU)", "CPython", branch, + Py_BuildValue("(sss)", "CPython", branch, svn_revision)); SET_SYS_FROM_STRING("dont_write_bytecode", PyBool_FromLong(Py_DontWriteBytecodeFlag)); @@ -1839,6 +1839,9 @@ PyObject *unicode = NULL, *writer = NULL, *args = NULL, *result = NULL; int err; + if (file == NULL) + return -1; + unicode = PyUnicode_FromString(text); if (unicode == NULL) goto error; Modified: python/branches/py3k-cdecimal/setup.py ============================================================================== --- python/branches/py3k-cdecimal/setup.py (original) +++ python/branches/py3k-cdecimal/setup.py Mon Jun 14 11:30:15 2010 @@ -14,6 +14,7 @@ from distutils.command.build_ext import build_ext from distutils.command.install import install from distutils.command.install_lib import install_lib +from distutils.spawn import find_executable # Were we compiled --with-pydebug or with #define Py_DEBUG? COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') @@ -525,6 +526,38 @@ # readline do_readline = self.compiler_obj.find_library_file(lib_dirs, 'readline') + readline_termcap_library = "" + curses_library = "" + # Determine if readline is already linked against curses or tinfo. + if do_readline and find_executable('ldd'): + # Cannot use os.popen here in py3k. + tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) + os.system("ldd %s > %s" % (do_readline, tmpfile)) + fp = open(tmpfile) + for ln in fp: + if 'curses' in ln: + readline_termcap_library = re.sub( + r'.*lib(n?cursesw?)\.so.*', r'\1', ln + ).rstrip() + break + if 'tinfo' in ln: # termcap interface split out from ncurses + readline_termcap_library = 'tinfo' + break + fp.close() + os.unlink(tmpfile) + # Issue 7384: If readline is already linked against curses, + # use the same library for the readline and curses modules. + if 'curses' in readline_termcap_library: + curses_library = readline_termcap_library + elif self.compiler_obj.find_library_file(lib_dirs, 'ncursesw'): + curses_library = 'ncursesw' + elif self.compiler_obj.find_library_file(lib_dirs, 'ncurses'): + curses_library = 'ncurses' + elif self.compiler_obj.find_library_file(lib_dirs, 'curses'): + curses_library = 'curses' + if platform == 'darwin': os_release = int(os.uname()[2].split('.')[0]) dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') @@ -548,14 +581,10 @@ readline_extra_link_args = () readline_libs = ['readline'] - if self.compiler_obj.find_library_file(lib_dirs, - 'ncursesw'): - readline_libs.append('ncursesw') - elif self.compiler_obj.find_library_file(lib_dirs, - 'ncurses'): - readline_libs.append('ncurses') - elif self.compiler_obj.find_library_file(lib_dirs, 'curses'): - readline_libs.append('curses') + if readline_termcap_library: + pass # Issue 7384: Already linked against curses or tinfo. + elif curses_library: + readline_libs.append(curses_library) elif self.compiler_obj.find_library_file(lib_dirs + ['/usr/lib/termcap'], 'termcap'): @@ -1070,19 +1099,15 @@ # Curses support, requiring the System V version of curses, often # provided by the ncurses library. panel_library = 'panel' - if (self.compiler_obj.find_library_file(lib_dirs, 'ncursesw')): - curses_libs = ['ncursesw'] - # Bug 1464056: If _curses.so links with ncursesw, - # _curses_panel.so must link with panelw. - panel_library = 'panelw' - exts.append( Extension('_curses', ['_cursesmodule.c'], - libraries = curses_libs) ) - elif (self.compiler_obj.find_library_file(lib_dirs, 'ncurses')): - curses_libs = ['ncurses'] + if curses_library.startswith('ncurses'): + if curses_library == 'ncursesw': + # Bug 1464056: If _curses.so links with ncursesw, + # _curses_panel.so must link with panelw. + panel_library = 'panelw' + curses_libs = [curses_library] exts.append( Extension('_curses', ['_cursesmodule.c'], libraries = curses_libs) ) - elif (self.compiler_obj.find_library_file(lib_dirs, 'curses') - and platform != 'darwin'): + elif curses_library == 'curses' and platform != 'darwin': # OSX has an old Berkeley curses, not good enough for # the _curses module. if (self.compiler_obj.find_library_file(lib_dirs, 'terminfo')): From python-checkins at python.org Mon Jun 14 16:15:50 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Mon, 14 Jun 2010 16:15:50 +0200 (CEST) Subject: [Python-checkins] r81981 - in python/branches/py3k: Doc/library/datetime.rst Lib/test/test_datetime.py Misc/ACKS Misc/NEWS Modules/datetimemodule.c Message-ID: <20100614141550.BFDA3EED7F@mail.python.org> Author: alexander.belopolsky Date: Mon Jun 14 16:15:50 2010 New Revision: 81981 Log: Issue #5094: The ``datetime`` module now has a simple concrete class implementing ``datetime.tzinfo`` interface. Modified: python/branches/py3k/Doc/library/datetime.rst python/branches/py3k/Lib/test/test_datetime.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/datetimemodule.c Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Mon Jun 14 16:15:50 2010 @@ -28,11 +28,14 @@ have an optional time zone information member, :attr:`tzinfo`, that can contain an instance of a subclass of the abstract :class:`tzinfo` class. These :class:`tzinfo` objects capture information about the offset from UTC time, the -time zone name, and whether Daylight Saving Time is in effect. Note that no -concrete :class:`tzinfo` classes are supplied by the :mod:`datetime` module. -Supporting timezones at whatever level of detail is required is up to the -application. The rules for time adjustment across the world are more political -than rational, and there is no standard suitable for every application. +time zone name, and whether Daylight Saving Time is in effect. Note that only +one concrete :class:`tzinfo` class, the :class:`timezone` class, is supplied by the +:mod:`datetime` module. The :class:`timezone` class can reprsent simple +timezones with fixed offset from UTC such as UTC itself or North American EST and +EDT timezones. Supporting timezones at whatever level of detail is +required is up to the application. The rules for time adjustment across the +world are more political than rational, change frequently, and there is no +standard suitable for every application aside from UTC. The :mod:`datetime` module exports the following constants: @@ -99,6 +102,14 @@ time adjustment (for example, to account for time zone and/or daylight saving time). +.. class:: timezone + + A class that implements the :class:`tzinfo` abstract base class as a + fixed offset from the UTC. + + .. versionadded:: 3.2 + + Objects of these types are immutable. Objects of the :class:`date` type are always naive. @@ -116,6 +127,7 @@ object timedelta tzinfo + timezone time date datetime @@ -660,8 +672,8 @@ Return the current UTC date and time, with :attr:`tzinfo` ``None``. This is like :meth:`now`, but returns the current UTC date and time, as a naive - :class:`datetime` object. See also :meth:`now`. - + :class:`datetime` object. An aware current UTC datetime can be obtained by + calling ``datetime.now(timezone.utc)``. See also :meth:`now`. .. classmethod:: datetime.fromtimestamp(timestamp, tz=None) @@ -1318,8 +1330,10 @@ :class:`tzinfo` is an abstract base class, meaning that this class should not be instantiated directly. You need to derive a concrete subclass, and (at least) supply implementations of the standard :class:`tzinfo` methods needed by the -:class:`datetime` methods you use. The :mod:`datetime` module does not supply -any concrete subclasses of :class:`tzinfo`. +:class:`datetime` methods you use. The :mod:`datetime` module supplies +a simple concrete subclass of :class:`tzinfo` :class:`timezone` which can reprsent +timezones with fixed offset from UTC such as UTC itself or North American EST and +EDT. An instance of (a concrete subclass of) :class:`tzinfo` can be passed to the constructors for :class:`datetime` and :class:`time` objects. The latter objects @@ -1520,9 +1534,65 @@ standard local time. Applications that can't bear such ambiguities should avoid using hybrid -:class:`tzinfo` subclasses; there are no ambiguities when using UTC, or any -other fixed-offset :class:`tzinfo` subclass (such as a class representing only -EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). +:class:`tzinfo` subclasses; there are no ambiguities when using :class:`timezone`, +or any other fixed-offset :class:`tzinfo` subclass (such as a class representing +only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). + + +.. _datetime-timezone: + +:class:`timezone` Objects +-------------------------- + +A :class:`timezone` object represents a timezone that is defined by a +fixed offset from UTC. Note that objects of this class cannot be used +to represent timezone information in the locations where different +offsets are used in different days of the year or where historical +changes have been made to civil time. + + +.. class:: timezone(offset[, name]) + + The ``offset`` argument must be specified as a :class:`timedelta` + object representing the difference between the local time and UTC. It must + be within the range [``-timedelta(hours=23, minutes=59), + ``timedelta(hours=23, minutes=59)``] and represent whole number of minutes, + otherwise :exc:`ValueError` is raised. + + The ``name`` argument is optional. If specified it must be a string that + used as the value returned by the ``tzname(dt)`` method. Otherwise, + ``tzname(dt)`` returns a string 'UTCsHH:MM', where s is the sign of + ``offset``, HH and MM are two digits of ``offset.hours`` and + ``offset.minutes`` respectively. + +.. method:: timezone.utcoffset(self, dt) + + Returns the fixed value specified when the :class:`timezone` instance is + constructed. The ``dt`` argument is ignored. The return value is a + :class:`timedelta` instance equal to the difference between the + local time and UTC. + +.. method:: timezone.tzname(self, dt) + + Returns the fixed value specified when the :class:`timezone` instance is + constructed or a string 'UTCsHH:MM', where s is the sign of + ``offset``, HH and MM are two digits of ``offset.hours`` and + ``offset.minutes`` respectively. The ``dt`` argument is ignored. + +.. method:: timezone.dst(self, dt) + + Always returns ``None``. + +.. method:: timezone.fromutc(self, dt) + + Returns ``dt + offset``. The ``dt`` argument must be aware with ``tzinfo`` + set to ``self``. + +Class attributes: + +.. attribute:: timezone.utc + + The UTC timezone, ``timezone(0, 'UTC')``. .. _strftime-strptime-behavior: 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 Mon Jun 14 16:15:50 2010 @@ -15,6 +15,7 @@ from datetime import timedelta from datetime import tzinfo from datetime import time +from datetime import timezone from datetime import date, datetime pickle_choices = [(pickle, pickle, proto) for proto in range(3)] @@ -49,6 +50,7 @@ # tzinfo tests class FixedOffset(tzinfo): + def __init__(self, offset, name, dstoffset=42): if isinstance(offset, int): offset = timedelta(minutes=offset) @@ -67,6 +69,7 @@ return self.__dstoffset class PicklableFixedOffset(FixedOffset): + def __init__(self, offset=None, name=None, dstoffset=None): FixedOffset.__init__(self, offset, name, dstoffset) @@ -131,6 +134,97 @@ self.assertEqual(derived.utcoffset(None), offset) self.assertEqual(derived.tzname(None), 'cookie') +class TestTimeZone(unittest.TestCase): + + def setUp(self): + self.ACDT = timezone(timedelta(hours=9.5), 'ACDT') + self.EST = timezone(-timedelta(hours=5), 'EST') + self.DT = datetime(2010, 1, 1) + + def test_str(self): + for tz in [self.ACDT, self.EST, timezone.utc, + timezone.min, timezone.max]: + self.assertEqual(str(tz), tz.tzname(None)) + + def test_class_members(self): + limit = timedelta(hours=23, minutes=59) + self.assertEquals(timezone.utc.utcoffset(None), ZERO) + self.assertEquals(timezone.min.utcoffset(None), -limit) + self.assertEquals(timezone.max.utcoffset(None), limit) + + + def test_constructor(self): + self.assertEquals(timezone.utc, timezone(timedelta(0))) + # invalid offsets + for invalid in [timedelta(microseconds=1), timedelta(1, 1), + timedelta(seconds=1), timedelta(1), -timedelta(1)]: + self.assertRaises(ValueError, timezone, invalid) + self.assertRaises(ValueError, timezone, -invalid) + + with self.assertRaises(TypeError): timezone(None) + with self.assertRaises(TypeError): timezone(42) + with self.assertRaises(TypeError): timezone(ZERO, None) + with self.assertRaises(TypeError): timezone(ZERO, 42) + + def test_inheritance(self): + self.assertTrue(isinstance(timezone.utc, tzinfo)) + self.assertTrue(isinstance(self.EST, tzinfo)) + + def test_utcoffset(self): + dummy = self.DT + for h in [0, 1.5, 12]: + offset = h * HOUR + self.assertEquals(offset, timezone(offset).utcoffset(dummy)) + self.assertEquals(-offset, timezone(-offset).utcoffset(dummy)) + + with self.assertRaises(TypeError): self.EST.utcoffset('') + with self.assertRaises(TypeError): self.EST.utcoffset(5) + + + def test_dst(self): + self.assertEquals(None, timezone.utc.dst(self.DT)) + + with self.assertRaises(TypeError): self.EST.dst('') + with self.assertRaises(TypeError): self.EST.dst(5) + + def test_tzname(self): + self.assertEquals('UTC+00:00', timezone(ZERO).tzname(None)) + self.assertEquals('UTC-05:00', timezone(-5 * HOUR).tzname(None)) + self.assertEquals('UTC+09:30', timezone(9.5 * HOUR).tzname(None)) + self.assertEquals('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None)) + self.assertEquals('XYZ', timezone(-5 * HOUR, 'XYZ').tzname(None)) + + with self.assertRaises(TypeError): self.EST.tzname('') + with self.assertRaises(TypeError): self.EST.tzname(5) + + def test_fromutc(self): + with self.assertRaises(ValueError): + timezone.utc.fromutc(self.DT) + for tz in [self.EST, self.ACDT, Eastern]: + utctime = self.DT.replace(tzinfo=tz) + local = tz.fromutc(utctime) + self.assertEquals(local - utctime, tz.utcoffset(local)) + self.assertEquals(local, + self.DT.replace(tzinfo=timezone.utc)) + + def test_comparison(self): + self.assertNotEqual(timezone(ZERO), timezone(HOUR)) + self.assertEqual(timezone(HOUR), timezone(HOUR)) + self.assertEqual(timezone(-5 * HOUR), timezone(-5 * HOUR, 'EST')) + with self.assertRaises(TypeError): timezone(ZERO) < timezone(ZERO) + self.assertIn(timezone(ZERO), {timezone(ZERO)}) + + def test_aware_datetime(self): + # test that timezone instances can be used by datetime + t = datetime(1, 1, 1) + for tz in [timezone.min, timezone.max, timezone.utc]: + self.assertEquals(tz.tzname(t), + t.replace(tzinfo=tz).tzname()) + self.assertEquals(tz.utcoffset(t), + t.replace(tzinfo=tz).utcoffset()) + self.assertEquals(tz.dst(t), + t.replace(tzinfo=tz).dst()) + ############################################################################# # Base clase for testing a particular aspect of timedelta, time, date and # datetime comparisons. @@ -2729,20 +2823,21 @@ # We don't know which time zone we're in, and don't have a tzinfo # class to represent it, so seeing whether a tz argument actually # does a conversion is tricky. - weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0) utc = FixedOffset(0, "utc", 0) - for dummy in range(3): - now = datetime.now(weirdtz) - self.assertTrue(now.tzinfo is weirdtz) - utcnow = datetime.utcnow().replace(tzinfo=utc) - now2 = utcnow.astimezone(weirdtz) - if abs(now - now2) < timedelta(seconds=30): - break - # Else the code is broken, or more than 30 seconds passed between - # calls; assuming the latter, just try again. - else: - # Three strikes and we're out. - self.fail("utcnow(), now(tz), or astimezone() may be broken") + for weirdtz in [FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0), + timezone(timedelta(hours=15, minutes=58), "weirdtz"),]: + for dummy in range(3): + now = datetime.now(weirdtz) + self.assertTrue(now.tzinfo is weirdtz) + utcnow = datetime.utcnow().replace(tzinfo=utc) + now2 = utcnow.astimezone(weirdtz) + if abs(now - now2) < timedelta(seconds=30): + break + # Else the code is broken, or more than 30 seconds passed between + # calls; assuming the latter, just try again. + else: + # Three strikes and we're out. + self.fail("utcnow(), now(tz), or astimezone() may be broken") def test_tzinfo_fromtimestamp(self): import time Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Mon Jun 14 16:15:50 2010 @@ -406,6 +406,7 @@ Kurt B. Kaiser Tamito Kajiyama Peter van Kampen +Rafe Kaplan Jacob Kaplan-Moss Lou Kates Hiroaki Kawai Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Jun 14 16:15:50 2010 @@ -1306,6 +1306,14 @@ Extension Modules ----------------- +- Issue #5094: The ``datetime`` module now has a simple concrete class + implementing ``datetime.tzinfo`` interface. Instances of the new + class, ``datetime.timezone``, return fixed name and UTC offset from + their ``tzname(dt)`` and ``utcoffset(dt)`` methods. The ``dst(dt)`` + method always returns ``None``. A class attribute, ``utc`` contains + an instance representing the UTC timezone. Original patch by Rafe + Kaplan. + - Issue #8973: Add __all__ to struct module; this ensures that help(struct) includes documentation for the struct.Struct class. Modified: python/branches/py3k/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k/Modules/datetimemodule.c (original) +++ python/branches/py3k/Modules/datetimemodule.c Mon Jun 14 16:15:50 2010 @@ -102,6 +102,7 @@ static PyTypeObject PyDateTime_DeltaType; static PyTypeObject PyDateTime_TimeType; static PyTypeObject PyDateTime_TZInfoType; +static PyTypeObject PyDateTime_TimeZoneType; /* --------------------------------------------------------------------------- * Math utilities. @@ -771,6 +772,52 @@ #define new_delta(d, s, us, normalize) \ new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType) + +typedef struct +{ + PyObject_HEAD + PyObject *offset; + PyObject *name; +} PyDateTime_TimeZone; + +/* Create new timezone instance checking offset range. This + function does not check the name argument. Caller must assure + that offset is a timedelta instance and name is either NULL + or a unicode object. */ +static PyObject * +new_timezone(PyObject *offset, PyObject *name) +{ + PyDateTime_TimeZone *self; + PyTypeObject *type = &PyDateTime_TimeZoneType; + + assert(offset != NULL); + assert(PyDelta_Check(offset)); + assert(name == NULL || PyUnicode_Check(name)); + + if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) { + PyErr_Format(PyExc_ValueError, "offset must be a timedelta" + " representing a whole number of minutes"); + return NULL; + } + if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) || + GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { + PyErr_Format(PyExc_ValueError, "offset must be a timedelta" + " strictly between -timedelta(hours=24) and" + " timedelta(hours=24)."); + return NULL; + } + + self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0)); + if (self == NULL) { + return NULL; + } + Py_INCREF(offset); + self->offset = offset; + Py_XINCREF(name); + self->name = name; + return (PyObject *)self; +} + /* --------------------------------------------------------------------------- * tzinfo helpers. */ @@ -3261,7 +3308,7 @@ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ tzinfo_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -3283,6 +3330,206 @@ 0, /* tp_free */ }; +static char *timezone_kws[] = {"offset", "name", NULL}; + +static PyObject * +timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *offset; + PyObject *name = NULL; + if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws, + &PyDateTime_DeltaType, &offset, + &PyUnicode_Type, &name)) + return new_timezone(offset, name); + + return NULL; +} + +static void +timezone_dealloc(PyDateTime_TimeZone *self) +{ + Py_CLEAR(self->offset); + Py_CLEAR(self->name); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject * +timezone_richcompare(PyDateTime_TimeZone *self, + PyDateTime_TimeZone *other, int op) +{ + if (op != Py_EQ && op != Py_NE) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + return delta_richcompare(self->offset, other->offset, op); +} + +static long +timezone_hash(PyDateTime_TimeZone *self) +{ + return delta_hash((PyDateTime_Delta *)self->offset); +} + +/* Check argument type passed to tzname, utcoffset, or dst methods. + Returns 0 for good argument. Returns -1 and sets exception info + otherwise. + */ +static int +_timezone_check_argument(PyObject *dt, const char *meth) +{ + if (dt == Py_None || PyDateTime_Check(dt)) + return 0; + PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance" + " or None, not %.200s", meth, Py_TYPE(dt)->tp_name); + return -1; +} + +static PyObject * +timezone_str(PyDateTime_TimeZone *self) +{ + char buf[10]; + int hours, minutes, seconds; + PyObject *offset; + char sign; + + if (self->name != NULL) { + Py_INCREF(self->name); + return self->name; + } + /* Offset is normalized, so it is negative if days < 0 */ + if (GET_TD_DAYS(self->offset) < 0) { + sign = '-'; + offset = delta_negative((PyDateTime_Delta *)self->offset); + if (offset == NULL) + return NULL; + } + else { + sign = '+'; + offset = self->offset; + Py_INCREF(offset); + } + /* Offset is not negative here. */ + seconds = GET_TD_SECONDS(offset); + Py_DECREF(offset); + minutes = divmod(seconds, 60, &seconds); + hours = divmod(minutes, 60, &minutes); + assert(seconds == 0); + /* XXX ignore sub-minute data, curently not allowed. */ + PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes); + + return PyUnicode_FromString(buf); +} + +static PyObject * +timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt) +{ + if (_timezone_check_argument(dt, "tzname") == -1) + return NULL; + + return timezone_str(self); +} + +static PyObject * +timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt) +{ + if (_timezone_check_argument(dt, "utcoffset") == -1) + return NULL; + + Py_INCREF(self->offset); + return self->offset; +} + +static PyObject * +timezone_dst(PyObject *self, PyObject *dt) +{ + if (_timezone_check_argument(dt, "dst") == -1) + return NULL; + + Py_RETURN_NONE; +} + +static PyObject * +add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta, + int factor); + +static PyObject * +timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt) +{ + if (! PyDateTime_Check(dt)) { + PyErr_SetString(PyExc_TypeError, + "fromutc: argument must be a datetime"); + return NULL; + } + if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) { + PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo " + "is not self"); + return NULL; + } + + return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1); +} + +static PyMethodDef timezone_methods[] = { + {"tzname", (PyCFunction)timezone_tzname, METH_O, + PyDoc_STR("If name is specified when timezone is created, returns the name." + " Otherwise returns offset as 'UTC(+|-)HHMM'.")}, + + {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O, + PyDoc_STR("Returns fixed offset. Ignores its argument.")}, + + {"dst", (PyCFunction)timezone_dst, METH_O, + PyDoc_STR("Returns None. Ignores its argument.")}, + + {"fromutc", (PyCFunction)timezone_fromutc, METH_O, + PyDoc_STR("datetime in UTC -> datetime in local time.")}, + + {NULL, NULL} +}; + +static char timezone_doc[] = +PyDoc_STR("Fixed offset from UTC implementation of tzinfo."); + +static PyTypeObject PyDateTime_TimeZoneType = { + PyVarObject_HEAD_INIT(NULL, 0) + "datetime.timezone", /* tp_name */ + sizeof(PyDateTime_TimeZone), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)timezone_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)timezone_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)timezone_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + timezone_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)timezone_richcompare,/* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + timezone_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyDateTime_TZInfoType, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + timezone_new, /* tp_new */ +}; + /* * PyDateTime_Time implementation. */ @@ -4971,6 +5218,7 @@ PyObject *m; /* a module object */ PyObject *d; /* its dict */ PyObject *x; + PyObject *delta; m = PyModule_Create(&datetimemodule); if (m == NULL) @@ -4986,6 +5234,8 @@ return NULL; if (PyType_Ready(&PyDateTime_TZInfoType) < 0) return NULL; + if (PyType_Ready(&PyDateTime_TimeZoneType) < 0) + return NULL; /* timedelta values */ d = PyDateTime_DeltaType.tp_dict; @@ -5059,6 +5309,36 @@ return NULL; Py_DECREF(x); + /* timezone values */ + d = PyDateTime_TimeZoneType.tp_dict; + + delta = new_delta(0, 0, 0, 0); + if (delta == NULL) + return NULL; + x = new_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0) + return NULL; + Py_DECREF(x); + + delta = new_delta(-1, 60, 0, 1); /* -23:59 */ + if (delta == NULL) + return NULL; + x = new_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) + return NULL; + Py_DECREF(x); + + delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */ + if (delta == NULL) + return NULL; + x = new_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) + return NULL; + Py_DECREF(x); + /* module initialization */ PyModule_AddIntConstant(m, "MINYEAR", MINYEAR); PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR); @@ -5079,6 +5359,9 @@ Py_INCREF(&PyDateTime_TZInfoType); PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); + Py_INCREF(&PyDateTime_TimeZoneType); + PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType); + x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL); if (x == NULL) return NULL; From python-checkins at python.org Mon Jun 14 17:58:39 2010 From: python-checkins at python.org (georg.brandl) Date: Mon, 14 Jun 2010 17:58:39 +0200 (CEST) Subject: [Python-checkins] r81984 - python/trunk/Doc/c-api/init.rst Message-ID: <20100614155839.A66BDEEDCA@mail.python.org> Author: georg.brandl Date: Mon Jun 14 17:58:39 2010 New Revision: 81984 Log: #8993: fix reference. Modified: python/trunk/Doc/c-api/init.rst Modified: python/trunk/Doc/c-api/init.rst ============================================================================== --- python/trunk/Doc/c-api/init.rst (original) +++ python/trunk/Doc/c-api/init.rst Mon Jun 14 17:58:39 2010 @@ -386,7 +386,7 @@ .. cfunction:: void PySys_SetArgv(int argc, char **argv) - This function works like :cfunc:`PySys_SetArgv` with *updatepath* set to 1. + This function works like :cfunc:`PySys_SetArgvEx` with *updatepath* set to 1. .. cfunction:: void Py_SetPythonHome(char *home) From python-checkins at python.org Mon Jun 14 19:32:04 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Mon, 14 Jun 2010 19:32:04 +0200 (CEST) Subject: [Python-checkins] r81988 - in python/branches/py3k/Lib: calendar.py test/test_calendar.py Message-ID: <20100614173204.20A9AEEE34@mail.python.org> Author: alexander.belopolsky Date: Mon Jun 14 19:32:03 2010 New Revision: 81988 Log: Issue 6280: Tests and simpler implementation for calendar.timegm Modified: python/branches/py3k/Lib/calendar.py python/branches/py3k/Lib/test/test_calendar.py Modified: python/branches/py3k/Lib/calendar.py ============================================================================== --- python/branches/py3k/Lib/calendar.py (original) +++ python/branches/py3k/Lib/calendar.py Mon Jun 14 19:32:03 2010 @@ -587,17 +587,12 @@ EPOCH = 1970 -_EPOCH_ORD = datetime.date(EPOCH, 1, 1).toordinal() - +_EPOCH_DATETIME = datetime.datetime(EPOCH, 1, 1) +_SECOND = datetime.timedelta(seconds=1) def timegm(tuple): """Unrelated but handy function to calculate Unix timestamp from GMT.""" - year, month, day, hour, minute, second = tuple[:6] - days = datetime.date(year, month, 1).toordinal() - _EPOCH_ORD + day - 1 - hours = days*24 + hour - minutes = hours*60 + minute - seconds = minutes*60 + second - return seconds + return (datetime.datetime(*tuple[:6]) - _EPOCH_DATETIME) // _SECOND def main(args): Modified: python/branches/py3k/Lib/test/test_calendar.py ============================================================================== --- python/branches/py3k/Lib/test/test_calendar.py (original) +++ python/branches/py3k/Lib/test/test_calendar.py Mon Jun 14 19:32:03 2010 @@ -2,7 +2,7 @@ import unittest from test import support - +import time result_2004_text = """ 2004 @@ -381,13 +381,21 @@ # A 31-day december starting on friday (2+7+7+7+7+1 days) self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1)) +class TimegmTestCase(unittest.TestCase): + TIMESTAMPS = [0, 10, 100, 1000, 10000, 100000, 1000000, + 1234567890, 1262304000, 1275785153,] + def test_timegm(self): + for secs in self.TIMESTAMPS: + tuple = time.gmtime(secs) + self.assertEqual(secs, calendar.timegm(tuple)) def test_main(): support.run_unittest( OutputTestCase, CalendarTestCase, MondayTestCase, - SundayTestCase + SundayTestCase, + TimegmTestCase, ) From python-checkins at python.org Mon Jun 14 20:33:19 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Mon, 14 Jun 2010 20:33:19 +0200 (CEST) Subject: [Python-checkins] r81989 - python/branches/py3k/Lib/calendar.py Message-ID: <20100614183319.B591EEEE5D@mail.python.org> Author: alexander.belopolsky Date: Mon Jun 14 20:33:19 2010 New Revision: 81989 Log: Undo r81988 code change leaving added test. Modified: python/branches/py3k/Lib/calendar.py Modified: python/branches/py3k/Lib/calendar.py ============================================================================== --- python/branches/py3k/Lib/calendar.py (original) +++ python/branches/py3k/Lib/calendar.py Mon Jun 14 20:33:19 2010 @@ -587,12 +587,17 @@ EPOCH = 1970 -_EPOCH_DATETIME = datetime.datetime(EPOCH, 1, 1) -_SECOND = datetime.timedelta(seconds=1) +_EPOCH_ORD = datetime.date(EPOCH, 1, 1).toordinal() + def timegm(tuple): """Unrelated but handy function to calculate Unix timestamp from GMT.""" - return (datetime.datetime(*tuple[:6]) - _EPOCH_DATETIME) // _SECOND + year, month, day, hour, minute, second = tuple[:6] + days = datetime.date(year, month, 1).toordinal() - _EPOCH_ORD + day - 1 + hours = days*24 + hour + minutes = hours*60 + minute + seconds = minutes*60 + second + return seconds def main(args): From python-checkins at python.org Tue Jun 15 00:22:54 2010 From: python-checkins at python.org (brett.cannon) Date: Tue, 15 Jun 2010 00:22:54 +0200 (CEST) Subject: [Python-checkins] r81990 - python/branches/py3k/Lib/test/regrtest.py Message-ID: <20100614222254.A4B8DEE9AA@mail.python.org> Author: brett.cannon Date: Tue Jun 15 00:22:54 2010 New Revision: 81990 Log: Switch the __import__ state check from using __builtins__ to builtins to be nicer to other VMs. Thanks to Philip Jenvey for the pointer. Modified: python/branches/py3k/Lib/test/regrtest.py Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Tue Jun 15 00:22:54 2010 @@ -152,6 +152,7 @@ option '-uall,-gui'. """ +import builtins import getopt import json import os @@ -859,15 +860,9 @@ sys.path_hooks[:] = saved_hooks[2] def get___import__(self): - if isinstance(__builtins__, dict): - return __builtins__['__import__'] - else: - return __builtins__.__import__ + return builtins.__import__ def restore___import__(self, import_): - if isinstance(__builtins__, dict): - __builtins__['__import__'] = import_ - else: - __builtins__.__import__ = import_ + builtins.__import__ = import_ def get_warnings_filters(self): return id(warnings.filters), warnings.filters, warnings.filters[:] From solipsis at pitrou.net Tue Jun 15 01:23:59 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 15 Jun 2010 01:23:59 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r81989): sum=0 Message-ID: <20100614232359.7EA961770A@ns6635.ovh.net> py3k results for svn r81989 (hg cset 7761497a32ef) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogmRxGk6', '-x'] From python-checkins at python.org Tue Jun 15 02:38:58 2010 From: python-checkins at python.org (andrew.kuchling) Date: Tue, 15 Jun 2010 02:38:58 +0200 (CEST) Subject: [Python-checkins] r81991 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: <20100615003858.E38BCEED80@mail.python.org> Author: andrew.kuchling Date: Tue Jun 15 02:38:58 2010 New Revision: 81991 Log: Add another bunch of 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 Tue Jun 15 02:38:58 2010 @@ -780,6 +780,12 @@ (Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.) +* The :keyword:`import` statement will no longer try a relative import + if an absolute import (e.g. ``from .os import sep``) fails. This + fixes a bug, but could possibly break certain :keyword:`import` + statements that were only working by accident. (Fixed by Meador Inge; + :issue:`7902`.) + * It's now possible for a subclass of the built-in :class:`unicode` type to override the :meth:`__unicode__` method. (Implemented by Victor Stinner; :issue:`1583863`.) @@ -1183,6 +1189,11 @@ will now ignore the name of the module containing the exception being tested. (Patch by Lennart Regebro; :issue:`7490`.) +* The :mod:`email` module's :class:`~email.message.Message` class will + now accept a Unicode-valued payload, automatically converting the + payload to the encoding specified by :attr:`output_charset`. + (Added by R. David Murray; :issue:`1368247`.) + * The :class:`~fractions.Fraction` class now accepts a single float or :class:`~decimal.Decimal` instance, or two rational numbers, as arguments to its constructor. (Implemented by Mark Dickinson; @@ -1425,6 +1436,11 @@ named pipes like a regular file by opening them for reading, and this would block indefinitely. (Fixed by Antoine Pitrou; :issue:`3002`.) +* The :mod:`signal` module no longer re-installs the signal handler + unless this is truly necessary, which fixes a bug that could make it + impossible to catch the EINTR signal robustly. (Fixed by + Charles-Francois Natali; :issue:`8354`.) + * New functions: in the :mod:`site` module, three new functions return various site- and user-specific paths. :func:`~site.getsitepackages` returns a list containing all From python-checkins at python.org Tue Jun 15 10:33:03 2010 From: python-checkins at python.org (mark.dickinson) Date: Tue, 15 Jun 2010 10:33:03 +0200 (CEST) Subject: [Python-checkins] r81992 - python/trunk/Doc/library/struct.rst Message-ID: <20100615083303.60242EE9DF@mail.python.org> Author: mark.dickinson Date: Tue Jun 15 10:33:03 2010 New Revision: 81992 Log: Issue #8469: Further clarifications and improvements to struct module documentation. Thanks Mads Kiilerich. Modified: python/trunk/Doc/library/struct.rst Modified: python/trunk/Doc/library/struct.rst ============================================================================== --- python/trunk/Doc/library/struct.rst (original) +++ python/trunk/Doc/library/struct.rst Tue Jun 15 10:33:03 2010 @@ -21,9 +21,9 @@ order to maintain proper alignment for the C types involved; similarly, alignment is taken into account when unpacking. This behavior is chosen so that the bytes of a packed struct correspond exactly to the layout in memory - of the corresponding C struct. To omit pad bytes, use `standard` size and - alignment instead of `native` size and alignment: see :ref:`struct-alignment` - for details. + of the corresponding C struct. To handle platform-independent data formats + or omit implicit pad bytes, use `standard` size and alignment instead of + `native` size and alignment: see :ref:`struct-alignment` for details. Functions and Exceptions ------------------------ @@ -100,19 +100,19 @@ the byte order, size and alignment of the packed data, according to the following table: -+-----------+------------------------+--------------------+ -| Character | Byte order | Size and alignment | -+===========+========================+====================+ -| ``@`` | native | native | -+-----------+------------------------+--------------------+ -| ``=`` | native | standard | -+-----------+------------------------+--------------------+ -| ``<`` | little-endian | standard | -+-----------+------------------------+--------------------+ -| ``>`` | big-endian | standard | -+-----------+------------------------+--------------------+ -| ``!`` | network (= big-endian) | standard | -+-----------+------------------------+--------------------+ ++-----------+------------------------+----------+-----------+ +| Character | Byte order | Size | Alignment | ++===========+========================+==========+===========+ +| ``@`` | native | native | native | ++-----------+------------------------+----------+-----------+ +| ``=`` | native | standard | none | ++-----------+------------------------+----------+-----------+ +| ``<`` | little-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``>`` | big-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``!`` | network (= big-endian) | standard | none | ++-----------+------------------------+----------+-----------+ If the first character is not one of these, ``'@'`` is assumed. @@ -125,11 +125,8 @@ Native size and alignment are determined using the C compiler's ``sizeof`` expression. This is always combined with native byte order. -Standard size and alignment are as follows: no alignment is required for any -type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and -:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 -bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating -point numbers, respectively. :ctype:`_Bool` is 1 byte. +Standard size depends only on the format character; see the table in +the :ref:`format-characters` section. Note the difference between ``'@'`` and ``'='``: both use native byte order, but the size and alignment of the latter is standardized. @@ -140,12 +137,6 @@ There is no way to indicate non-native byte order (force byte-swapping); use the appropriate choice of ``'<'`` or ``'>'``. -The ``'P'`` format character is only available for the native byte ordering -(selected as the default or with the ``'@'`` byte order character). The byte -order character ``'='`` chooses to use little- or big-endian ordering based on -the host system. The struct module does not interpret this as native ordering, -so the ``'P'`` format is not available. - Notes: (1) Padding is only automatically added between successive structure members. @@ -197,15 +188,15 @@ | ``Q`` | :ctype:`unsigned long | integer | 8 | \(2), \(3) | | | long` | | | | +--------+-------------------------+--------------------+----------------+------------+ -| ``f`` | :ctype:`float` | float | 4 | | +| ``f`` | :ctype:`float` | float | 4 | \(4) | +--------+-------------------------+--------------------+----------------+------------+ -| ``d`` | :ctype:`double` | float | 8 | | +| ``d`` | :ctype:`double` | float | 8 | \(4) | +--------+-------------------------+--------------------+----------------+------------+ | ``s`` | :ctype:`char[]` | string | | | +--------+-------------------------+--------------------+----------------+------------+ | ``p`` | :ctype:`char[]` | string | | | +--------+-------------------------+--------------------+----------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | \(3) | +| ``P`` | :ctype:`void \*` | integer | | \(5), \(3) | +--------+-------------------------+--------------------+----------------+------------+ Notes: @@ -240,6 +231,18 @@ :meth:`__int__` method to convert, and :exc:`DeprecationWarning` was raised only for float arguments. +(4) + For the ``'f'`` and ``'d'`` conversion codes, the packed representation uses + the IEEE 754 binary32 (for ``'f'``) or binary64 (for ``'d'``) format, + regardless of the floating-point format used by the platform. + +(5) + The ``'P'`` format character is only available for the native byte ordering + (selected as the default or with the ``'@'`` byte order character). The byte + order character ``'='`` chooses to use little- or big-endian ordering based + on the host system. The struct module does not interpret this as native + ordering, so the ``'P'`` format is not available. + A format character may be preceded by an integral repeat count. For example, the format string ``'4h'`` means exactly the same as ``'hhhh'``. From python-checkins at python.org Tue Jun 15 10:38:22 2010 From: python-checkins at python.org (mark.dickinson) Date: Tue, 15 Jun 2010 10:38:22 +0200 (CEST) Subject: [Python-checkins] r81993 - in python/branches/release26-maint: Doc/library/struct.rst Message-ID: <20100615083822.06B5AEEF03@mail.python.org> Author: mark.dickinson Date: Tue Jun 15 10:38:21 2010 New Revision: 81993 Log: Merged revisions 81992 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81992 | mark.dickinson | 2010-06-15 09:33:03 +0100 (Tue, 15 Jun 2010) | 3 lines Issue #8469: Further clarifications and improvements to struct module documentation. Thanks Mads Kiilerich. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/struct.rst Modified: python/branches/release26-maint/Doc/library/struct.rst ============================================================================== --- python/branches/release26-maint/Doc/library/struct.rst (original) +++ python/branches/release26-maint/Doc/library/struct.rst Tue Jun 15 10:38:21 2010 @@ -21,9 +21,9 @@ order to maintain proper alignment for the C types involved; similarly, alignment is taken into account when unpacking. This behavior is chosen so that the bytes of a packed struct correspond exactly to the layout in memory - of the corresponding C struct. To omit pad bytes, use `standard` size and - alignment instead of `native` size and alignment: see :ref:`struct-alignment` - for details. + of the corresponding C struct. To handle platform-independent data formats + or omit implicit pad bytes, use `standard` size and alignment instead of + `native` size and alignment: see :ref:`struct-alignment` for details. Functions and Exceptions ------------------------ @@ -100,19 +100,19 @@ the byte order, size and alignment of the packed data, according to the following table: -+-----------+------------------------+--------------------+ -| Character | Byte order | Size and alignment | -+===========+========================+====================+ -| ``@`` | native | native | -+-----------+------------------------+--------------------+ -| ``=`` | native | standard | -+-----------+------------------------+--------------------+ -| ``<`` | little-endian | standard | -+-----------+------------------------+--------------------+ -| ``>`` | big-endian | standard | -+-----------+------------------------+--------------------+ -| ``!`` | network (= big-endian) | standard | -+-----------+------------------------+--------------------+ ++-----------+------------------------+----------+-----------+ +| Character | Byte order | Size | Alignment | ++===========+========================+==========+===========+ +| ``@`` | native | native | native | ++-----------+------------------------+----------+-----------+ +| ``=`` | native | standard | none | ++-----------+------------------------+----------+-----------+ +| ``<`` | little-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``>`` | big-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``!`` | network (= big-endian) | standard | none | ++-----------+------------------------+----------+-----------+ If the first character is not one of these, ``'@'`` is assumed. @@ -125,11 +125,8 @@ Native size and alignment are determined using the C compiler's ``sizeof`` expression. This is always combined with native byte order. -Standard size and alignment are as follows: no alignment is required for any -type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and -:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 -bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating -point numbers, respectively. :ctype:`_Bool` is 1 byte. +Standard size depends only on the format character; see the table in +the :ref:`format-characters` section. Note the difference between ``'@'`` and ``'='``: both use native byte order, but the size and alignment of the latter is standardized. @@ -140,12 +137,6 @@ There is no way to indicate non-native byte order (force byte-swapping); use the appropriate choice of ``'<'`` or ``'>'``. -The ``'P'`` format character is only available for the native byte ordering -(selected as the default or with the ``'@'`` byte order character). The byte -order character ``'='`` chooses to use little- or big-endian ordering based on -the host system. The struct module does not interpret this as native ordering, -so the ``'P'`` format is not available. - Notes: (1) Padding is only automatically added between successive structure members. @@ -174,38 +165,38 @@ +--------+-------------------------+--------------------+----------------+------------+ | ``c`` | :ctype:`char` | string of length 1 | 1 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``b`` | :ctype:`signed char` | integer | 1 | \(3) | +| ``b`` | :ctype:`signed char` | integer | 1 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``B`` | :ctype:`unsigned char` | integer | 1 | \(3) | +| ``B`` | :ctype:`unsigned char` | integer | 1 | | +--------+-------------------------+--------------------+----------------+------------+ | ``?`` | :ctype:`_Bool` | bool | 1 | \(1) | +--------+-------------------------+--------------------+----------------+------------+ -| ``h`` | :ctype:`short` | integer | 2 | \(3) | +| ``h`` | :ctype:`short` | integer | 2 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``H`` | :ctype:`unsigned short` | integer | 2 | \(3) | +| ``H`` | :ctype:`unsigned short` | integer | 2 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``i`` | :ctype:`int` | integer | 4 | \(3) | +| ``i`` | :ctype:`int` | integer | 4 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``I`` | :ctype:`unsigned int` | integer | 4 | \(3) | +| ``I`` | :ctype:`unsigned int` | integer | 4 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``l`` | :ctype:`long` | integer | 4 | \(3) | +| ``l`` | :ctype:`long` | integer | 4 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``L`` | :ctype:`unsigned long` | integer | 4 | \(3) | +| ``L`` | :ctype:`unsigned long` | integer | 4 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``q`` | :ctype:`long long` | integer | 8 | \(2), \(3) | +| ``q`` | :ctype:`long long` | integer | 8 | \(2) | +--------+-------------------------+--------------------+----------------+------------+ -| ``Q`` | :ctype:`unsigned long | integer | 8 | \(2), \(3) | +| ``Q`` | :ctype:`unsigned long | integer | 8 | \(2) | | | long` | | | | +--------+-------------------------+--------------------+----------------+------------+ -| ``f`` | :ctype:`float` | float | 4 | | +| ``f`` | :ctype:`float` | float | 4 | \(3) | +--------+-------------------------+--------------------+----------------+------------+ -| ``d`` | :ctype:`double` | float | 8 | | +| ``d`` | :ctype:`double` | float | 8 | \(3) | +--------+-------------------------+--------------------+----------------+------------+ | ``s`` | :ctype:`char[]` | string | | | +--------+-------------------------+--------------------+----------------+------------+ | ``p`` | :ctype:`char[]` | string | | | +--------+-------------------------+--------------------+----------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | \(3) | +| ``P`` | :ctype:`void \*` | integer | | \(4) | +--------+-------------------------+--------------------+----------------+------------+ Notes: @@ -224,6 +215,19 @@ .. versionadded:: 2.2 +(3) + For the ``'f'`` and ``'d'`` conversion codes, the packed representation uses + the IEEE 754 binary32 (for ``'f'``) or binary64 (for ``'d'``) format, + regardless of the floating-point format used by the platform. + +(4) + The ``'P'`` format character is only available for the native byte ordering + (selected as the default or with the ``'@'`` byte order character). The byte + order character ``'='`` chooses to use little- or big-endian ordering based + on the host system. The struct module does not interpret this as native + ordering, so the ``'P'`` format is not available. + + A format character may be preceded by an integral repeat count. For example, the format string ``'4h'`` means exactly the same as ``'hhhh'``. From python-checkins at python.org Tue Jun 15 10:42:37 2010 From: python-checkins at python.org (mark.dickinson) Date: Tue, 15 Jun 2010 10:42:37 +0200 (CEST) Subject: [Python-checkins] r81994 - in python/branches/py3k: Doc/library/struct.rst Message-ID: <20100615084237.EB2CDEEEFE@mail.python.org> Author: mark.dickinson Date: Tue Jun 15 10:42:37 2010 New Revision: 81994 Log: Merged revisions 81992 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81992 | mark.dickinson | 2010-06-15 09:33:03 +0100 (Tue, 15 Jun 2010) | 3 lines Issue #8469: Further clarifications and improvements to struct module documentation. Thanks Mads Kiilerich. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/struct.rst Modified: python/branches/py3k/Doc/library/struct.rst ============================================================================== --- python/branches/py3k/Doc/library/struct.rst (original) +++ python/branches/py3k/Doc/library/struct.rst Tue Jun 15 10:42:37 2010 @@ -20,9 +20,9 @@ order to maintain proper alignment for the C types involved; similarly, alignment is taken into account when unpacking. This behavior is chosen so that the bytes of a packed struct correspond exactly to the layout in memory - of the corresponding C struct. To omit pad bytes, use `standard` size and - alignment instead of `native` size and alignment: see :ref:`struct-alignment` - for details. + of the corresponding C struct. To handle platform-independent data formats + or omit implicit pad bytes, use `standard` size and alignment instead of + `native` size and alignment: see :ref:`struct-alignment` for details. Functions and Exceptions ------------------------ @@ -95,19 +95,19 @@ the byte order, size and alignment of the packed data, according to the following table: -+-----------+------------------------+--------------------+ -| Character | Byte order | Size and alignment | -+===========+========================+====================+ -| ``@`` | native | native | -+-----------+------------------------+--------------------+ -| ``=`` | native | standard | -+-----------+------------------------+--------------------+ -| ``<`` | little-endian | standard | -+-----------+------------------------+--------------------+ -| ``>`` | big-endian | standard | -+-----------+------------------------+--------------------+ -| ``!`` | network (= big-endian) | standard | -+-----------+------------------------+--------------------+ ++-----------+------------------------+----------+-----------+ +| Character | Byte order | Size | Alignment | ++===========+========================+==========+===========+ +| ``@`` | native | native | native | ++-----------+------------------------+----------+-----------+ +| ``=`` | native | standard | none | ++-----------+------------------------+----------+-----------+ +| ``<`` | little-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``>`` | big-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``!`` | network (= big-endian) | standard | none | ++-----------+------------------------+----------+-----------+ If the first character is not one of these, ``'@'`` is assumed. @@ -120,11 +120,8 @@ Native size and alignment are determined using the C compiler's ``sizeof`` expression. This is always combined with native byte order. -Standard size and alignment are as follows: no alignment is required for any -type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and -:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 -bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating -point numbers, respectively. :ctype:`_Bool` is 1 byte. +Standard size depends only on the format character; see the table in +the :ref:`format-characters` section. Note the difference between ``'@'`` and ``'='``: both use native byte order, but the size and alignment of the latter is standardized. @@ -135,12 +132,6 @@ There is no way to indicate non-native byte order (force byte-swapping); use the appropriate choice of ``'<'`` or ``'>'``. -The ``'P'`` format character is only available for the native byte ordering -(selected as the default or with the ``'@'`` byte order character). The byte -order character ``'='`` chooses to use little- or big-endian ordering based on -the host system. The struct module does not interpret this as native ordering, -so the ``'P'`` format is not available. - Notes: (1) Padding is only automatically added between successive structure members. @@ -192,15 +183,15 @@ | ``Q`` | :ctype:`unsigned long | integer | 8 | \(3), \(4) | | | long` | | | | +--------+-------------------------+--------------------+----------------+------------+ -| ``f`` | :ctype:`float` | float | 4 | | +| ``f`` | :ctype:`float` | float | 4 | \(5) | +--------+-------------------------+--------------------+----------------+------------+ -| ``d`` | :ctype:`double` | float | 8 | | +| ``d`` | :ctype:`double` | float | 8 | \(5) | +--------+-------------------------+--------------------+----------------+------------+ | ``s`` | :ctype:`char[]` | bytes | | \(1) | +--------+-------------------------+--------------------+----------------+------------+ | ``p`` | :ctype:`char[]` | bytes | | \(1) | +--------+-------------------------+--------------------+----------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | | +| ``P`` | :ctype:`void \*` | integer | | \(6) | +--------+-------------------------+--------------------+----------------+------------+ Notes: @@ -228,6 +219,18 @@ .. versionchanged:: 3.2 Use of the :meth:`__index__` method for non-integers is new in 3.2. +(5) + For the ``'f'`` and ``'d'`` conversion codes, the packed representation uses + the IEEE 754 binary32 (for ``'f'``) or binary64 (for ``'d'``) format, + regardless of the floating-point format used by the platform. + +(6) + The ``'P'`` format character is only available for the native byte ordering + (selected as the default or with the ``'@'`` byte order character). The byte + order character ``'='`` chooses to use little- or big-endian ordering based + on the host system. The struct module does not interpret this as native + ordering, so the ``'P'`` format is not available. + A format character may be preceded by an integral repeat count. For example, the format string ``'4h'`` means exactly the same as ``'hhhh'``. From python-checkins at python.org Tue Jun 15 10:45:06 2010 From: python-checkins at python.org (mark.dickinson) Date: Tue, 15 Jun 2010 10:45:06 +0200 (CEST) Subject: [Python-checkins] r81995 - in python/branches/release31-maint: Doc/library/struct.rst Message-ID: <20100615084506.79BC9F6979@mail.python.org> Author: mark.dickinson Date: Tue Jun 15 10:45:06 2010 New Revision: 81995 Log: Merged revisions 81994 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81994 | mark.dickinson | 2010-06-15 09:42:37 +0100 (Tue, 15 Jun 2010) | 10 lines Merged revisions 81992 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81992 | mark.dickinson | 2010-06-15 09:33:03 +0100 (Tue, 15 Jun 2010) | 3 lines Issue #8469: Further clarifications and improvements to struct module documentation. Thanks Mads Kiilerich. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/struct.rst Modified: python/branches/release31-maint/Doc/library/struct.rst ============================================================================== --- python/branches/release31-maint/Doc/library/struct.rst (original) +++ python/branches/release31-maint/Doc/library/struct.rst Tue Jun 15 10:45:06 2010 @@ -20,9 +20,9 @@ order to maintain proper alignment for the C types involved; similarly, alignment is taken into account when unpacking. This behavior is chosen so that the bytes of a packed struct correspond exactly to the layout in memory - of the corresponding C struct. To omit pad bytes, use `standard` size and - alignment instead of `native` size and alignment: see :ref:`struct-alignment` - for details. + of the corresponding C struct. To handle platform-independent data formats + or omit implicit pad bytes, use `standard` size and alignment instead of + `native` size and alignment: see :ref:`struct-alignment` for details. Functions and Exceptions ------------------------ @@ -95,19 +95,19 @@ the byte order, size and alignment of the packed data, according to the following table: -+-----------+------------------------+--------------------+ -| Character | Byte order | Size and alignment | -+===========+========================+====================+ -| ``@`` | native | native | -+-----------+------------------------+--------------------+ -| ``=`` | native | standard | -+-----------+------------------------+--------------------+ -| ``<`` | little-endian | standard | -+-----------+------------------------+--------------------+ -| ``>`` | big-endian | standard | -+-----------+------------------------+--------------------+ -| ``!`` | network (= big-endian) | standard | -+-----------+------------------------+--------------------+ ++-----------+------------------------+----------+-----------+ +| Character | Byte order | Size | Alignment | ++===========+========================+==========+===========+ +| ``@`` | native | native | native | ++-----------+------------------------+----------+-----------+ +| ``=`` | native | standard | none | ++-----------+------------------------+----------+-----------+ +| ``<`` | little-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``>`` | big-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``!`` | network (= big-endian) | standard | none | ++-----------+------------------------+----------+-----------+ If the first character is not one of these, ``'@'`` is assumed. @@ -120,11 +120,8 @@ Native size and alignment are determined using the C compiler's ``sizeof`` expression. This is always combined with native byte order. -Standard size and alignment are as follows: no alignment is required for any -type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and -:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 -bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating -point numbers, respectively. :ctype:`_Bool` is 1 byte. +Standard size depends only on the format character; see the table in +the :ref:`format-characters` section. Note the difference between ``'@'`` and ``'='``: both use native byte order, but the size and alignment of the latter is standardized. @@ -135,12 +132,6 @@ There is no way to indicate non-native byte order (force byte-swapping); use the appropriate choice of ``'<'`` or ``'>'``. -The ``'P'`` format character is only available for the native byte ordering -(selected as the default or with the ``'@'`` byte order character). The byte -order character ``'='`` chooses to use little- or big-endian ordering based on -the host system. The struct module does not interpret this as native ordering, -so the ``'P'`` format is not available. - Notes: (1) Padding is only automatically added between successive structure members. @@ -192,15 +183,15 @@ | ``Q`` | :ctype:`unsigned long | integer | 8 | \(3), \(4) | | | long` | | | | +--------+-------------------------+--------------------+----------------+------------+ -| ``f`` | :ctype:`float` | float | 4 | | +| ``f`` | :ctype:`float` | float | 4 | \(5) | +--------+-------------------------+--------------------+----------------+------------+ -| ``d`` | :ctype:`double` | float | 8 | | +| ``d`` | :ctype:`double` | float | 8 | \(5) | +--------+-------------------------+--------------------+----------------+------------+ | ``s`` | :ctype:`char[]` | bytes | | \(1) | +--------+-------------------------+--------------------+----------------+------------+ | ``p`` | :ctype:`char[]` | bytes | | \(1) | +--------+-------------------------+--------------------+----------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | | +| ``P`` | :ctype:`void \*` | integer | | \(6) | +--------+-------------------------+--------------------+----------------+------------+ Notes: @@ -220,6 +211,27 @@ the platform C compiler supports C :ctype:`long long`, or, on Windows, :ctype:`__int64`. They are always available in standard modes. +(4) + When attempting to pack a non-integer using any of the integer conversion + codes, if the non-integer has a :meth:`__index__` method then that method is + called to convert the argument to an integer before packing. + + .. versionchanged:: 3.2 + Use of the :meth:`__index__` method for non-integers is new in 3.2. + +(5) + For the ``'f'`` and ``'d'`` conversion codes, the packed representation uses + the IEEE 754 binary32 (for ``'f'``) or binary64 (for ``'d'``) format, + regardless of the floating-point format used by the platform. + +(6) + The ``'P'`` format character is only available for the native byte ordering + (selected as the default or with the ``'@'`` byte order character). The byte + order character ``'='`` chooses to use little- or big-endian ordering based + on the host system. The struct module does not interpret this as native + ordering, so the ``'P'`` format is not available. + + A format character may be preceded by an integral repeat count. For example, the format string ``'4h'`` means exactly the same as ``'hhhh'``. From python-checkins at python.org Tue Jun 15 10:49:30 2010 From: python-checkins at python.org (mark.dickinson) Date: Tue, 15 Jun 2010 10:49:30 +0200 (CEST) Subject: [Python-checkins] r81996 - python/branches/release31-maint/Doc/library/struct.rst Message-ID: <20100615084930.8202BF698C@mail.python.org> Author: mark.dickinson Date: Tue Jun 15 10:49:30 2010 New Revision: 81996 Log: Fix notes in format character table. Modified: python/branches/release31-maint/Doc/library/struct.rst Modified: python/branches/release31-maint/Doc/library/struct.rst ============================================================================== --- python/branches/release31-maint/Doc/library/struct.rst (original) +++ python/branches/release31-maint/Doc/library/struct.rst Tue Jun 15 10:49:30 2010 @@ -160,38 +160,38 @@ +--------+-------------------------+--------------------+----------------+------------+ | ``c`` | :ctype:`char` | bytes of length 1 | 1 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``b`` | :ctype:`signed char` | integer | 1 | \(1),\(4) | +| ``b`` | :ctype:`signed char` | integer | 1 | \(1) | +--------+-------------------------+--------------------+----------------+------------+ -| ``B`` | :ctype:`unsigned char` | integer | 1 | \(4) | +| ``B`` | :ctype:`unsigned char` | integer | 1 | | +--------+-------------------------+--------------------+----------------+------------+ | ``?`` | :ctype:`_Bool` | bool | 1 | \(2) | +--------+-------------------------+--------------------+----------------+------------+ -| ``h`` | :ctype:`short` | integer | 2 | \(4) | +| ``h`` | :ctype:`short` | integer | 2 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``H`` | :ctype:`unsigned short` | integer | 2 | \(4) | +| ``H`` | :ctype:`unsigned short` | integer | 2 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``i`` | :ctype:`int` | integer | 4 | \(4) | +| ``i`` | :ctype:`int` | integer | 4 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``I`` | :ctype:`unsigned int` | integer | 4 | \(4) | +| ``I`` | :ctype:`unsigned int` | integer | 4 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``l`` | :ctype:`long` | integer | 4 | \(4) | +| ``l`` | :ctype:`long` | integer | 4 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``L`` | :ctype:`unsigned long` | integer | 4 | \(4) | +| ``L`` | :ctype:`unsigned long` | integer | 4 | | +--------+-------------------------+--------------------+----------------+------------+ -| ``q`` | :ctype:`long long` | integer | 8 | \(3), \(4) | +| ``q`` | :ctype:`long long` | integer | 8 | \(3) | +--------+-------------------------+--------------------+----------------+------------+ -| ``Q`` | :ctype:`unsigned long | integer | 8 | \(3), \(4) | +| ``Q`` | :ctype:`unsigned long | integer | 8 | \(3) | | | long` | | | | +--------+-------------------------+--------------------+----------------+------------+ -| ``f`` | :ctype:`float` | float | 4 | \(5) | +| ``f`` | :ctype:`float` | float | 4 | \(4) | +--------+-------------------------+--------------------+----------------+------------+ -| ``d`` | :ctype:`double` | float | 8 | \(5) | +| ``d`` | :ctype:`double` | float | 8 | \(4) | +--------+-------------------------+--------------------+----------------+------------+ | ``s`` | :ctype:`char[]` | bytes | | \(1) | +--------+-------------------------+--------------------+----------------+------------+ | ``p`` | :ctype:`char[]` | bytes | | \(1) | +--------+-------------------------+--------------------+----------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | \(6) | +| ``P`` | :ctype:`void \*` | integer | | \(5) | +--------+-------------------------+--------------------+----------------+------------+ Notes: @@ -212,19 +212,11 @@ :ctype:`__int64`. They are always available in standard modes. (4) - When attempting to pack a non-integer using any of the integer conversion - codes, if the non-integer has a :meth:`__index__` method then that method is - called to convert the argument to an integer before packing. - - .. versionchanged:: 3.2 - Use of the :meth:`__index__` method for non-integers is new in 3.2. - -(5) For the ``'f'`` and ``'d'`` conversion codes, the packed representation uses the IEEE 754 binary32 (for ``'f'``) or binary64 (for ``'d'``) format, regardless of the floating-point format used by the platform. -(6) +(5) The ``'P'`` format character is only available for the native byte ordering (selected as the default or with the ``'@'`` byte order character). The byte order character ``'='`` chooses to use little- or big-endian ordering based From python-checkins at python.org Tue Jun 15 15:11:01 2010 From: python-checkins at python.org (stefan.krah) Date: Tue, 15 Jun 2010 15:11:01 +0200 (CEST) Subject: [Python-checkins] r81997 - python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Message-ID: <20100615131101.E53D6EEA36@mail.python.org> Author: stefan.krah Date: Tue Jun 15 15:11:01 2010 New Revision: 81997 Log: 1) context.setflags() and context.settraps() incorrectly returned -1. 2) Remove superfluous casts. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Modified: python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Tue Jun 15 15:11:01 2010 @@ -211,7 +211,7 @@ ssize_t n, j; if (!PyList_Check(list)) { - PyErr_Format(PyExc_TypeError, "argument must be a signal list"); + PyErr_SetString(PyExc_TypeError, "argument must be a signal list"); return UINT32_MAX; } @@ -274,7 +274,7 @@ overflow = 0; x = PyLong_AsLongAndOverflow(v, &overflow); if (overflow != 0 || x < 0 || x > (long)MPD_Max_status) { - PyErr_Format(PyExc_ValueError, "invalid flag value"); + PyErr_SetString(PyExc_ValueError, "invalid flag value"); return UINT32_MAX; } @@ -803,7 +803,7 @@ } static PyObject * -context_unsafe_setprec(PyObject *self, PyObject *value, void *closure UNUSED) +context_unsafe_setprec(PyObject *self, PyObject *value) { mpd_context_t *ctx = CtxAddr(self); @@ -815,7 +815,7 @@ } static PyObject * -context_unsafe_setemin(PyObject *self, PyObject *value, void *closure UNUSED) +context_unsafe_setemin(PyObject *self, PyObject *value) { mpd_context_t *ctx = CtxAddr(self); @@ -827,7 +827,7 @@ } static PyObject * -context_unsafe_setemax(PyObject *self, PyObject *value, void *closure UNUSED) +context_unsafe_setemax(PyObject *self, PyObject *value) { mpd_context_t *ctx = CtxAddr(self); @@ -1386,6 +1386,24 @@ ); } +static PyObject * +PyDec_SetStatusFromList(PyObject *self, PyObject *value) +{ + if (context_setstatus_list(self, value) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +PyDec_SetTrapsFromList(PyObject *self, PyObject *value) +{ + if (context_settraps_list(self, value) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + static PyGetSetDef context_getsets [] = { @@ -4723,15 +4741,15 @@ { "shift", _DecCtx_mpd_qshift, METH_VARARGS, doc_ctx_shift }, /* Set context values */ - { "setflags", (PyCFunction)context_setstatus_list, METH_O, doc_ctx_setflags }, - { "settraps", (PyCFunction)context_settraps_list, METH_O, doc_ctx_settraps }, + { "setflags", PyDec_SetStatusFromList, METH_O, doc_ctx_setflags }, + { "settraps", PyDec_SetTrapsFromList, METH_O, doc_ctx_settraps }, { "clear_flags", context_clear_flags, METH_NOARGS, doc_ctx_clear_flags }, { "clear_traps", context_clear_traps, METH_NOARGS, doc_ctx_clear_traps }, /* Unsafe set functions with no range checks */ - { "unsafe_setprec", (PyCFunction)context_unsafe_setprec, METH_O, NULL }, - { "unsafe_setemin", (PyCFunction)context_unsafe_setemin, METH_O, NULL }, - { "unsafe_setemax", (PyCFunction)context_unsafe_setemax, METH_O, NULL }, + { "unsafe_setprec", context_unsafe_setprec, METH_O, NULL }, + { "unsafe_setemin", context_unsafe_setemin, METH_O, NULL }, + { "unsafe_setemax", context_unsafe_setemax, METH_O, NULL }, /* Miscellaneous */ { "__copy__", (PyCFunction)context_copy, METH_NOARGS, NULL }, From python-checkins at python.org Tue Jun 15 18:05:20 2010 From: python-checkins at python.org (ronald.oussoren) Date: Tue, 15 Jun 2010 18:05:20 +0200 (CEST) Subject: [Python-checkins] r81999 - in python/branches/py3k/Lib: distutils/command/install.py sysconfig.py Message-ID: <20100615160520.8D207EE992@mail.python.org> Author: ronald.oussoren Date: Tue Jun 15 18:05:20 2010 New Revision: 81999 Log: Fix for issue #8577: without this patch test_distutils will fail when builddir != srcdir (that is, when you run configure in a directory that is not the top of the source tree). Modified: python/branches/py3k/Lib/distutils/command/install.py python/branches/py3k/Lib/sysconfig.py Modified: python/branches/py3k/Lib/distutils/command/install.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/install.py (original) +++ python/branches/py3k/Lib/distutils/command/install.py Tue Jun 15 18:05:20 2010 @@ -302,8 +302,8 @@ # about needing recursive variable expansion (shudder). py_version = sys.version.split()[0] - prefix, exec_prefix, srcdir = get_config_vars('prefix', 'exec_prefix', - 'srcdir') + prefix, exec_prefix, srcdir, projectbase = get_config_vars('prefix', 'exec_prefix', + 'srcdir', 'projectbase') self.config_vars = {'dist_name': self.distribution.get_name(), 'dist_version': self.distribution.get_version(), @@ -316,6 +316,7 @@ 'sys_exec_prefix': exec_prefix, 'exec_prefix': exec_prefix, 'srcdir': srcdir, + 'projectbase': projectbase, } self.config_vars['userbase'] = self.install_userbase Modified: python/branches/py3k/Lib/sysconfig.py ============================================================================== --- python/branches/py3k/Lib/sysconfig.py (original) +++ python/branches/py3k/Lib/sysconfig.py Tue Jun 15 18:05:20 2010 @@ -123,8 +123,8 @@ if _PYTHON_BUILD: for scheme in ('posix_prefix', 'posix_home'): - _INSTALL_SCHEMES[scheme]['include'] = '{projectbase}/Include' - _INSTALL_SCHEMES[scheme]['platinclude'] = '{srcdir}' + _INSTALL_SCHEMES[scheme]['include'] = '{srcdir}/Include' + _INSTALL_SCHEMES[scheme]['platinclude'] = '{projectbase}/.' def _subst_vars(s, local_vars): try: From python-checkins at python.org Tue Jun 15 19:00:21 2010 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 15 Jun 2010 19:00:21 +0200 (CEST) Subject: [Python-checkins] r82000 - python/branches/py3k/Doc/c-api/file.rst Message-ID: <20100615170021.EFFE5EE992@mail.python.org> Author: antoine.pitrou Date: Tue Jun 15 19:00:21 2010 New Revision: 82000 Log: Fixes to the PyFile_FromFd() doc, by Renato Cunha. Modified: python/branches/py3k/Doc/c-api/file.rst Modified: python/branches/py3k/Doc/c-api/file.rst ============================================================================== --- python/branches/py3k/Doc/c-api/file.rst (original) +++ python/branches/py3k/Doc/c-api/file.rst Tue Jun 15 19:00:21 2010 @@ -13,12 +13,13 @@ the :mod:`io` module. -.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *newline, int closefd) +.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd) Create a new :ctype:`PyFileObject` from the file descriptor of an already - opened file *fd*. The arguments *name*, *encoding* and *newline* can be - *NULL* to use the defaults; *buffering* can be *-1* to use the default. - Return *NULL* on failure. + opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline* + can be *NULL* to use the defaults; *buffering* can be *-1* to use the + default. Return *NULL* on failure. For a more comprehensive description of + the arguments, please refer to the :func:`io.open` function documentation. .. warning:: From python-checkins at python.org Tue Jun 15 19:30:16 2010 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 15 Jun 2010 19:30:16 +0200 (CEST) Subject: [Python-checkins] r82001 - python/branches/py3k/Doc/c-api/file.rst Message-ID: <20100615173016.E50ECEE9F2@mail.python.org> Author: antoine.pitrou Date: Tue Jun 15 19:30:16 2010 New Revision: 82001 Log: Further refinements to the C file API. Modified: python/branches/py3k/Doc/c-api/file.rst Modified: python/branches/py3k/Doc/c-api/file.rst ============================================================================== --- python/branches/py3k/Doc/c-api/file.rst (original) +++ python/branches/py3k/Doc/c-api/file.rst Tue Jun 15 19:30:16 2010 @@ -7,25 +7,29 @@ .. index:: object: file -Python's built-in file objects are implemented entirely on the :ctype:`FILE\*` -support from the C standard library. This is an implementation detail and may -change in future releases of Python. The ``PyFile_`` APIs are a wrapper over -the :mod:`io` module. +These APIs are a minimal emulation of the Python 2 C API for built-in file +objects, which used to rely on the buffered I/O (:ctype:`FILE\*`) support +from the C standard library. In Python 3, files and streams use the new +:mod:`io` module, which defines several layers over the low-level unbuffered +I/O of the operating system. The functions described below are +convenience C wrappers over these new APIs, and meant mostly for internal +error reporting in the interpreter; third-party code is advised to access +the :mod:`io` APIs instead. .. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd) - Create a new :ctype:`PyFileObject` from the file descriptor of an already - opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline* + Create a Python file object from the file descriptor of an already + opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline* can be *NULL* to use the defaults; *buffering* can be *-1* to use the - default. Return *NULL* on failure. For a more comprehensive description of + default. Return *NULL* on failure. For a more comprehensive description of the arguments, please refer to the :func:`io.open` function documentation. .. warning:: - Take care when you are mixing streams and descriptors! For more - information, see `the GNU C Library docs - `_. + Since Python streams have their own buffering layer, mixing them with + OS-level file descriptors can produce various issues (such as unexpected + ordering of data). .. cfunction:: int PyObject_AsFileDescriptor(PyObject *p) From python-checkins at python.org Tue Jun 15 19:31:05 2010 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 15 Jun 2010 19:31:05 +0200 (CEST) Subject: [Python-checkins] r82002 - in python/branches/release31-maint: Doc/c-api/file.rst Message-ID: <20100615173105.4F4A4EEA0F@mail.python.org> Author: antoine.pitrou Date: Tue Jun 15 19:31:05 2010 New Revision: 82002 Log: Merged revisions 82000-82001 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r82000 | antoine.pitrou | 2010-06-15 19:00:21 +0200 (mar., 15 juin 2010) | 3 lines Fixes to the PyFile_FromFd() doc, by Renato Cunha. ........ r82001 | antoine.pitrou | 2010-06-15 19:30:16 +0200 (mar., 15 juin 2010) | 3 lines Further refinements to the C file API. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/c-api/file.rst Modified: python/branches/release31-maint/Doc/c-api/file.rst ============================================================================== --- python/branches/release31-maint/Doc/c-api/file.rst (original) +++ python/branches/release31-maint/Doc/c-api/file.rst Tue Jun 15 19:31:05 2010 @@ -7,24 +7,29 @@ .. index:: object: file -Python's built-in file objects are implemented entirely on the :ctype:`FILE\*` -support from the C standard library. This is an implementation detail and may -change in future releases of Python. The ``PyFile_`` APIs are a wrapper over -the :mod:`io` module. - - -.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *newline, int closefd) - - Create a new :ctype:`PyFileObject` from the file descriptor of an already - opened file *fd*. The arguments *name*, *encoding* and *newline* can be - *NULL* to use the defaults; *buffering* can be *-1* to use the default. - Return *NULL* on failure. +These APIs are a minimal emulation of the Python 2 C API for built-in file +objects, which used to rely on the buffered I/O (:ctype:`FILE\*`) support +from the C standard library. In Python 3, files and streams use the new +:mod:`io` module, which defines several layers over the low-level unbuffered +I/O of the operating system. The functions described below are +convenience C wrappers over these new APIs, and meant mostly for internal +error reporting in the interpreter; third-party code is advised to access +the :mod:`io` APIs instead. + + +.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd) + + Create a Python file object from the file descriptor of an already + opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline* + can be *NULL* to use the defaults; *buffering* can be *-1* to use the + default. Return *NULL* on failure. For a more comprehensive description of + the arguments, please refer to the :func:`io.open` function documentation. .. warning:: - Take care when you are mixing streams and descriptors! For more - information, see `the GNU C Library docs - `_. + Since Python streams have their own buffering layer, mixing them with + OS-level file descriptors can produce various issues (such as unexpected + ordering of data). .. cfunction:: int PyObject_AsFileDescriptor(PyObject *p) From python-checkins at python.org Tue Jun 15 20:40:23 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Tue, 15 Jun 2010 20:40:23 +0200 (CEST) Subject: [Python-checkins] r82003 - python/branches/py3k/Lib/test/test_datetime.py Message-ID: <20100615184023.86822EE9B4@mail.python.org> Author: alexander.belopolsky Date: Tue Jun 15 20:40:23 2010 New Revision: 82003 Log: Minor changes to the choice of assert methods Modified: 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 Jun 15 20:40:23 2010 @@ -148,13 +148,13 @@ def test_class_members(self): limit = timedelta(hours=23, minutes=59) - self.assertEquals(timezone.utc.utcoffset(None), ZERO) - self.assertEquals(timezone.min.utcoffset(None), -limit) - self.assertEquals(timezone.max.utcoffset(None), limit) + self.assertEqual(timezone.utc.utcoffset(None), ZERO) + self.assertEqual(timezone.min.utcoffset(None), -limit) + self.assertEqual(timezone.max.utcoffset(None), limit) def test_constructor(self): - self.assertEquals(timezone.utc, timezone(timedelta(0))) + self.assertEqual(timezone.utc, timezone(timedelta(0))) # invalid offsets for invalid in [timedelta(microseconds=1), timedelta(1, 1), timedelta(seconds=1), timedelta(1), -timedelta(1)]: @@ -167,32 +167,32 @@ with self.assertRaises(TypeError): timezone(ZERO, 42) def test_inheritance(self): - self.assertTrue(isinstance(timezone.utc, tzinfo)) - self.assertTrue(isinstance(self.EST, tzinfo)) + self.assertIsInstance(timezone.utc, tzinfo) + self.assertIsInstance(self.EST, tzinfo) def test_utcoffset(self): dummy = self.DT for h in [0, 1.5, 12]: offset = h * HOUR - self.assertEquals(offset, timezone(offset).utcoffset(dummy)) - self.assertEquals(-offset, timezone(-offset).utcoffset(dummy)) + self.assertEqual(offset, timezone(offset).utcoffset(dummy)) + self.assertEqual(-offset, timezone(-offset).utcoffset(dummy)) with self.assertRaises(TypeError): self.EST.utcoffset('') with self.assertRaises(TypeError): self.EST.utcoffset(5) def test_dst(self): - self.assertEquals(None, timezone.utc.dst(self.DT)) + self.assertEqual(None, timezone.utc.dst(self.DT)) with self.assertRaises(TypeError): self.EST.dst('') with self.assertRaises(TypeError): self.EST.dst(5) def test_tzname(self): - self.assertEquals('UTC+00:00', timezone(ZERO).tzname(None)) - self.assertEquals('UTC-05:00', timezone(-5 * HOUR).tzname(None)) - self.assertEquals('UTC+09:30', timezone(9.5 * HOUR).tzname(None)) - self.assertEquals('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None)) - self.assertEquals('XYZ', timezone(-5 * HOUR, 'XYZ').tzname(None)) + self.assertEqual('UTC+00:00', timezone(ZERO).tzname(None)) + self.assertEqual('UTC-05:00', timezone(-5 * HOUR).tzname(None)) + self.assertEqual('UTC+09:30', timezone(9.5 * HOUR).tzname(None)) + self.assertEqual('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None)) + self.assertEqual('XYZ', timezone(-5 * HOUR, 'XYZ').tzname(None)) with self.assertRaises(TypeError): self.EST.tzname('') with self.assertRaises(TypeError): self.EST.tzname(5) @@ -203,9 +203,9 @@ for tz in [self.EST, self.ACDT, Eastern]: utctime = self.DT.replace(tzinfo=tz) local = tz.fromutc(utctime) - self.assertEquals(local - utctime, tz.utcoffset(local)) - self.assertEquals(local, - self.DT.replace(tzinfo=timezone.utc)) + self.assertEqual(local - utctime, tz.utcoffset(local)) + self.assertEqual(local, + self.DT.replace(tzinfo=timezone.utc)) def test_comparison(self): self.assertNotEqual(timezone(ZERO), timezone(HOUR)) @@ -218,12 +218,12 @@ # test that timezone instances can be used by datetime t = datetime(1, 1, 1) for tz in [timezone.min, timezone.max, timezone.utc]: - self.assertEquals(tz.tzname(t), - t.replace(tzinfo=tz).tzname()) - self.assertEquals(tz.utcoffset(t), - t.replace(tzinfo=tz).utcoffset()) - self.assertEquals(tz.dst(t), - t.replace(tzinfo=tz).dst()) + self.assertEqual(tz.tzname(t), + t.replace(tzinfo=tz).tzname()) + self.assertEqual(tz.utcoffset(t), + t.replace(tzinfo=tz).utcoffset()) + self.assertEqual(tz.dst(t), + t.replace(tzinfo=tz).dst()) ############################################################################# # Base clase for testing a particular aspect of timedelta, time, date and @@ -1681,8 +1681,8 @@ def test_microsecond_rounding(self): # Test whether fromtimestamp "rounds up" floats that are less # than one microsecond smaller than an integer. - self.assertEquals(self.theclass.fromtimestamp(0.9999999), - self.theclass.fromtimestamp(1)) + self.assertEqual(self.theclass.fromtimestamp(0.9999999), + self.theclass.fromtimestamp(1)) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, @@ -1710,7 +1710,7 @@ @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_utcfromtimestamp(self): d = self.theclass.utcfromtimestamp(-1.05) - self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) + self.assertEqual(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) def test_utcnow(self): import time From python-checkins at python.org Tue Jun 15 21:24:52 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Tue, 15 Jun 2010 21:24:52 +0200 (CEST) Subject: [Python-checkins] r82004 - in python/branches/py3k: Doc/library/datetime.rst Modules/datetimemodule.c Message-ID: <20100615192452.D0B65EE9B4@mail.python.org> Author: alexander.belopolsky Date: Tue Jun 15 21:24:52 2010 New Revision: 82004 Log: Issue 5094: minor documentation fixes Modified: python/branches/py3k/Doc/library/datetime.rst python/branches/py3k/Modules/datetimemodule.c Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Tue Jun 15 21:24:52 2010 @@ -1351,7 +1351,7 @@ :mod:`datetime` objects. If in doubt, simply implement all of them. -.. method:: tzinfo.utcoffset(self, dt) +.. method:: tzinfo.utcoffset(dt) Return offset of local time from UTC, in minutes east of UTC. If local time is west of UTC, this should be negative. Note that this is intended to be the @@ -1373,7 +1373,7 @@ :exc:`NotImplementedError`. -.. method:: tzinfo.dst(self, dt) +.. method:: tzinfo.dst(dt) Return the daylight saving time (DST) adjustment, in minutes east of UTC, or ``None`` if DST information isn't known. Return ``timedelta(0)`` if DST is not @@ -1421,7 +1421,7 @@ The default implementation of :meth:`dst` raises :exc:`NotImplementedError`. -.. method:: tzinfo.tzname(self, dt) +.. method:: tzinfo.tzname(dt) Return the time zone name corresponding to the :class:`datetime` object *dt*, as a string. Nothing about string names is defined by the :mod:`datetime` module, @@ -1457,7 +1457,7 @@ There is one more :class:`tzinfo` method that a subclass may wish to override: -.. method:: tzinfo.fromutc(self, dt) +.. method:: tzinfo.fromutc(dt) This is called from the default :class:`datetime.astimezone()` implementation. When called from that, ``dt.tzinfo`` is *self*, and *dt*'s date and time members @@ -1553,46 +1553,46 @@ .. class:: timezone(offset[, name]) - The ``offset`` argument must be specified as a :class:`timedelta` + The *offset* argument must be specified as a :class:`timedelta` object representing the difference between the local time and UTC. It must - be within the range [``-timedelta(hours=23, minutes=59), - ``timedelta(hours=23, minutes=59)``] and represent whole number of minutes, + be strictly between ``-timedelta(hours=24)`` and + ``timedelta(hours=24)`` and represent a whole number of minutes, otherwise :exc:`ValueError` is raised. - The ``name`` argument is optional. If specified it must be a string that - used as the value returned by the ``tzname(dt)`` method. Otherwise, + The *name* argument is optional. If specified it must be a string that + is used as the value returned by the ``tzname(dt)`` method. Otherwise, ``tzname(dt)`` returns a string 'UTCsHH:MM', where s is the sign of - ``offset``, HH and MM are two digits of ``offset.hours`` and + *offset*, HH and MM are two digits of ``offset.hours`` and ``offset.minutes`` respectively. -.. method:: timezone.utcoffset(self, dt) +.. method:: timezone.utcoffset(dt) - Returns the fixed value specified when the :class:`timezone` instance is - constructed. The ``dt`` argument is ignored. The return value is a + Return the fixed value specified when the :class:`timezone` instance is + constructed. The *dt* argument is ignored. The return value is a :class:`timedelta` instance equal to the difference between the local time and UTC. -.. method:: timezone.tzname(self, dt) +.. method:: timezone.tzname(dt) - Returns the fixed value specified when the :class:`timezone` instance is + Return the fixed value specified when the :class:`timezone` instance is constructed or a string 'UTCsHH:MM', where s is the sign of - ``offset``, HH and MM are two digits of ``offset.hours`` and - ``offset.minutes`` respectively. The ``dt`` argument is ignored. + *offset*, HH and MM are two digits of ``offset.hours`` and + ``offset.minutes`` respectively. -.. method:: timezone.dst(self, dt) +.. method:: timezone.dst(dt) Always returns ``None``. -.. method:: timezone.fromutc(self, dt) +.. method:: timezone.fromutc(dt) - Returns ``dt + offset``. The ``dt`` argument must be aware with ``tzinfo`` - set to ``self``. + Return ``dt + offset``. The *dt* argument must be an aware + :class:`datetime` instance, with ``tzinfo`` set to ``self``. Class attributes: .. attribute:: timezone.utc - The UTC timezone, ``timezone(0, 'UTC')``. + The UTC timezone, ``timezone(timedelta(0))``. .. _strftime-strptime-behavior: Modified: python/branches/py3k/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k/Modules/datetimemodule.c (original) +++ python/branches/py3k/Modules/datetimemodule.c Tue Jun 15 21:24:52 2010 @@ -3472,13 +3472,13 @@ static PyMethodDef timezone_methods[] = { {"tzname", (PyCFunction)timezone_tzname, METH_O, PyDoc_STR("If name is specified when timezone is created, returns the name." - " Otherwise returns offset as 'UTC(+|-)HHMM'.")}, + " Otherwise returns offset as 'UTC(+|-)HH:MM'.")}, {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O, - PyDoc_STR("Returns fixed offset. Ignores its argument.")}, + PyDoc_STR("Return fixed offset.")}, {"dst", (PyCFunction)timezone_dst, METH_O, - PyDoc_STR("Returns None. Ignores its argument.")}, + PyDoc_STR("Return None.")}, {"fromutc", (PyCFunction)timezone_fromutc, METH_O, PyDoc_STR("datetime in UTC -> datetime in local time.")}, From nnorwitz at gmail.com Tue Jun 15 22:32:10 2010 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 15 Jun 2010 16:32:10 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20100615203210.GA7833@kbk-i386-bb.psfb.org> 346 tests OK. 1 test failed: test_subprocess 37 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gdb test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 7 skips unexpected on linux2: test_epoll test_gdb test_ioctl test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly == CPython 2.7rc1+ (trunk:82004M, Jun 15 2010, 16:03:39) [GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)] == Linux-2.6.9-gentoo-r1-i686-AMD_Athlon-tm-_XP_3000+-with-gentoo-1.4.16 little-endian == /tmp/test_python_25951 test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_argparse test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn fetching http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml ... 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_dictcomps test_dictviews test_difflib test_dircache test_dis test_distutils [20673 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdb test_gdb skipped -- gdb versions before 7.0 didn't support python embedding Saw: GNU gdb 6.2.1 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-pc-linux-gnu". test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [16678 refs] [16678 refs] [16678 refs] [26966 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization fetching http://www.unicode.org/Public/5.2.0/ucd/NormalizationTest.txt ... test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os [16678 refs] [16678 refs] test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- only NT+ and systems with Unicode-friendly filesystem encoding test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [18074 refs] [18074 refs] test_plistlib test_poll test_popen [16683 refs] [16683 refs] [16683 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 [21890 refs] [21890 refs] [21890 refs] [21890 refs] [21890 refs] [21889 refs] [21889 refs] test_pyexpat test_queue test_quopri [19507 refs] [19507 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_setcomps test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [16678 refs] [16678 refs] [16678 refs] [16678 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_strtod test_struct test_structmembers test_structseq test_subprocess [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16893 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] . [16678 refs] [16678 refs] this bit of output is from a test of stdout in a different process ... [16678 refs] [16678 refs] [16893 refs] [16678 refs] [16678 refs] [16678 refs] p.send_signal(2,) succeeded after 2 attempts [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16893 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] [16678 refs] . [16678 refs] [16678 refs] this bit of output is from a test of stdout in a different process ... [16678 refs] [16678 refs] [16893 refs] test test_subprocess failed -- multiple errors occurred; run in verbose mode for details Re-running test 'test_subprocess' in verbose mode test_call_kwargs (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_call_seq (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_check_call_nonzero (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_check_call_zero (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_check_output (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_check_output_nonzero (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_check_output_stderr (test.test_subprocess.ProcessTestCase) ... ERROR test_check_output_stdout_arg (test.test_subprocess.ProcessTestCase) ... ERROR test_communicate (test.test_subprocess.ProcessTestCase) ... ERROR test_communicate_pipe_buf (test.test_subprocess.ProcessTestCase) ... ERROR test_communicate_pipe_fd_leak (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_communicate_returns (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_communicate_stderr (test.test_subprocess.ProcessTestCase) ... ERROR test_communicate_stdin (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_communicate_stdout (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_cwd (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_env (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_executable_with_cwd (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_executable_without_cwd (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_invalid_bufsize (test.test_subprocess.ProcessTestCase) ... ERROR test_leaking_fds_on_error (test.test_subprocess.ProcessTestCase) ... ERROR test_list2cmdline (test.test_subprocess.ProcessTestCase) ... ERROR test_no_leaking (test.test_subprocess.ProcessTestCase) ... ERROR test_poll (test.test_subprocess.ProcessTestCase) ... [16893 refs] ERROR test_stderr_filedes (test.test_subprocess.ProcessTestCase) ... ERROR test_stderr_fileobj (test.test_subprocess.ProcessTestCase) ... ERROR test_stderr_none (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_stderr_pipe (test.test_subprocess.ProcessTestCase) ... ERROR test_stdin_filedes (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_stdin_fileobj (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_stdin_none (test.test_subprocess.ProcessTestCase) ... ERROR test_stdin_pipe (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_stdout_filedes (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_stdout_filedes_of_stdout (test.test_subprocess.ProcessTestCase) ... . [16678 refs] ERROR test_stdout_fileobj (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_stdout_none (test.test_subprocess.ProcessTestCase) ... this bit of output is from a test of stdout in a different process ... ERROR test_stdout_pipe (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_stdout_stderr_file (test.test_subprocess.ProcessTestCase) ... ERROR test_stdout_stderr_pipe (test.test_subprocess.ProcessTestCase) ... ERROR test_universal_newlines (test.test_subprocess.ProcessTestCase) ... [16678 refs] ERROR test_universal_newlines_communicate (test.test_subprocess.ProcessTestCase) ... ERROR test_wait (test.test_subprocess.ProcessTestCase) ... [16893 refs] ERROR test_writes_before_communicate (test.test_subprocess.ProcessTestCase) ... ERROR test_args_string (test.test_subprocess.POSIXProcessTestCase) ... [16678 refs] ERROR test_call_string (test.test_subprocess.POSIXProcessTestCase) ... [16678 refs] ERROR test_exceptions (test.test_subprocess.POSIXProcessTestCase) ... ERROR test_invalid_args (test.test_subprocess.POSIXProcessTestCase) ... ERROR test_kill (test.test_subprocess.POSIXProcessTestCase) ... ERROR test_preexec (test.test_subprocess.POSIXProcessTestCase) ... [16678 refs] ERROR test_run_abort (test.test_subprocess.POSIXProcessTestCase) ... ERROR test_send_signal (test.test_subprocess.POSIXProcessTestCase) ... ERROR test_shell_sequence (test.test_subprocess.POSIXProcessTestCase) ... ERROR test_shell_string (test.test_subprocess.POSIXProcessTestCase) ... ERROR test_terminate (test.test_subprocess.POSIXProcessTestCase) ... ERROR test_call_string (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_close_fds (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_creationflags (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_invalid_args (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_kill (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_send_signal (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_shell_sequence (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_shell_string (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_startupinfo (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_terminate (test.test_subprocess.Win32ProcessTestCase) ... skipped 'Windows specific tests' test_call_kwargs (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_call_seq (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_check_call_nonzero (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_check_call_zero (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_check_output (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_check_output_nonzero (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_check_output_stderr (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_check_output_stdout_arg (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_communicate (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_communicate_pipe_buf (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_communicate_pipe_fd_leak (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_communicate_returns (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_communicate_stderr (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_communicate_stdin (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_communicate_stdout (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_cwd (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_env (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_executable_with_cwd (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_executable_without_cwd (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_invalid_bufsize (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_leaking_fds_on_error (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_list2cmdline (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_no_leaking (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_poll (test.test_subprocess.ProcessTestCaseNoPoll) ... [16893 refs] ERROR test_stderr_filedes (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_stderr_fileobj (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_stderr_none (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_stderr_pipe (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_stdin_filedes (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_stdin_fileobj (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_stdin_none (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_stdin_pipe (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_stdout_filedes (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_stdout_filedes_of_stdout (test.test_subprocess.ProcessTestCaseNoPoll) ... . [16678 refs] ERROR test_stdout_fileobj (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_stdout_none (test.test_subprocess.ProcessTestCaseNoPoll) ... this bit of output is from a test of stdout in a different process ... ERROR test_stdout_pipe (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_stdout_stderr_file (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_stdout_stderr_pipe (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_universal_newlines (test.test_subprocess.ProcessTestCaseNoPoll) ... [16678 refs] ERROR test_universal_newlines_communicate (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_wait (test.test_subprocess.ProcessTestCaseNoPoll) ... [16893 refs] ERROR test_writes_before_communicate (test.test_subprocess.ProcessTestCaseNoPoll) ... ERROR test_eintr_retry_call (test.test_subprocess.HelperFunctionTests) ... ok ====================================================================== ERROR: test_call_kwargs (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_call_seq (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_call_nonzero (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_call_zero (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_output (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_output_nonzero (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_output_stderr (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_output_stdout_arg (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_pipe_buf (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_pipe_fd_leak (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_returns (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_stderr (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_stdin (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_stdout (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_cwd (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_env (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_executable_with_cwd (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_executable_without_cwd (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_invalid_bufsize (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_leaking_fds_on_error (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_list2cmdline (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_no_leaking (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_poll (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stderr_filedes (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stderr_fileobj (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stderr_none (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stderr_pipe (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdin_filedes (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdin_fileobj (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdin_none (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdin_pipe (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_filedes (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_filedes_of_stdout (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_fileobj (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_none (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_pipe (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_stderr_file (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_stderr_pipe (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_universal_newlines (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_universal_newlines_communicate (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_wait (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_writes_before_communicate (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_args_string (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_call_string (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_exceptions (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_invalid_args (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_kill (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_preexec (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_run_abort (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_send_signal (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_shell_sequence (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_shell_string (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_terminate (test.test_subprocess.POSIXProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_call_kwargs (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_call_seq (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_call_nonzero (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_call_zero (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_output (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_output_nonzero (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_output_stderr (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_check_output_stdout_arg (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_pipe_buf (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_pipe_fd_leak (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_returns (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_stderr (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_stdin (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_communicate_stdout (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_cwd (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_env (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_executable_with_cwd (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_executable_without_cwd (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_invalid_bufsize (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_leaking_fds_on_error (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_list2cmdline (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_no_leaking (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_poll (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stderr_filedes (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stderr_fileobj (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stderr_none (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stderr_pipe (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdin_filedes (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdin_fileobj (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdin_none (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdin_pipe (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_filedes (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_filedes_of_stdout (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_fileobj (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_none (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_pipe (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_stderr_file (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_stdout_stderr_pipe (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_universal_newlines (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_universal_newlines_communicate (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_wait (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ====================================================================== ERROR: test_writes_before_communicate (test.test_subprocess.ProcessTestCaseNoPoll) ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 802, in tearDown ProcessTestCase.tearDown(self) File "/tmp/python-test/local/lib/python2.7/test/test_subprocess.py", line 46, in tearDown self.assertFalse(subprocess._active, "subprocess._active not empty") AssertionError: subprocess._active not empty ---------------------------------------------------------------------- Ran 108 tests in 76.124s FAILED (errors=97, skipped=10) test test_subprocess failed -- multiple errors occurred test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [16678 refs] [16678 refs] [16678 refs] [16907 refs] [16701 refs] test_sysconfig [16678 refs] [16678 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [16678 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [19978 refs] [21247 refs] [21061 refs] [21061 refs] [21061 refs] [21061 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 test_wait3 test_wait4 test_warnings [16709 refs] [16709 refs] [16702 refs] [16709 refs] [16709 refs] [16702 refs] test_wave test_weakref test_weakset test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 346 tests OK. 1 test failed: test_subprocess 37 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gdb test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 7 skips unexpected on linux2: test_epoll test_gdb test_ioctl test_multiprocessing test_tk test_ttk_guionly test_ttk_textonly [967331 refs] From python-checkins at python.org Tue Jun 15 23:19:50 2010 From: python-checkins at python.org (ronald.oussoren) Date: Tue, 15 Jun 2010 23:19:50 +0200 (CEST) Subject: [Python-checkins] r82005 - python/branches/py3k/Lib/sysconfig.py Message-ID: <20100615211950.8E9ECEEA37@mail.python.org> Author: ronald.oussoren Date: Tue Jun 15 23:19:50 2010 New Revision: 82005 Log: Fix for buildbot failure in r81999. Modified: python/branches/py3k/Lib/sysconfig.py Modified: python/branches/py3k/Lib/sysconfig.py ============================================================================== --- python/branches/py3k/Lib/sysconfig.py (original) +++ python/branches/py3k/Lib/sysconfig.py Tue Jun 15 23:19:50 2010 @@ -432,6 +432,8 @@ if 'srcdir' not in _CONFIG_VARS: _CONFIG_VARS['srcdir'] = _PROJECT_BASE + else: + _CONFIG_VARS['srcdir'] = realpath(_CONFIG_VARS['srcdir']) # Convert srcdir into an absolute path if it appears necessary. From python-checkins at python.org Wed Jun 16 00:18:54 2010 From: python-checkins at python.org (stefan.krah) Date: Wed, 16 Jun 2010 00:18:54 +0200 (CEST) Subject: [Python-checkins] r82006 - python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Message-ID: <20100615221854.8BBA1EEA12@mail.python.org> Author: stefan.krah Date: Wed Jun 16 00:18:54 2010 New Revision: 82006 Log: Fix typo that did not affect the module. The library should also be safe on the vast majority of platforms. Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c ============================================================================== --- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c (original) +++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Wed Jun 16 00:18:54 2010 @@ -1150,7 +1150,7 @@ uint8_t sign = MPD_POS; if (a < 0) { - if (a == INT64_MAX) { + if (a == INT64_MIN) { u = (uint64_t)INT64_MAX + (-(INT64_MIN+INT64_MAX)); } else { From python-checkins at python.org Wed Jun 16 01:21:18 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 01:21:18 +0200 (CEST) Subject: [Python-checkins] r82007 - in python/branches/release26-maint: Doc/library/doctest.rst Message-ID: <20100615232118.74051EEA30@mail.python.org> Author: r.david.murray Date: Wed Jun 16 01:21:18 2010 New Revision: 82007 Log: Merged revisions 81634 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81634 | r.david.murray | 2010-05-31 21:42:41 -0400 (Mon, 31 May 2010) | 2 lines #7583: clarify discussion of hard tab expansion in doctests. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/doctest.rst 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 Wed Jun 16 01:21:18 2010 @@ -299,15 +299,8 @@ How are Docstring Examples Recognized? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In most cases a copy-and-paste of an interactive console session works fine, but -doctest isn't trying to do an exact emulation of any specific Python shell. All -hard tab characters are expanded to spaces, using 8-column tab stops. If you -don't believe tabs should mean that, too bad: don't use hard tabs, or write -your own :class:`DocTestParser` class. - -.. versionchanged:: 2.4 - Expanding tabs to spaces is new; previous versions tried to preserve hard tabs, - with confusing results. +In most cases a copy-and-paste of an interactive console session works fine, +but doctest isn't trying to do an exact emulation of any specific Python shell. :: @@ -342,6 +335,21 @@ ```` was added; there was no way to use expected output containing empty lines in previous versions. +* All hard tab characters are expanded to spaces, using 8-column tab stops. + Tabs in output generated by the tested code are not modified. Because any + hard tabs in the sample output *are* expanded, this means that if the code + output includes hard tabs, the only way the doctest can pass is if the + :const:`NORMALIZE_WHITESPACE` option or directive is in effect. + Alternatively, the test can be rewritten to capture the output and compare it + to an expected value as part of the test. This handling of tabs in the + source was arrived at through trial and error, and has proven to be the least + error prone way of handling them. It is possible to use a different + algorithm for handling tabs by writing a custom :class:`DocTestParser` class. + + .. versionchanged:: 2.4 + Expanding tabs to spaces is new; previous versions tried to preserve hard tabs, + with confusing results. + * Output to stdout is captured, but not output to stderr (exception tracebacks are captured via a different means). @@ -1856,4 +1864,3 @@ .. [#] Examples containing both expected output and an exception are not supported. Trying to guess where one ends and the other begins is too error-prone, and that also makes for a confusing test. - From solipsis at pitrou.net Wed Jun 16 01:23:19 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 16 Jun 2010 01:23:19 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r82004): sum=0 Message-ID: <20100615232319.3CD6A1771C@ns6635.ovh.net> py3k results for svn r82004 (hg cset 89523ef75153) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogGswS8O', '-x'] From python-checkins at python.org Wed Jun 16 01:46:40 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 01:46:40 +0200 (CEST) Subject: [Python-checkins] r82008 - in python/branches/py3k: Doc/library/doctest.rst Message-ID: <20100615234640.DD076EE9A8@mail.python.org> Author: r.david.murray Date: Wed Jun 16 01:46:40 2010 New Revision: 82008 Log: Merged revisions 81634 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81634 | r.david.murray | 2010-05-31 21:42:41 -0400 (Mon, 31 May 2010) | 2 lines #7583: clarify discussion of hard tab expansion in doctests. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/doctest.rst Modified: python/branches/py3k/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k/Doc/library/doctest.rst (original) +++ python/branches/py3k/Doc/library/doctest.rst Wed Jun 16 01:46:40 2010 @@ -282,11 +282,8 @@ How are Docstring Examples Recognized? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In most cases a copy-and-paste of an interactive console session works fine, but -doctest isn't trying to do an exact emulation of any specific Python shell. All -hard tab characters are expanded to spaces, using 8-column tab stops. If you -don't believe tabs should mean that, too bad: don't use hard tabs, or write -your own :class:`DocTestParser` class. +In most cases a copy-and-paste of an interactive console session works fine, +but doctest isn't trying to do an exact emulation of any specific Python shell. :: @@ -317,6 +314,21 @@ blank line, put ```` in your doctest example each place a blank line is expected. +* All hard tab characters are expanded to spaces, using 8-column tab stops. + Tabs in output generated by the tested code are not modified. Because any + hard tabs in the sample output *are* expanded, this means that if the code + output includes hard tabs, the only way the doctest can pass is if the + :const:`NORMALIZE_WHITESPACE` option or directive is in effect. + Alternatively, the test can be rewritten to capture the output and compare it + to an expected value as part of the test. This handling of tabs in the + source was arrived at through trial and error, and has proven to be the least + error prone way of handling them. It is possible to use a different + algorithm for handling tabs by writing a custom :class:`DocTestParser` class. + + .. versionchanged:: 2.4 + Expanding tabs to spaces is new; previous versions tried to preserve hard tabs, + with confusing results. + * Output to stdout is captured, but not output to stderr (exception tracebacks are captured via a different means). @@ -1778,4 +1790,3 @@ .. [#] Examples containing both expected output and an exception are not supported. Trying to guess where one ends and the other begins is too error-prone, and that also makes for a confusing test. - From python-checkins at python.org Wed Jun 16 02:37:16 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 02:37:16 +0200 (CEST) Subject: [Python-checkins] r82009 - in python/branches/release31-maint: Doc/library/doctest.rst Message-ID: <20100616003716.5A0EDEEB67@mail.python.org> Author: r.david.murray Date: Wed Jun 16 02:37:16 2010 New Revision: 82009 Log: Merged revisions 82008 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r82008 | r.david.murray | 2010-06-15 19:46:40 -0400 (Tue, 15 Jun 2010) | 9 lines Merged revisions 81634 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81634 | r.david.murray | 2010-05-31 21:42:41 -0400 (Mon, 31 May 2010) | 2 lines #7583: clarify discussion of hard tab expansion in doctests. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/doctest.rst 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 Wed Jun 16 02:37:16 2010 @@ -282,11 +282,8 @@ How are Docstring Examples Recognized? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In most cases a copy-and-paste of an interactive console session works fine, but -doctest isn't trying to do an exact emulation of any specific Python shell. All -hard tab characters are expanded to spaces, using 8-column tab stops. If you -don't believe tabs should mean that, too bad: don't use hard tabs, or write -your own :class:`DocTestParser` class. +In most cases a copy-and-paste of an interactive console session works fine, +but doctest isn't trying to do an exact emulation of any specific Python shell. :: @@ -317,6 +314,21 @@ blank line, put ```` in your doctest example each place a blank line is expected. +* All hard tab characters are expanded to spaces, using 8-column tab stops. + Tabs in output generated by the tested code are not modified. Because any + hard tabs in the sample output *are* expanded, this means that if the code + output includes hard tabs, the only way the doctest can pass is if the + :const:`NORMALIZE_WHITESPACE` option or directive is in effect. + Alternatively, the test can be rewritten to capture the output and compare it + to an expected value as part of the test. This handling of tabs in the + source was arrived at through trial and error, and has proven to be the least + error prone way of handling them. It is possible to use a different + algorithm for handling tabs by writing a custom :class:`DocTestParser` class. + + .. versionchanged:: 2.4 + Expanding tabs to spaces is new; previous versions tried to preserve hard tabs, + with confusing results. + * Output to stdout is captured, but not output to stderr (exception tracebacks are captured via a different means). @@ -1760,4 +1772,3 @@ .. [#] Examples containing both expected output and an exception are not supported. Trying to guess where one ends and the other begins is too error-prone, and that also makes for a confusing test. - From python-checkins at python.org Wed Jun 16 02:57:25 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 02:57:25 +0200 (CEST) Subject: [Python-checkins] r82010 - in python/branches/release26-maint: Lib/email/feedparser.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20100616005725.EA8D7EEA63@mail.python.org> Author: r.david.murray Date: Wed Jun 16 02:57:25 2010 New Revision: 82010 Log: Merged revisions 81675 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81675 | r.david.murray | 2010-06-03 11:43:20 -0400 (Thu, 03 Jun 2010) | 10 lines #5610: use \Z not $ so we don't eat extra chars when body part ends with \r\n. If a body part ended with \r\n, feedparser, using '$' to terminate its search for the newline, would match on the \r\n, and think that it needed to strip two characters in order to account for the line end before the boundary. That made it chop one too many characters off the end of the body part. Using \Z makes the match correct. Patch and test by Tony Nelson. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/email/feedparser.py python/branches/release26-maint/Lib/email/test/test_email.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/email/feedparser.py ============================================================================== --- python/branches/release26-maint/Lib/email/feedparser.py (original) +++ python/branches/release26-maint/Lib/email/feedparser.py Wed Jun 16 02:57:25 2010 @@ -28,7 +28,7 @@ NLCRE = re.compile('\r\n|\r|\n') NLCRE_bol = re.compile('(\r\n|\r|\n)') -NLCRE_eol = re.compile('(\r\n|\r|\n)$') +NLCRE_eol = re.compile('(\r\n|\r|\n)\Z') NLCRE_crack = re.compile('(\r\n|\r|\n)') # RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character # except controls, SP, and ":". Modified: python/branches/release26-maint/Lib/email/test/test_email.py ============================================================================== --- python/branches/release26-maint/Lib/email/test/test_email.py (original) +++ python/branches/release26-maint/Lib/email/test/test_email.py Wed Jun 16 02:57:25 2010 @@ -2590,6 +2590,24 @@ eq(headers, ['A', 'B', 'CC']) eq(msg.get_payload(), 'body') + def test_CRLFLF_at_end_of_part(self): + # issue 5610: feedparser should not eat two chars from body part ending + # with "\r\n\n". + m = ( + "From: foo at bar.com\n" + "To: baz\n" + "Mime-Version: 1.0\n" + "Content-Type: multipart/mixed; boundary=BOUNDARY\n" + "\n" + "--BOUNDARY\n" + "Content-Type: text/plain\n" + "\n" + "body ending with CRLF newline\r\n" + "\n" + "--BOUNDARY--\n" + ) + msg = email.message_from_string(m) + self.assertTrue(msg.get_payload(0).get_payload().endswith('\r\n')) class TestBase64(unittest.TestCase): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Jun 16 02:57:25 2010 @@ -71,6 +71,9 @@ Library ------- +- Issue #5610: feedparser no longer eats extra characters at the end of + a body part if the body part ends with a \r\n. + - Issue #8924: logging: Improved error handling for Unicode in exception text. - Fix codecs.escape_encode to return the correct consumed size. From python-checkins at python.org Wed Jun 16 04:19:41 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 04:19:41 +0200 (CEST) Subject: [Python-checkins] r82011 - in python/branches/py3k: Lib/email/feedparser.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20100616021941.0BD18EE9BB@mail.python.org> Author: r.david.murray Date: Wed Jun 16 04:19:40 2010 New Revision: 82011 Log: Merged revisions 81675 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81675 | r.david.murray | 2010-06-03 11:43:20 -0400 (Thu, 03 Jun 2010) | 10 lines #5610: use \Z not $ so we don't eat extra chars when body part ends with \r\n. If a body part ended with \r\n, feedparser, using '$' to terminate its search for the newline, would match on the \r\n, and think that it needed to strip two characters in order to account for the line end before the boundary. That made it chop one too many characters off the end of the body part. Using \Z makes the match correct. Patch and test by Tony Nelson. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/email/feedparser.py python/branches/py3k/Lib/email/test/test_email.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/email/feedparser.py ============================================================================== --- python/branches/py3k/Lib/email/feedparser.py (original) +++ python/branches/py3k/Lib/email/feedparser.py Wed Jun 16 04:19:40 2010 @@ -28,7 +28,7 @@ NLCRE = re.compile('\r\n|\r|\n') NLCRE_bol = re.compile('(\r\n|\r|\n)') -NLCRE_eol = re.compile('(\r\n|\r|\n)$') +NLCRE_eol = re.compile('(\r\n|\r|\n)\Z') NLCRE_crack = re.compile('(\r\n|\r|\n)') # RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character # except controls, SP, and ":". Modified: python/branches/py3k/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k/Lib/email/test/test_email.py (original) +++ python/branches/py3k/Lib/email/test/test_email.py Wed Jun 16 04:19:40 2010 @@ -2588,6 +2588,24 @@ eq(headers, ['A', 'B', 'CC']) eq(msg.get_payload(), 'body') + def test_CRLFLF_at_end_of_part(self): + # issue 5610: feedparser should not eat two chars from body part ending + # with "\r\n\n". + m = ( + "From: foo at bar.com\n" + "To: baz\n" + "Mime-Version: 1.0\n" + "Content-Type: multipart/mixed; boundary=BOUNDARY\n" + "\n" + "--BOUNDARY\n" + "Content-Type: text/plain\n" + "\n" + "body ending with CRLF newline\r\n" + "\n" + "--BOUNDARY--\n" + ) + msg = email.message_from_string(m) + self.assertTrue(msg.get_payload(0).get_payload().endswith('\r\n')) class TestBase64(unittest.TestCase): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Jun 16 04:19:40 2010 @@ -432,6 +432,9 @@ Library ------- +- Issue #5610: feedparser no longer eats extra characters at the end of + a body part if the body part ends with a \r\n. + - Issue #8986: math.erfc was incorrectly raising OverflowError for values between -27.3 and -30.0 on some platforms. From python-checkins at python.org Wed Jun 16 04:22:57 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 04:22:57 +0200 (CEST) Subject: [Python-checkins] r82012 - in python/branches/release31-maint: Lib/email/feedparser.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20100616022257.2979EF4FD@mail.python.org> Author: r.david.murray Date: Wed Jun 16 04:22:56 2010 New Revision: 82012 Log: Merged revisions 82011 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r82011 | r.david.murray | 2010-06-15 22:19:40 -0400 (Tue, 15 Jun 2010) | 17 lines Merged revisions 81675 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81675 | r.david.murray | 2010-06-03 11:43:20 -0400 (Thu, 03 Jun 2010) | 10 lines #5610: use \Z not $ so we don't eat extra chars when body part ends with \r\n. If a body part ended with \r\n, feedparser, using '$' to terminate its search for the newline, would match on the \r\n, and think that it needed to strip two characters in order to account for the line end before the boundary. That made it chop one too many characters off the end of the body part. Using \Z makes the match correct. Patch and test by Tony Nelson. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/email/feedparser.py python/branches/release31-maint/Lib/email/test/test_email.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/email/feedparser.py ============================================================================== --- python/branches/release31-maint/Lib/email/feedparser.py (original) +++ python/branches/release31-maint/Lib/email/feedparser.py Wed Jun 16 04:22:56 2010 @@ -28,7 +28,7 @@ NLCRE = re.compile('\r\n|\r|\n') NLCRE_bol = re.compile('(\r\n|\r|\n)') -NLCRE_eol = re.compile('(\r\n|\r|\n)$') +NLCRE_eol = re.compile('(\r\n|\r|\n)\Z') NLCRE_crack = re.compile('(\r\n|\r|\n)') # RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character # except controls, SP, and ":". Modified: python/branches/release31-maint/Lib/email/test/test_email.py ============================================================================== --- python/branches/release31-maint/Lib/email/test/test_email.py (original) +++ python/branches/release31-maint/Lib/email/test/test_email.py Wed Jun 16 04:22:56 2010 @@ -2584,6 +2584,24 @@ eq(headers, ['A', 'B', 'CC']) eq(msg.get_payload(), 'body') + def test_CRLFLF_at_end_of_part(self): + # issue 5610: feedparser should not eat two chars from body part ending + # with "\r\n\n". + m = ( + "From: foo at bar.com\n" + "To: baz\n" + "Mime-Version: 1.0\n" + "Content-Type: multipart/mixed; boundary=BOUNDARY\n" + "\n" + "--BOUNDARY\n" + "Content-Type: text/plain\n" + "\n" + "body ending with CRLF newline\r\n" + "\n" + "--BOUNDARY--\n" + ) + msg = email.message_from_string(m) + self.assertTrue(msg.get_payload(0).get_payload().endswith('\r\n')) class TestBase64(unittest.TestCase): Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Wed Jun 16 04:22:56 2010 @@ -61,6 +61,9 @@ Library ------- +- Issue #5610: feedparser no longer eats extra characters at the end of + a body part if the body part ends with a \r\n. + - Fix codecs.escape_encode to return the correct consumed size. - Issue #8897: Fix sunau module, use bytes to write the header. Patch written From python-checkins at python.org Wed Jun 16 04:51:26 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 04:51:26 +0200 (CEST) Subject: [Python-checkins] r82013 - python/branches/release26-maint Message-ID: <20100616025126.5D8C7EEB51@mail.python.org> Author: r.david.murray Date: Wed Jun 16 04:51:26 2010 New Revision: 82013 Log: Blocked revisions 81678 via svnmerge ........ r81678 | r.david.murray | 2010-06-03 16:19:25 -0400 (Thu, 03 Jun 2010) | 7 lines #8889: rewrite transient_internet so we don't use EAI_NODATA on FreeBSD. FreeBSD doesn't have socket.EAI_NODATA. I rewrote the routine because there's no easy way to conditionally include a context manager in a with statement. As a side benefit, instead of a stack of context managers there's now only one. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Jun 16 14:53:07 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 14:53:07 +0200 (CEST) Subject: [Python-checkins] r82014 - python/branches/py3k Message-ID: <20100616125307.599E4EEB21@mail.python.org> Author: r.david.murray Date: Wed Jun 16 14:53:07 2010 New Revision: 82014 Log: Blocked revisions 81571,81678 via svnmerge I'm going to merge 81678 by hand. ........ r81571 | victor.stinner | 2010-05-27 18:29:48 -0400 (Thu, 27 May 2010) | 3 lines Issue #8835: test_support.transient_internet() catchs gaierror(EAI_NONAME) and gaierror(EAI_NODATA) ........ r81678 | r.david.murray | 2010-06-03 16:19:25 -0400 (Thu, 03 Jun 2010) | 7 lines #8889: rewrite transient_internet so we don't use EAI_NODATA on FreeBSD. FreeBSD doesn't have socket.EAI_NODATA. I rewrote the routine because there's no easy way to conditionally include a context manager in a with statement. As a side benefit, instead of a stack of context managers there's now only one. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Wed Jun 16 14:56:31 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 14:56:31 +0200 (CEST) Subject: [Python-checkins] r82015 - python/branches/py3k/Doc/library/doctest.rst Message-ID: <20100616125631.449B0EE9BB@mail.python.org> Author: r.david.murray Date: Wed Jun 16 14:56:31 2010 New Revision: 82015 Log: Remove versionadded accidentally introduced by r82008. Modified: python/branches/py3k/Doc/library/doctest.rst Modified: python/branches/py3k/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k/Doc/library/doctest.rst (original) +++ python/branches/py3k/Doc/library/doctest.rst Wed Jun 16 14:56:31 2010 @@ -325,10 +325,6 @@ error prone way of handling them. It is possible to use a different algorithm for handling tabs by writing a custom :class:`DocTestParser` class. - .. versionchanged:: 2.4 - Expanding tabs to spaces is new; previous versions tried to preserve hard tabs, - with confusing results. - * Output to stdout is captured, but not output to stderr (exception tracebacks are captured via a different means). From python-checkins at python.org Wed Jun 16 14:57:52 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 14:57:52 +0200 (CEST) Subject: [Python-checkins] r82016 - in python/branches/release31-maint: Doc/library/doctest.rst Message-ID: <20100616125752.833B8EE9BB@mail.python.org> Author: r.david.murray Date: Wed Jun 16 14:57:52 2010 New Revision: 82016 Log: Merged revisions 82015 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r82015 | r.david.murray | 2010-06-16 08:56:31 -0400 (Wed, 16 Jun 2010) | 2 lines Remove versionadded accidentally introduced by r82008. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/doctest.rst 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 Wed Jun 16 14:57:52 2010 @@ -325,10 +325,6 @@ error prone way of handling them. It is possible to use a different algorithm for handling tabs by writing a custom :class:`DocTestParser` class. - .. versionchanged:: 2.4 - Expanding tabs to spaces is new; previous versions tried to preserve hard tabs, - with confusing results. - * Output to stdout is captured, but not output to stderr (exception tracebacks are captured via a different means). From python-checkins at python.org Wed Jun 16 16:17:23 2010 From: python-checkins at python.org (stefan.krah) Date: Wed, 16 Jun 2010 16:17:23 +0200 (CEST) Subject: [Python-checkins] r82017 - in python/branches/release26-maint: Lib/test/test_curses.py Misc/NEWS setup.py Message-ID: <20100616141723.2355BEEC13@mail.python.org> Author: stefan.krah Date: Wed Jun 16 16:17:22 2010 New Revision: 82017 Log: Issue #7384: If the system readline library is linked against ncurses, do not link the readline module against ncursesw. Modified: python/branches/release26-maint/Lib/test/test_curses.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/setup.py Modified: python/branches/release26-maint/Lib/test/test_curses.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_curses.py (original) +++ python/branches/release26-maint/Lib/test/test_curses.py Wed Jun 16 16:17:22 2010 @@ -19,12 +19,6 @@ from test.test_support import requires, TestSkipped requires('curses') -# skip all these tests on FreeBSD: test_curses currently hangs the -# FreeBSD buildbots, preventing other tests from running. See issue -# #7384. -if 'freebsd' in sys.platform: - raise TestSkipped('The curses module is broken on FreeBSD. ' - 'See http://bugs.python.org/issue7384.') # XXX: if newterm was supported we could use it instead of initscr and not exit term = os.environ.get('TERM') Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Jun 16 16:17:22 2010 @@ -259,6 +259,11 @@ Extension Modules ----------------- +- Issue #7384: If the system readline library is linked against + ncurses, do not link the readline module against ncursesw. The + additional restriction of linking the readline and curses modules + against the same curses library is currently not enabled. + - Issue #2810: Fix cases where the Windows registry API returns ERROR_MORE_DATA, requiring a re-try in order to get the complete result. Modified: python/branches/release26-maint/setup.py ============================================================================== --- python/branches/release26-maint/setup.py (original) +++ python/branches/release26-maint/setup.py Wed Jun 16 16:17:22 2010 @@ -15,6 +15,7 @@ from distutils.command.build_ext import build_ext from distutils.command.install import install from distutils.command.install_lib import install_lib +from distutils.spawn import find_executable # This global variable is used to hold the list of modules to be disabled. disabled_module_list = [] @@ -601,6 +602,36 @@ # readline do_readline = self.compiler.find_library_file(lib_dirs, 'readline') + readline_termcap_library = "" + curses_library = "" + # Determine if readline is already linked against curses or tinfo. + if do_readline and find_executable('ldd'): + fp = os.popen("ldd %s" % do_readline) + for ln in fp: + if 'curses' in ln: + readline_termcap_library = re.sub( + r'.*lib(n?cursesw?)\.so.*', r'\1', ln + ).rstrip() + break + if 'tinfo' in ln: # termcap interface split out from ncurses + readline_termcap_library = 'tinfo' + break + fp.close() + # Issue 7384: If readline is already linked against curses, + # use the same library for the readline and curses modules. + # Disabled since applications relying on ncursesw might break. + # + # if 'curses' in readline_termcap_library: + # curses_library = readline_termcap_library + # elif self.compiler.find_library_file(lib_dirs, 'ncursesw'): + # (...) + if self.compiler.find_library_file(lib_dirs, 'ncursesw'): + curses_library = 'ncursesw' + elif self.compiler.find_library_file(lib_dirs, 'ncurses'): + curses_library = 'ncurses' + elif self.compiler.find_library_file(lib_dirs, 'curses'): + curses_library = 'curses' + if platform == 'darwin': os_release = int(os.uname()[2].split('.')[0]) dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') @@ -624,14 +655,10 @@ readline_extra_link_args = () readline_libs = ['readline'] - if self.compiler.find_library_file(lib_dirs, - 'ncursesw'): - readline_libs.append('ncursesw') - elif self.compiler.find_library_file(lib_dirs, - 'ncurses'): - readline_libs.append('ncurses') - elif self.compiler.find_library_file(lib_dirs, 'curses'): - readline_libs.append('curses') + if readline_termcap_library: + pass # Issue 7384: Already linked against curses or tinfo. + elif curses_library: + readline_libs.append(curses_library) elif self.compiler.find_library_file(lib_dirs + ['/usr/lib/termcap'], 'termcap'): @@ -1162,19 +1189,15 @@ # Curses support, requiring the System V version of curses, often # provided by the ncurses library. panel_library = 'panel' - if (self.compiler.find_library_file(lib_dirs, 'ncursesw')): - curses_libs = ['ncursesw'] - # Bug 1464056: If _curses.so links with ncursesw, - # _curses_panel.so must link with panelw. - panel_library = 'panelw' - exts.append( Extension('_curses', ['_cursesmodule.c'], - libraries = curses_libs) ) - elif (self.compiler.find_library_file(lib_dirs, 'ncurses')): - curses_libs = ['ncurses'] + if curses_library.startswith('ncurses'): + if curses_library == 'ncursesw': + # Bug 1464056: If _curses.so links with ncursesw, + # _curses_panel.so must link with panelw. + panel_library = 'panelw' + curses_libs = [curses_library] exts.append( Extension('_curses', ['_cursesmodule.c'], libraries = curses_libs) ) - elif (self.compiler.find_library_file(lib_dirs, 'curses') - and platform != 'darwin'): + elif curses_library == 'curses' and platform != 'darwin': # OSX has an old Berkeley curses, not good enough for # the _curses module. if (self.compiler.find_library_file(lib_dirs, 'terminfo')): From python-checkins at python.org Wed Jun 16 16:55:31 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 16 Jun 2010 16:55:31 +0200 (CEST) Subject: [Python-checkins] r82018 - python/trunk/Doc/library/simplehttpserver.rst Message-ID: <20100616145531.CDB47EE9BB@mail.python.org> Author: senthil.kumaran Date: Wed Jun 16 16:55:31 2010 New Revision: 82018 Log: Fix Issue8937 - SimpleHTTPServer should contain usage example Modified: python/trunk/Doc/library/simplehttpserver.rst Modified: python/trunk/Doc/library/simplehttpserver.rst ============================================================================== --- python/trunk/Doc/library/simplehttpserver.rst (original) +++ python/trunk/Doc/library/simplehttpserver.rst Wed Jun 16 16:55:31 2010 @@ -81,12 +81,34 @@ contents of the file are output. If the file's MIME type starts with ``text/`` the file is opened in text mode; otherwise binary mode is used. - For example usage, see the implementation of the :func:`test` function. + The :func:`test` function in the :mod:`SimpleHTTPServer` module is an + example which interfaces the :class:`SimpleHTTPRequestHandler` as a + Handler to the :mod:`BaseHTTPServer` module. .. versionadded:: 2.5 The ``'Last-Modified'`` header. +The :mod:`SimpleHTTPServer` module can be used the following manner in order to +setup a very basic web server serving files relative to the current directory.:: + + import SimpleHTTPServer + import SocketServer + + PORT = 8000 + + Handler = SimpleHTTPServer.SimpleHTTPRequestHandler + + httpd = SocketServer.TCPServer(("", PORT), Handler) + + print "serving at port", PORT + httpd.serve_forever() + +It can also be invoked directly using the ``-m`` switch of interpreter a with +``port number`` argument.:: + + python -m SimpleHTTPServer 8000 + .. seealso:: Module :mod:`BaseHTTPServer` From python-checkins at python.org Wed Jun 16 17:07:41 2010 From: python-checkins at python.org (stefan.krah) Date: Wed, 16 Jun 2010 17:07:41 +0200 (CEST) Subject: [Python-checkins] r82019 - in python/branches/release31-maint: Lib/test/test_curses.py Misc/NEWS setup.py Message-ID: <20100616150741.DC76DEEC42@mail.python.org> Author: stefan.krah Date: Wed Jun 16 17:07:41 2010 New Revision: 82019 Log: Issue #7384: If the system readline library is linked against ncurses, do not link the readline module against ncursesw. Modified: python/branches/release31-maint/Lib/test/test_curses.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/setup.py Modified: python/branches/release31-maint/Lib/test/test_curses.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_curses.py (original) +++ python/branches/release31-maint/Lib/test/test_curses.py Wed Jun 16 17:07:41 2010 @@ -23,11 +23,6 @@ curses = import_module('curses') curses.panel = import_module('curses.panel') -# skip all these tests on FreeBSD: test_curses currently hangs the -# FreeBSD buildbots, preventing other tests from running. See issue -# #7384. -if 'freebsd' in sys.platform: - raise unittest.SkipTest('The curses module is broken on FreeBSD. See http://bugs.python.org/issue7384.') # XXX: if newterm was supported we could use it instead of initscr and not exit term = os.environ.get('TERM') Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Wed Jun 16 17:07:41 2010 @@ -244,6 +244,11 @@ Extension Modules ----------------- +- Issue #7384: If the system readline library is linked against + ncurses, do not link the readline module against ncursesw. The + additional restriction of linking the readline and curses modules + against the same curses library is currently not enabled. + - Issue #8973: Add __all__ to struct module; this ensures that help(struct) includes documentation for the struct.Struct class. Modified: python/branches/release31-maint/setup.py ============================================================================== --- python/branches/release31-maint/setup.py (original) +++ python/branches/release31-maint/setup.py Wed Jun 16 17:07:41 2010 @@ -14,6 +14,7 @@ from distutils.command.build_ext import build_ext from distutils.command.install import install from distutils.command.install_lib import install_lib +from distutils.spawn import find_executable # This global variable is used to hold the list of modules to be disabled. disabled_module_list = [] @@ -538,6 +539,42 @@ # readline do_readline = self.compiler.find_library_file(lib_dirs, 'readline') + readline_termcap_library = "" + curses_library = "" + # Determine if readline is already linked against curses or tinfo. + if do_readline and find_executable('ldd'): + # Cannot use os.popen here in py3k. + tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) + os.system("ldd %s > %s" % (do_readline, tmpfile)) + fp = open(tmpfile) + for ln in fp: + if 'curses' in ln: + readline_termcap_library = re.sub( + r'.*lib(n?cursesw?)\.so.*', r'\1', ln + ).rstrip() + break + if 'tinfo' in ln: # termcap interface split out from ncurses + readline_termcap_library = 'tinfo' + break + fp.close() + os.unlink(tmpfile) + # Issue 7384: If readline is already linked against curses, + # use the same library for the readline and curses modules. + # Disabled since applications relying on ncursesw might break. + # + # if 'curses' in readline_termcap_library: + # curses_library = readline_termcap_library + # elif self.compiler.find_library_file(lib_dirs, 'ncursesw'): + # (...) + if self.compiler.find_library_file(lib_dirs, 'ncursesw'): + curses_library = 'ncursesw' + elif self.compiler.find_library_file(lib_dirs, 'ncurses'): + curses_library = 'ncurses' + elif self.compiler.find_library_file(lib_dirs, 'curses'): + curses_library = 'curses' + if platform == 'darwin': # and os.uname()[2] < '9.': # MacOSX 10.4 has a broken readline. Don't try to build # the readline module unless the user has installed a fixed @@ -558,14 +595,10 @@ readline_extra_link_args = () readline_libs = ['readline'] - if self.compiler.find_library_file(lib_dirs, - 'ncursesw'): - readline_libs.append('ncursesw') - elif self.compiler.find_library_file(lib_dirs, - 'ncurses'): - readline_libs.append('ncurses') - elif self.compiler.find_library_file(lib_dirs, 'curses'): - readline_libs.append('curses') + if readline_termcap_library: + pass # Issue 7384: Already linked against curses or tinfo. + elif curses_library: + readline_libs.append(curses_library) elif self.compiler.find_library_file(lib_dirs + ['/usr/lib/termcap'], 'termcap'): @@ -1071,19 +1104,15 @@ # Curses support, requiring the System V version of curses, often # provided by the ncurses library. panel_library = 'panel' - if (self.compiler.find_library_file(lib_dirs, 'ncursesw')): - curses_libs = ['ncursesw'] - # Bug 1464056: If _curses.so links with ncursesw, - # _curses_panel.so must link with panelw. - panel_library = 'panelw' - exts.append( Extension('_curses', ['_cursesmodule.c'], - libraries = curses_libs) ) - elif (self.compiler.find_library_file(lib_dirs, 'ncurses')): - curses_libs = ['ncurses'] + if curses_library.startswith('ncurses'): + if curses_library == 'ncursesw': + # Bug 1464056: If _curses.so links with ncursesw, + # _curses_panel.so must link with panelw. + panel_library = 'panelw' + curses_libs = [curses_library] exts.append( Extension('_curses', ['_cursesmodule.c'], libraries = curses_libs) ) - elif (self.compiler.find_library_file(lib_dirs, 'curses') - and platform != 'darwin'): + elif curses_library == 'curses' and platform != 'darwin': # OSX has an old Berkeley curses, not good enough for # the _curses module. if (self.compiler.find_library_file(lib_dirs, 'terminfo')): From python-checkins at python.org Wed Jun 16 18:17:33 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 16 Jun 2010 18:17:33 +0200 (CEST) Subject: [Python-checkins] r82020 - in python/branches/release26-maint: Doc/library/simplehttpserver.rst Message-ID: <20100616161733.AC547EEBC8@mail.python.org> Author: senthil.kumaran Date: Wed Jun 16 18:17:33 2010 New Revision: 82020 Log: Merged revisions 82018 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82018 | senthil.kumaran | 2010-06-16 20:25:31 +0530 (Wed, 16 Jun 2010) | 3 lines Fix Issue8937 - SimpleHTTPServer should contain usage example ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/simplehttpserver.rst Modified: python/branches/release26-maint/Doc/library/simplehttpserver.rst ============================================================================== --- python/branches/release26-maint/Doc/library/simplehttpserver.rst (original) +++ python/branches/release26-maint/Doc/library/simplehttpserver.rst Wed Jun 16 18:17:33 2010 @@ -81,12 +81,34 @@ contents of the file are output. If the file's MIME type starts with ``text/`` the file is opened in text mode; otherwise binary mode is used. - For example usage, see the implementation of the :func:`test` function. + The :func:`test` function in the :mod:`SimpleHTTPServer` module is an + example which interfaces the :class:`SimpleHTTPRequestHandler` as a + Handler to the :mod:`BaseHTTPServer` module. .. versionadded:: 2.5 The ``'Last-Modified'`` header. +The :mod:`SimpleHTTPServer` module can be used the following manner in order to +setup a very basic web server serving files relative to the current directory.:: + + import SimpleHTTPServer + import SocketServer + + PORT = 8000 + + Handler = SimpleHTTPServer.SimpleHTTPRequestHandler + + httpd = SocketServer.TCPServer(("", PORT), Handler) + + print "serving at port", PORT + httpd.serve_forever() + +It can also be invoked directly using the ``-m`` switch of interpreter a with +``port number`` argument.:: + + python -m SimpleHTTPServer 8000 + .. seealso:: Module :mod:`BaseHTTPServer` From python-checkins at python.org Wed Jun 16 18:21:26 2010 From: python-checkins at python.org (collin.winter) Date: Wed, 16 Jun 2010 18:21:26 +0200 (CEST) Subject: [Python-checkins] r82021 - in python/branches/py3k-jit: Doc/c-api/arg.rst Doc/c-api/buffer.rst Doc/distutils/builtdist.rst Doc/extending/newtypes.rst Doc/library/argparse.rst Doc/library/datetime.rst Doc/library/decimal.rst Doc/library/dis.rst Doc/library/doctest.rst Doc/library/ftplib.rst Doc/library/functions.rst Doc/library/io.rst Doc/library/os.rst Doc/library/socket.rst Doc/library/sqlite3.rst Doc/library/ssl.rst Doc/library/struct.rst Doc/library/subprocess.rst Doc/library/sysconfig.rst Doc/library/tarfile.rst Doc/library/time.rst Doc/library/unittest.rst Doc/library/urllib.parse.rst Doc/library/winreg.rst Doc/library/xml.dom.minidom.rst Doc/tools/sphinxext/pyspecific.py Doc/whatsnew/3.2.rst Include/longobject.h Lib/base64.py Lib/ctypes/test/test_bytes.py Lib/ctypes/test/test_structures.py Lib/decimal.py Lib/distutils/unixccompiler.py Lib/doctest.py Lib/email/charset.py Lib/email/encoders.py Lib/email/test/test_email.py Lib/ftplib.py Lib/html/parser.py Lib/http/client.py Lib/logging/config.py Lib/os.py Lib/sqlite3/test/dbapi.py Lib/struct.py Lib/sunau.py Lib/sysconfig.py Lib/tarfile.py Lib/test/math_testcases.txt Lib/test/regrtest.py Lib/test/test_base64.py Lib/test/test_builtin.py Lib/test/test_calendar.py Lib/test/test_capi.py Lib/test/test_codecs.py Lib/test/test_curses.py Lib/test/test_datetime.py Lib/test/test_descr.py Lib/test/test_doctest.py Lib/test/test_enumerate.py Lib/test/test_fractions.py Lib/test/test_ftplib.py Lib/test/test_getargs2.py Lib/test/test_htmlparser.py Lib/test/test_httplib.py Lib/test/test_long.py Lib/test/test_math.py Lib/test/test_minidom.py Lib/test/test_numeric_tower.py Lib/test/test_os.py Lib/test/test_socketserver.py Lib/test/test_ssl.py Lib/test/test_struct.py Lib/test/test_sunau.py Lib/test/test_sundry.py Lib/test/test_sys.py Lib/test/test_sysconfig.py Lib/test/test_tarfile.py Lib/test/test_tcl.py Lib/test/test_unicode.py Lib/test/test_urllib2.py Lib/test/test_winreg.py Lib/test/test_winsound.py Lib/test/testtar.tar Lib/tkinter/_fix.py Lib/unittest/case.py Lib/unittest/loader.py Lib/unittest/suite.py Lib/unittest/test/test_case.py Lib/unittest/test/test_runner.py Lib/unittest/test/test_setups.py Lib/unittest/util.py Lib/urllib/request.py Lib/webbrowser.py Lib/xml/dom/minidom.py Mac/Tools/pythonw.c Misc/ACKS Misc/NEWS Misc/developers.txt Misc/maintainers.rst Modules/_codecsmodule.c Modules/_ctypes/_ctypes.c Modules/_ctypes/cfield.c Modules/_localemodule.c Modules/_multiprocessing/multiprocessing.h Modules/_sqlite/connection.c Modules/_struct.c Modules/_testcapimodule.c Modules/config.c.in Modules/datetimemodule.c Modules/itertoolsmodule.c Modules/mathmodule.c Modules/readline.c Modules/timemodule.c Objects/abstract.c Objects/bytearrayobject.c Objects/bytesobject.c Objects/exceptions.c Objects/longobject.c Objects/stringlib/formatter.h Objects/stringlib/string_format.h Objects/typeobject.c Objects/unicodeobject.c PC/winreg.c Parser/asdl_c.py Python/Python-ast.c Python/ceval.c Python/errors.c Python/getargs.c Python/modsupport.c Python/pythonrun.c Python/symtable.c Python/sysmodule.c Tools/i18n/msgfmt.py Tools/scripts/serve.py configure configure.in setup.py Message-ID: <20100616162126.6F577EEBC8@mail.python.org> Author: collin.winter Date: Wed Jun 16 18:21:24 2010 New Revision: 82021 Log: Merged revisions 81498,81504,81511,81513-81514,81519,81522,81526,81528,81532-81533,81535,81538,81541,81545,81547-81548,81550,81553,81556-81557,81560,81564-81565,81568,81572,81575,81581,81583,81585,81588,81590,81595,81600,81604,81607,81609,81611-81613,81623,81625,81628,81630,81632,81638,81642,81647,81650,81654,81656,81660,81665,81670,81673,81682,81685,81689,81694-81695,81698-81699,81703,81708,81711,81713,81725,81730-81731,81737,81742-81743,81746,81748,81751,81754-81755,81757,81762,81765-81766,81768,81771,81778-81782,81790,81792,81794,81806-81807,81809,81811,81814,81816,81818,81821,81823,81826-81827,81829-81832,81835,81838,81840-81841,81843-81844,81849,81851,81854,81856-81857,81862,81865,81869,81871,81873-81875,81877,81879,81883,81885,81891,81893-81898,81901-81902,81905,81908,81911-81912,81914,81916,81918,81920,81923,81925,81927,81929-81930,81936-81938,81944,81946-81952,81954-81956,81958,81961,81965,81968,81970,81972-81974,81981,81988-81989 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81498 | antoine.pitrou | 2010-05-24 14:20:20 -0700 (Mon, 24 May 2010) | 3 lines Document the context attribute of SSL sockets ................ r81504 | victor.stinner | 2010-05-24 14:46:25 -0700 (Mon, 24 May 2010) | 13 lines Recorded merge of revisions 81500-81501 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81500 | victor.stinner | 2010-05-24 23:33:24 +0200 (lun., 24 mai 2010) | 2 lines Issue #6662: Fix parsing of malformatted charref (&#bad;) ........ r81501 | victor.stinner | 2010-05-24 23:37:28 +0200 (lun., 24 mai 2010) | 2 lines Add the author of the last fix (Issue #6662) ........ ................ r81511 | benjamin.peterson | 2010-05-24 19:27:55 -0700 (Mon, 24 May 2010) | 8 lines Blocked revisions 81509 via svnmerge ........ r81509 | benjamin.peterson | 2010-05-24 21:23:32 -0500 (Mon, 24 May 2010) | 1 line correct default docs ........ ................ r81513 | tarek.ziade | 2010-05-25 02:44:36 -0700 (Tue, 25 May 2010) | 1 line Made sysconfig a script that displays useful information - #8770 ................ r81514 | tarek.ziade | 2010-05-25 02:47:06 -0700 (Tue, 25 May 2010) | 1 line added the list of public APIs in sysconfig ................ r81519 | r.david.murray | 2010-05-25 08:26:21 -0700 (Tue, 25 May 2010) | 13 lines Blocked revisions 81518 via svnmerge ........ r81518 | r.david.murray | 2010-05-25 11:20:46 -0400 (Tue, 25 May 2010) | 8 lines Issue 8143: sync unquote in urlparse with urllib; add comment about doing so. unquote is duplicated in the two files to avoid a circular reference. (This is fixed in Python3.) Updates keep getting made to the public unquote without fixing the urlparse one, however, so this fix syncs the two and adds a comment to both to make sure changes are applied to both. ........ ................ r81522 | r.david.murray | 2010-05-25 08:36:46 -0700 (Tue, 25 May 2010) | 9 lines Recorded merge of revisions 81521 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81521 | r.david.murray | 2010-05-25 11:32:06 -0400 (Tue, 25 May 2010) | 2 lines Issue 8818: urlparse/urlsplit keyword is 'scheme', not 'default_scheme'. ........ ................ r81526 | mark.dickinson | 2010-05-25 12:06:24 -0700 (Tue, 25 May 2010) | 10 lines Merged revisions 81525 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81525 | mark.dickinson | 2010-05-25 20:01:08 +0100 (Tue, 25 May 2010) | 3 lines Issue #8816: Extra tests for some built-in functions. These tests are ports of IronPython tests. Thanks Gregory Nofi. ........ ................ r81528 | mark.dickinson | 2010-05-25 12:46:20 -0700 (Tue, 25 May 2010) | 9 lines Merged revisions 81527 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81527 | mark.dickinson | 2010-05-25 20:44:49 +0100 (Tue, 25 May 2010) | 1 line Fix a NameError in test_enumerate. ........ ................ r81532 | martin.v.loewis | 2010-05-25 13:07:11 -0700 (Tue, 25 May 2010) | 9 lines Merged revisions 81531 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81531 | martin.v.loewis | 2010-05-25 22:06:02 +0200 (Di, 25 Mai 2010) | 2 lines Add Alexander Belopolsky. ........ ................ r81533 | victor.stinner | 2010-05-25 14:12:34 -0700 (Tue, 25 May 2010) | 3 lines Issue #4769: Fix main() function of the base64 module, use sys.stdin.buffer and sys.stdout.buffer (instead of sys.stdin and sys.stdout) to use the bytes API ................ r81535 | victor.stinner | 2010-05-25 15:17:22 -0700 (Tue, 25 May 2010) | 2 lines Fix the new TestMain.test_decode() of test_base64 for Windows ................ r81538 | victor.stinner | 2010-05-25 15:35:40 -0700 (Tue, 25 May 2010) | 11 lines Blocked revisions 81537 via svnmerge ........ r81537 | victor.stinner | 2010-05-26 00:30:32 +0200 (mer., 26 mai 2010) | 3 lines Issue #3798: Write sys.exit() message to sys.stderr to use stderr encoding and error handler, instead of writing to the C stderr file in utf-8 ........ py3k was already fixed by r81252. ................ r81541 | mark.dickinson | 2010-05-26 09:02:59 -0700 (Wed, 26 May 2010) | 4 lines Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near for use by the datetime module; also refactor long_round to use this function. ................ r81545 | victor.stinner | 2010-05-26 10:33:03 -0700 (Wed, 26 May 2010) | 9 lines Merged revisions 81543 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81543 | victor.stinner | 2010-05-26 19:25:28 +0200 (mer., 26 mai 2010) | 2 lines Issue #7449: Skip test_socketserver if threading support is disabled ........ ................ r81547 | brian.curtin | 2010-05-26 10:43:50 -0700 (Wed, 26 May 2010) | 6 lines Fix #2810 - handle the case where some registry calls return ERROR_MORE_DATA, requiring another call to get the remaining data. Patch by Daniel Stutzbach ................ r81548 | giampaolo.rodola | 2010-05-26 11:06:04 -0700 (Wed, 26 May 2010) | 1 line Fix issue #8806: add SSL contexts support to ftplib ................ r81550 | giampaolo.rodola | 2010-05-26 11:21:26 -0700 (Wed, 26 May 2010) | 1 line fix wrong assertIs context ................ r81553 | mark.dickinson | 2010-05-26 12:14:01 -0700 (Wed, 26 May 2010) | 9 lines Merged revisions 81551 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81551 | mark.dickinson | 2010-05-26 20:06:33 +0100 (Wed, 26 May 2010) | 1 line Issue #8825: additional testcases for int(string, 0) and long(string, 0). ........ ................ r81556 | alexander.belopolsky | 2010-05-26 13:00:12 -0700 (Wed, 26 May 2010) | 10 lines Merged revisions 81555 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81555 | alexander.belopolsky | 2010-05-26 15:43:16 -0400 (Wed, 26 May 2010) | 3 lines Issue #7879: Do not test negative timestamps on any Windows platform including Windows CE. ........ ................ r81557 | mark.dickinson | 2010-05-26 13:07:58 -0700 (Wed, 26 May 2010) | 4 lines Issue #2844: Make int('42', n) consistently raise ValueError for invalid integers n (including n = -909). ................ r81560 | alexander.belopolsky | 2010-05-26 13:48:30 -0700 (Wed, 26 May 2010) | 10 lines Merged revisions 81559 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81559 | alexander.belopolsky | 2010-05-26 16:45:37 -0400 (Wed, 26 May 2010) | 3 lines Issue #7879: Skip negative timestamps test on any Windows platform using unittest.skipIf decorator. ........ ................ r81564 | mark.dickinson | 2010-05-27 12:45:50 -0700 (Thu, 27 May 2010) | 9 lines Merged revisions 81512 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81512 | brett.cannon | 2010-05-25 03:53:04 +0100 (Tue, 25 May 2010) | 1 line Make the contributor list alphabetical again. ........ ................ r81565 | mark.dickinson | 2010-05-27 12:47:53 -0700 (Thu, 27 May 2010) | 1 line Stefan Krah was missing from Misc/ACKS in the py3k branch. ................ r81568 | alexander.belopolsky | 2010-05-27 14:42:58 -0700 (Thu, 27 May 2010) | 10 lines Merged revisions 81566 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81566 | alexander.belopolsky | 2010-05-27 16:55:27 -0400 (Thu, 27 May 2010) | 3 lines Issue #7150: Raise OverflowError if the result of adding or subtracting timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range. ........ ................ r81572 | benjamin.peterson | 2010-05-27 15:32:22 -0700 (Thu, 27 May 2010) | 1 line correct default value in signature ................ r81575 | ezio.melotti | 2010-05-27 15:38:16 -0700 (Thu, 27 May 2010) | 9 lines Merged revisions 81318 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81318 | ezio.melotti | 2010-05-19 03:32:52 +0300 (Wed, 19 May 2010) | 1 line Fix typo in argparse doc. ........ ................ r81581 | benjamin.peterson | 2010-05-27 20:23:57 -0700 (Thu, 27 May 2010) | 12 lines Blocked revisions 81578-81579 via svnmerge ........ r81578 | benjamin.peterson | 2010-05-27 21:12:36 -0500 (Thu, 27 May 2010) | 1 line remove non-ascii coding per PEP 8 ........ r81579 | benjamin.peterson | 2010-05-27 22:10:31 -0500 (Thu, 27 May 2010) | 1 line 2to3 doesn't fix test_support #6583 ........ ................ r81583 | martin.v.loewis | 2010-05-28 08:44:20 -0700 (Fri, 28 May 2010) | 9 lines Merged revisions 81582 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81582 | martin.v.loewis | 2010-05-28 17:28:47 +0200 (Fr, 28 Mai 2010) | 2 lines Issue #1759169: Drop _XOPEN_SOURCE on Solaris. ........ ................ r81585 | brian.curtin | 2010-05-28 09:08:40 -0700 (Fri, 28 May 2010) | 10 lines Merged revisions 81584 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81584 | brian.curtin | 2010-05-28 10:49:21 -0500 (Fri, 28 May 2010) | 3 lines Fix #8405 for slow buildbots. Remove the sleep on startup and move the pipe communication into a loop to retry in case a buildbot gets even slower. ........ ................ r81588 | victor.stinner | 2010-05-28 14:55:10 -0700 (Fri, 28 May 2010) | 3 lines Issue #8837: Remove "O?" format of PyArg_Parse*() functions. The format is no used anymore and it was never documented. ................ r81590 | victor.stinner | 2010-05-28 17:13:06 -0700 (Fri, 28 May 2010) | 2 lines Remove dead code ................ r81595 | antoine.pitrou | 2010-05-29 05:08:25 -0700 (Sat, 29 May 2010) | 9 lines Merged revisions 81594 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81594 | antoine.pitrou | 2010-05-29 14:06:13 +0200 (sam., 29 mai 2010) | 3 lines Issue #8840: Make documentation for truncate() clearer ........ ................ r81600 | stefan.krah | 2010-05-29 05:59:18 -0700 (Sat, 29 May 2010) | 9 lines Merged revisions 81598 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81598 | stefan.krah | 2010-05-29 14:54:35 +0200 (Sat, 29 May 2010) | 1 line Fix typo ........ ................ r81604 | mark.dickinson | 2010-05-29 14:05:27 -0700 (Sat, 29 May 2010) | 9 lines Merged revisions 81602 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81602 | mark.dickinson | 2010-05-29 22:00:52 +0100 (Sat, 29 May 2010) | 1 line Untabify Modules/config.c.in. ........ ................ r81607 | mark.dickinson | 2010-05-30 05:12:56 -0700 (Sun, 30 May 2010) | 10 lines Blocked revisions 81606 via svnmerge ........ r81606 | mark.dickinson | 2010-05-30 13:12:25 +0100 (Sun, 30 May 2010) | 4 lines Issue #5211: Complete removal of implicit coercions for the complex type. Coercion for arithmetic operations was already removed in r78280, but that commit didn't remove coercion for rich comparisons. ........ ................ r81609 | mark.dickinson | 2010-05-30 05:17:39 -0700 (Sun, 30 May 2010) | 8 lines Blocked revisions 81608 via svnmerge ........ r81608 | mark.dickinson | 2010-05-30 13:17:11 +0100 (Sun, 30 May 2010) | 1 line Remove declaration for unused variable. ........ ................ r81611 | mark.dickinson | 2010-05-30 06:18:47 -0700 (Sun, 30 May 2010) | 10 lines Recorded merge of revisions 81610 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81610 | mark.dickinson | 2010-05-30 14:18:10 +0100 (Sun, 30 May 2010) | 3 lines Issue #8748: Fix incorrect results from comparisons between an integer and a complex instance. Based on a patch by Meador Inge. ........ ................ r81612 | benjamin.peterson | 2010-05-30 07:49:32 -0700 (Sun, 30 May 2010) | 1 line use atomic structures in non-thread version ................ r81613 | ronald.oussoren | 2010-05-30 08:46:48 -0700 (Sun, 30 May 2010) | 4 lines Remove conditional import of 'ic', that module was removed in the transition from python 2.x to python 3.x. ................ r81623 | antoine.pitrou | 2010-05-31 10:04:40 -0700 (Mon, 31 May 2010) | 9 lines Merged revisions 81621 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81621 | antoine.pitrou | 2010-05-31 19:01:01 +0200 (lun., 31 mai 2010) | 4 lines Improve documentation for getaddrinfo() (part of #8857) ........ ................ r81625 | alexander.belopolsky | 2010-05-31 10:33:47 -0700 (Mon, 31 May 2010) | 3 lines Issue #1289118: datetime.timedelta objects can now be multiplied by float and divided by float and int objects. ................ r81628 | r.david.murray | 2010-05-31 16:23:50 -0700 (Mon, 31 May 2010) | 9 lines Merged revisions 81587 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81587 | r.david.murray | 2010-05-28 14:17:20 -0400 (Fri, 28 May 2010) | 2 lines Make the ctl-C shutdown of serve.py prettier. ........ ................ r81630 | r.david.murray | 2010-05-31 18:11:18 -0700 (Mon, 31 May 2010) | 9 lines Merged revisions 81586 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81586 | r.david.murray | 2010-05-28 14:08:11 -0400 (Fri, 28 May 2010) | 2 lines Make reference to Generic Attribute Management a hyperlink. ........ ................ r81632 | r.david.murray | 2010-05-31 18:32:12 -0700 (Mon, 31 May 2010) | 4 lines #8845: expose sqlite3 inTransaction as RO in_transaction Connection attribute. Patch by R. David Murray, unit tests by Shashwat Anand. ................ r81638 | senthil.kumaran | 2010-06-01 05:53:48 -0700 (Tue, 01 Jun 2010) | 9 lines Merged revisions 81636 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81636 | senthil.kumaran | 2010-06-01 18:10:07 +0530 (Tue, 01 Jun 2010) | 3 lines Fix Issue8797 - urllib2 basic authentication fix for wrong passwords. It fails after 5 retries. ........ ................ r81642 | brian.curtin | 2010-06-01 06:49:19 -0700 (Tue, 01 Jun 2010) | 10 lines Merged revisions 81640 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81640 | brian.curtin | 2010-06-01 08:29:13 -0500 (Tue, 01 Jun 2010) | 3 lines Fix #8618. Ask the Windows mixer API if there are any playback devices configured before attempting to test PlaySound. ........ ................ r81647 | senthil.kumaran | 2010-06-01 19:29:00 -0700 (Tue, 01 Jun 2010) | 9 lines Merged revisions 81645 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81645 | senthil.kumaran | 2010-06-02 07:49:15 +0530 (Wed, 02 Jun 2010) | 3 lines Fix issue8788 - description of doseq parameter in urllib.urlencode ........ ................ r81650 | ronald.oussoren | 2010-06-01 20:50:56 -0700 (Tue, 01 Jun 2010) | 11 lines Merged revisions 81649 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81649 | ronald.oussoren | 2010-06-02 05:47:14 +0200 (Wed, 02 Jun 2010) | 5 lines Fix for issue8868: without this patch 'MacOS.WMAvailable()' will return False on MacOSX 10.5 or earlier and scripts won't be able to access GUI functionality. ........ ................ r81654 | antoine.pitrou | 2010-06-02 10:10:49 -0700 (Wed, 02 Jun 2010) | 10 lines Merged revisions 81652 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81652 | antoine.pitrou | 2010-06-02 19:08:47 +0200 (mer., 02 juin 2010) | 4 lines Issue #8873: add a documentation note about possible performance issues with the default of unbuffered IO in subprocess.Popen. ........ ................ r81656 | benjamin.peterson | 2010-06-02 11:10:09 -0700 (Wed, 02 Jun 2010) | 1 line remove description of LOAD_LOCALS #8874 ................ r81660 | r.david.murray | 2010-06-02 18:58:28 -0700 (Wed, 02 Jun 2010) | 25 lines Fix Charset.body_encode to encode to output_charset before calling base64mime. This means that what gets encoded in base64 is the encoded version of the unicode payload. This bug was revealed by a forward port of the tests from Issue 1368247, but the fix was completely different. Note that the merge is only of the tests, the doc changes were inappropriate since email5 expects unicode, not bytes. I'm also not convinced that quopri works correctly in email5, but that's a different issue. Merged revisions 81658 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81658 | r.david.murray | 2010-06-02 18:03:15 -0400 (Wed, 02 Jun 2010) | 9 lines #1368247: make set_charset/MIMEText automatically encode unicode _payload. Fixes (mysterious, to the end user) UnicodeErrors when using utf-8 as the charset and unicode as the _text argument. Also makes the way in which unicode gets encoded to quoted printable for other charsets more sane (it only worked by accident previously). The _payload now is encoded to the charset.output_charset if it is unicode. ........ ................ r81665 | lars.gustaebel | 2010-06-03 03:11:52 -0700 (Thu, 03 Jun 2010) | 11 lines Merged revisions 81663 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81663 | lars.gustaebel | 2010-06-03 11:56:22 +0200 (Thu, 03 Jun 2010) | 4 lines Issue #8833: tarfile created hard link entries with a size field != 0 by mistake. The associated testcase did not expose this bug because it was broken too. ........ ................ r81670 | lars.gustaebel | 2010-06-03 05:45:16 -0700 (Thu, 03 Jun 2010) | 14 lines Merged revisions 81667 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81667 | lars.gustaebel | 2010-06-03 14:34:14 +0200 (Thu, 03 Jun 2010) | 8 lines Issue #8741: Fixed the TarFile.makelink() method that is responsible for extracting symbolic and hard link entries as regular files as a work-around on platforms that do not support filesystem links. This stopped working reliably after a change in r74571. I also added a few tests for this functionality. ........ ................ r81673 | ronald.oussoren | 2010-06-03 07:42:25 -0700 (Thu, 03 Jun 2010) | 16 lines Merged revisions 81662 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81662 | ronald.oussoren | 2010-06-03 11:47:21 +0200 (Thu, 03 Jun 2010) | 9 lines Fix for issue #7724: ensure that distutils and python's own setup.py honor the MacOSX SDK when one is specified. This is needed to be able to build using the 10.4u SDK while running on OSX 10.6. This is a fixed version of the patch in r80963, I've tested this patch on OSX and Linux. ........ ................ r81682 | sean.reifschneider | 2010-06-03 18:51:38 -0700 (Thu, 03 Jun 2010) | 2 lines Issue8810: Clearing up docstring for tzinfo.utcoffset. ................ r81685 | r.david.murray | 2010-06-04 09:11:08 -0700 (Fri, 04 Jun 2010) | 4 lines #4768: store base64 encoded email body parts as text, not binary. Patch and tests by Forest Bond. ................ r81689 | senthil.kumaran | 2010-06-04 09:38:00 -0700 (Fri, 04 Jun 2010) | 9 lines Merged revisions 81687 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81687 | senthil.kumaran | 2010-06-04 22:02:14 +0530 (Fri, 04 Jun 2010) | 3 lines Fix issue6312 - close the resp object for HEAD response. ........ ................ r81694 | martin.v.loewis | 2010-06-04 10:20:56 -0700 (Fri, 04 Jun 2010) | 10 lines Merged revisions 81692 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81692 | martin.v.loewis | 2010-06-04 19:18:42 +0200 (Fr, 04 Jun 2010) | 3 lines Issue #8864: Define _XOPEN_SOURCE on Solaris for the multiprocessing module. ........ ................ r81695 | senthil.kumaran | 2010-06-04 10:27:11 -0700 (Fri, 04 Jun 2010) | 9 lines Merged revisions 81691 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81691 | senthil.kumaran | 2010-06-04 22:47:09 +0530 (Fri, 04 Jun 2010) | 3 lines test verifying the resp object is closed for HEAD response. ........ ................ r81698 | martin.v.loewis | 2010-06-04 11:14:42 -0700 (Fri, 04 Jun 2010) | 9 lines Merged revisions 81697 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81697 | martin.v.loewis | 2010-06-04 20:04:42 +0200 (Fr, 04 Jun 2010) | 2 lines Issue #5464: Implement plural forms in msgfmt.py. ........ ................ r81699 | martin.v.loewis | 2010-06-04 11:40:55 -0700 (Fri, 04 Jun 2010) | 2 lines Port to Python 3. ................ r81703 | martin.v.loewis | 2010-06-04 12:50:26 -0700 (Fri, 04 Jun 2010) | 10 lines Merged revisions 81701 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81701 | martin.v.loewis | 2010-06-04 21:39:07 +0200 (Fr, 04 Jun 2010) | 2 lines Issue #6470: Drop UNC prefix in FixTk.py Patch by Christop Gohlke and Amaury Forgeot d'Arc. ........ ................ r81708 | benjamin.peterson | 2010-06-04 17:45:37 -0700 (Fri, 04 Jun 2010) | 13 lines Merged revisions 81706-81707 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81706 | benjamin.peterson | 2010-06-04 19:32:50 -0500 (Fri, 04 Jun 2010) | 1 line properly lookup the __format__ special method ........ r81707 | benjamin.peterson | 2010-06-04 19:38:22 -0500 (Fri, 04 Jun 2010) | 1 line remove PyType_Ready call; float should be initialized in interpreter startup ........ ................ r81711 | benjamin.peterson | 2010-06-04 18:03:24 -0700 (Fri, 04 Jun 2010) | 13 lines Merged revisions 81709-81710 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81709 | benjamin.peterson | 2010-06-04 19:56:46 -0500 (Fri, 04 Jun 2010) | 1 line implement object.__format__ with PyObject_Format ........ r81710 | benjamin.peterson | 2010-06-04 20:00:10 -0500 (Fri, 04 Jun 2010) | 1 line fix ref counting ........ ................ r81713 | benjamin.peterson | 2010-06-04 19:11:45 -0700 (Fri, 04 Jun 2010) | 9 lines Merged revisions 81712 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81712 | benjamin.peterson | 2010-06-04 21:07:01 -0500 (Fri, 04 Jun 2010) | 1 line _PyObject_LookupSpecial returns a new reference ........ ................ r81725 | michael.foord | 2010-06-05 03:45:41 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81724 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81724 | michael.foord | 2010-06-05 11:39:42 +0100 (Sat, 05 Jun 2010) | 1 line unittest TestLoader test discovery filename matching done in a method. This makes it easier to override the matching strategy in subclasses. No behaviour change in actual implementation. ........ ................ r81730 | michael.foord | 2010-06-05 04:27:52 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81728 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81728 | michael.foord | 2010-06-05 12:23:51 +0100 (Sat, 05 Jun 2010) | 1 line Issue 8351. Suppress large diffs in unittest.TestCase.assertSequenceEqual. ........ ................ r81731 | michael.foord | 2010-06-05 04:30:23 -0700 (Sat, 05 Jun 2010) | 1 line Test fix to use floor division. Correction from merge in previous commit. ................ r81737 | mark.dickinson | 2010-06-05 04:53:11 -0700 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81736 via svnmerge ........ r81736 | mark.dickinson | 2010-06-05 12:52:24 +0100 (Sat, 05 Jun 2010) | 1 line Issue #8627: remove out-of-date warning about overriding __cmp__ ........ ................ r81742 | michael.foord | 2010-06-05 05:17:02 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81739 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81739 | michael.foord | 2010-06-05 13:10:52 +0100 (Sat, 05 Jun 2010) | 1 line Removed the new max_diff argument to assertSequenceEqual. All unittest.TestCase assert methods that use difflib to produce failure messages now truncate overly long messages. New class attribute unittest.TestCase.maxDiff to configure this if necessary. Issue 8351. ........ ................ r81743 | mark.dickinson | 2010-06-05 05:38:00 -0700 (Sat, 05 Jun 2010) | 10 lines Blocked revisions 81740 via svnmerge ........ r81740 | mark.dickinson | 2010-06-05 13:14:43 +0100 (Sat, 05 Jun 2010) | 5 lines Issue #8627: Fix "XXX undetected error" from unchecked PyErr_WarnPy3k return. This is just a quick fix: if the warning is turned into an exception, the exception simply gets ignored. ........ ................ r81746 | mark.dickinson | 2010-06-05 05:52:23 -0700 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81744 via svnmerge ........ r81744 | mark.dickinson | 2010-06-05 13:51:21 +0100 (Sat, 05 Jun 2010) | 1 line Fix comment typo. ........ ................ r81748 | michael.foord | 2010-06-05 06:14:43 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81747 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81747 | michael.foord | 2010-06-05 13:58:39 +0100 (Sat, 05 Jun 2010) | 1 line unittest.TestCase.assertDictEqual and assertMultilineEqual provide better default failure messages in the event of long diffs. ........ ................ r81751 | mark.dickinson | 2010-06-05 06:27:17 -0700 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81749 via svnmerge ........ r81749 | mark.dickinson | 2010-06-05 14:18:33 +0100 (Sat, 05 Jun 2010) | 2 lines Fix test_py3kwarn not to test for __cmp__-related DeprecationWarning. ........ ................ r81754 | michael.foord | 2010-06-05 06:49:56 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81752 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81752 | michael.foord | 2010-06-05 14:38:16 +0100 (Sat, 05 Jun 2010) | 1 line unittest.TestCase assertion methods inform you when they have omitted an over long diff on failure. Issue 8351. ........ ................ r81755 | michael.foord | 2010-06-05 06:57:23 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81753 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81753 | michael.foord | 2010-06-05 14:48:27 +0100 (Sat, 05 Jun 2010) | 1 line Fix unittest tests after previous commit. ........ ................ r81757 | alexander.belopolsky | 2010-06-05 08:04:51 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81756 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81756 | alexander.belopolsky | 2010-06-05 10:54:26 -0400 (Sat, 05 Jun 2010) | 1 line Issue #8899: time.struct_time now has class and atribute docstrings. ........ ................ r81762 | michael.foord | 2010-06-05 12:58:25 -0700 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81761 via svnmerge ........ r81761 | michael.foord | 2010-06-05 20:51:38 +0100 (Sat, 05 Jun 2010) | 1 line Updated NEWS file. ........ ................ r81765 | michael.foord | 2010-06-05 14:01:08 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81763 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81763 | michael.foord | 2010-06-05 21:33:43 +0100 (Sat, 05 Jun 2010) | 1 line Tests for unittest.TestCase.maxDiff. ........ ................ r81766 | michael.foord | 2010-06-05 14:12:23 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81764 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81764 | michael.foord | 2010-06-05 21:59:00 +0100 (Sat, 05 Jun 2010) | 1 line Tests for issue 8302, skipped test in a setUpClass or a setUpModule are reported as skips rather than errors. ........ ................ r81768 | michael.foord | 2010-06-05 14:59:55 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81767 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81767 | michael.foord | 2010-06-05 22:57:03 +0100 (Sat, 05 Jun 2010) | 1 line Documentation updates for issues 8302 and 8351 (truncating excessive diffs in unittest failure messages and reporting SkipTest exceptions in setUpClass and setUpModule as skips rather than errors). ........ ................ r81771 | michael.foord | 2010-06-05 16:59:34 -0700 (Sat, 05 Jun 2010) | 9 lines Merged revisions 81770 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81770 | michael.foord | 2010-06-06 00:58:40 +0100 (Sun, 06 Jun 2010) | 1 line Code formatting change. ........ ................ r81778 | benjamin.peterson | 2010-06-05 19:14:27 -0700 (Sat, 05 Jun 2010) | 16 lines Blocked revisions 81772-81773,81777 via svnmerge ........ r81772 | benjamin.peterson | 2010-06-05 19:22:09 -0500 (Sat, 05 Jun 2010) | 1 line bump version to 2.7 rc1 ........ r81773 | benjamin.peterson | 2010-06-05 19:49:27 -0500 (Sat, 05 Jun 2010) | 1 line update pydoc-topics ........ r81777 | benjamin.peterson | 2010-06-05 21:09:33 -0500 (Sat, 05 Jun 2010) | 1 line careening towards 2.7rc2 we go ........ ................ r81779 | benjamin.peterson | 2010-06-05 19:32:09 -0700 (Sat, 05 Jun 2010) | 13 lines Merged revisions 81774-81775 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81774 | benjamin.peterson | 2010-06-05 19:50:58 -0500 (Sat, 05 Jun 2010) | 1 line remove extra space ........ r81775 | benjamin.peterson | 2010-06-05 19:54:29 -0500 (Sat, 05 Jun 2010) | 1 line fix sphinx warning with an extra space ........ ................ r81780 | benjamin.peterson | 2010-06-05 19:40:38 -0700 (Sat, 05 Jun 2010) | 1 line fix typo ................ r81781 | benjamin.peterson | 2010-06-05 19:41:24 -0700 (Sat, 05 Jun 2010) | 1 line reST indentation nit ................ r81782 | benjamin.peterson | 2010-06-05 19:44:41 -0700 (Sat, 05 Jun 2010) | 1 line bltn-file-objects don't exist in python3 ................ r81790 | tarek.ziade | 2010-06-06 13:18:42 -0700 (Sun, 06 Jun 2010) | 9 lines Merged revisions 81788 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81788 | tarek.ziade | 2010-06-06 22:05:20 +0200 (Sun, 06 Jun 2010) | 1 line Fixed #8909: now the doc details the size of the bitmap used in distutils' bdist_wininst ........ ................ r81792 | victor.stinner | 2010-06-06 13:27:51 -0700 (Sun, 06 Jun 2010) | 2 lines Simplify getbuffer(): convertbuffer() fails anyway if bf_getbuffer is NULL ................ r81794 | victor.stinner | 2010-06-06 13:38:02 -0700 (Sun, 06 Jun 2010) | 4 lines convertsimple(): call PyErr_NoMemory() on PyMem_NEW() failure Raise a more revelant error (MemoryError instead of TypeError) ................ r81806 | mark.dickinson | 2010-06-07 11:47:09 -0700 (Mon, 07 Jun 2010) | 1 line Fix naming inconsistency. ................ r81807 | victor.stinner | 2010-06-07 12:57:46 -0700 (Mon, 07 Jun 2010) | 2 lines Issue #8848: U / U# formats of Py_BuildValue() are just alias to s / s# ................ r81809 | victor.stinner | 2010-06-07 13:14:04 -0700 (Mon, 07 Jun 2010) | 3 lines Issue #8897: Fix sunau module, use bytes to write the header. Patch written by Thomas Jollans. ................ r81811 | victor.stinner | 2010-06-07 14:20:41 -0700 (Mon, 07 Jun 2010) | 9 lines Issue #8925: fix types of Py_Parse*() and Py_BuildValue() functions * Add links to Python types * Replace "string" by bytes or str * Replace "long" by "int" * Specify the default encoding * Fix reST syntax ("..note ::") * etc. ................ r81814 | benjamin.peterson | 2010-06-07 14:41:35 -0700 (Mon, 07 Jun 2010) | 9 lines Merged revisions 81813 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81813 | benjamin.peterson | 2010-06-07 16:37:09 -0500 (Mon, 07 Jun 2010) | 2 lines locale grouping strings should end in '\0' ........ ................ r81816 | ezio.melotti | 2010-06-07 14:57:18 -0700 (Mon, 07 Jun 2010) | 8 lines Blocked revisions 81769 via svnmerge ........ r81769 | ezio.melotti | 2010-06-06 01:28:10 +0300 (Sun, 06 Jun 2010) | 1 line Replace deprecated fail* methods with the equivalent assert* ones. ........ ................ r81818 | ezio.melotti | 2010-06-07 15:02:50 -0700 (Mon, 07 Jun 2010) | 8 lines Blocked revisions 81817 via svnmerge ........ r81817 | ezio.melotti | 2010-06-08 01:00:18 +0300 (Tue, 08 Jun 2010) | 1 line Silence deprecation warning in test___all__ caused by an import bsddb. ........ ................ r81821 | benjamin.peterson | 2010-06-07 15:24:18 -0700 (Mon, 07 Jun 2010) | 1 line use the 's' format code instead of 'U' ................ r81823 | benjamin.peterson | 2010-06-07 15:31:26 -0700 (Mon, 07 Jun 2010) | 9 lines Merged revisions 81820 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81820 | benjamin.peterson | 2010-06-07 17:23:23 -0500 (Mon, 07 Jun 2010) | 1 line correctly overflow when indexes are too large ........ ................ r81826 | benjamin.peterson | 2010-06-07 15:35:08 -0700 (Mon, 07 Jun 2010) | 9 lines Merged revisions 81824 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81824 | benjamin.peterson | 2010-06-07 17:32:44 -0500 (Mon, 07 Jun 2010) | 1 line remove extra byte and fix comment ........ ................ r81827 | benjamin.peterson | 2010-06-07 15:36:44 -0700 (Mon, 07 Jun 2010) | 8 lines Blocked revisions 81825 via svnmerge ........ r81825 | benjamin.peterson | 2010-06-07 17:33:09 -0500 (Mon, 07 Jun 2010) | 1 line use unicode literals ........ ................ r81829 | stefan.krah | 2010-06-08 06:26:49 -0700 (Tue, 08 Jun 2010) | 21 lines Blocked revisions 81669,81672,81683 via svnmerge ........ r81669 | stefan.krah | 2010-06-03 14:39:50 +0200 (Thu, 03 Jun 2010) | 9 lines Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. Thanks Thomas Dickey for answering questions about ncurses/ncursesw and readline! ........ r81672 | stefan.krah | 2010-06-03 16:25:16 +0200 (Thu, 03 Jun 2010) | 3 lines Use compiler rather than compiler_obj. Thanks Michael Foord for noticing. ........ r81683 | stefan.krah | 2010-06-04 11:49:20 +0200 (Fri, 04 Jun 2010) | 1 line Detect missing ldd on all systems. ........ ................ r81830 | stefan.krah | 2010-06-08 06:41:44 -0700 (Tue, 08 Jun 2010) | 9 lines Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. Thanks Thomas Dickey for answering questions about ncurses/ncursesw and readline! ................ r81831 | stefan.krah | 2010-06-08 07:00:52 -0700 (Tue, 08 Jun 2010) | 1 line Add note for r81830. ................ r81832 | r.david.murray | 2010-06-08 07:41:45 -0700 (Tue, 08 Jun 2010) | 2 lines Now that sunau has some tests, remove it from test_sundry. ................ r81835 | benjamin.peterson | 2010-06-08 07:57:22 -0700 (Tue, 08 Jun 2010) | 9 lines Merged revisions 81834 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81834 | benjamin.peterson | 2010-06-08 09:53:29 -0500 (Tue, 08 Jun 2010) | 1 line kill extra word ........ ................ r81838 | alexander.belopolsky | 2010-06-08 10:06:48 -0700 (Tue, 08 Jun 2010) | 1 line Added myself as a maintainer of time and datetime modules. ................ r81840 | alexander.belopolsky | 2010-06-08 11:59:20 -0700 (Tue, 08 Jun 2010) | 9 lines Merged revisions 81489 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81489 | georg.brandl | 2010-05-23 17:29:29 -0400 (Sun, 23 May 2010) | 1 line #1436346: make it more obvious that timetuple[7] is yday. ........ ................ r81841 | victor.stinner | 2010-06-08 13:46:00 -0700 (Tue, 08 Jun 2010) | 6 lines sys_pyfile_write() does nothing if file is NULL mywrite() falls back to the C file object if sys_pyfile_write() returns an error. This patch fixes a segfault is Py_FatalError() is called in an early stage of Python initialization. ................ r81843 | brian.curtin | 2010-06-08 13:57:52 -0700 (Tue, 08 Jun 2010) | 3 lines Fix a compile warning missed during porting (wchar_t/char) and move a variable declaration outside of a loop. #2810 was when this first went in. ................ r81844 | victor.stinner | 2010-06-08 14:00:13 -0700 (Tue, 08 Jun 2010) | 6 lines Py_FatalError(): don't sys sys.last_xxx variables Call PyErr_PrintEx(0) instead of PyErr_Print() to avoid a crash if Py_FatalError() is called in an early stage of Python initialization (if PySys is not yet initialized). ................ r81849 | victor.stinner | 2010-06-08 14:45:51 -0700 (Tue, 08 Jun 2010) | 7 lines PyArg_Parse*("Z#") raises an error for unknown type instead of ignoring the error and leave the pointer to the string and the size unchanged (not initialized). Fix also the type in the error message of "Z", "Z#" and "Y" formats. ................ r81851 | brian.curtin | 2010-06-08 15:27:07 -0700 (Tue, 08 Jun 2010) | 2 lines Fix #8946. Extra PyObject* parameter documented which doesn't exist. ................ r81854 | victor.stinner | 2010-06-08 15:54:19 -0700 (Tue, 08 Jun 2010) | 5 lines Issue #8838, #8339: Remove codecs.charbuffer_encode() and "t#" parsing format Remove last references to the "char buffer" of the buffer protocol from Python3. ................ r81856 | kristjan.jonsson | 2010-06-09 01:13:42 -0700 (Wed, 09 Jun 2010) | 2 lines http://bugs.python.org/issue8832 Issue minidom.unlink with a context manager ................ r81857 | stefan.krah | 2010-06-09 01:56:28 -0700 (Wed, 09 Jun 2010) | 3 lines Issue #8932: Skip required when compiled --without-threads. ................ r81862 | antoine.pitrou | 2010-06-09 09:38:55 -0700 (Wed, 09 Jun 2010) | 9 lines Merged revisions 81860 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81860 | antoine.pitrou | 2010-06-09 18:24:00 +0200 (mer., 09 juin 2010) | 3 lines Issue #8930: fix some C code indentation ........ ................ r81865 | alexander.belopolsky | 2010-06-09 10:11:01 -0700 (Wed, 09 Jun 2010) | 9 lines Merged revisions 81864 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81864 | alexander.belopolsky | 2010-06-09 13:08:11 -0400 (Wed, 09 Jun 2010) | 1 line Fixed markup of tm_isdst attribute. ........ ................ r81869 | victor.stinner | 2010-06-10 05:00:55 -0700 (Thu, 10 Jun 2010) | 4 lines Issue #8922: Normalize the encoding name in PyUnicode_AsEncodedString() to enable shortcuts for upper case encoding name. Add also a shortcut for "iso-8859-1" in PyUnicode_AsEncodedString() and PyUnicode_Decode(). ................ r81871 | victor.stinner | 2010-06-10 06:36:23 -0700 (Thu, 10 Jun 2010) | 4 lines Fix r81869: ISO-8859-15 was seen as an alias to ISO-8859-1 Don't use normalize_encoding() result if it is truncated. ................ r81873 | mark.dickinson | 2010-06-10 09:05:10 -0700 (Thu, 10 Jun 2010) | 4 lines Issue #8950: Make PyArg_Parse* with 'L' code raise for float inputs, instead of warning. This makes it consistent with the other integer codes. ................ r81874 | michael.foord | 2010-06-10 09:16:08 -0700 (Thu, 10 Jun 2010) | 9 lines Merged revisions 81853 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81853 | michael.foord | 2010-06-08 23:44:52 +0100 (Tue, 08 Jun 2010) | 1 line Issue 8948. cleanup functions are not run by unittest.TestCase.debug(), plus class and module teardowns are not run by unittest.TestSuite.debug(). ........ ................ r81875 | michael.foord | 2010-06-10 09:17:07 -0700 (Thu, 10 Jun 2010) | 9 lines Merged revisions 81859 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81859 | michael.foord | 2010-06-09 13:29:56 +0100 (Wed, 09 Jun 2010) | 1 line Typo correction. ........ ................ r81877 | michael.foord | 2010-06-10 09:33:34 -0700 (Thu, 10 Jun 2010) | 8 lines Blocked revisions 81876 via svnmerge ........ r81876 | michael.foord | 2010-06-10 17:32:00 +0100 (Thu, 10 Jun 2010) | 1 line NEWS update for issue 8948. ........ ................ r81879 | michael.foord | 2010-06-10 13:41:54 -0700 (Thu, 10 Jun 2010) | 9 lines Merged revisions 81878 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81878 | michael.foord | 2010-06-10 21:40:21 +0100 (Thu, 10 Jun 2010) | 2 lines Fix issue with nested test suites debug method and module setups. (unittest) ........ ................ r81883 | victor.stinner | 2010-06-10 17:36:33 -0700 (Thu, 10 Jun 2010) | 5 lines Issue #8965: initfsencoding() doesn't change the encoding on Mac OS X File system encoding have to be hardcoded to "utf-8" on Mac OS X. r81190 introduced a regression: the encoding was changed depending on the locale. ................ r81885 | victor.stinner | 2010-06-10 17:41:41 -0700 (Thu, 10 Jun 2010) | 2 lines test_sys: add a test on the file system encoding for darwin ................ r81891 | ezio.melotti | 2010-06-10 19:26:42 -0700 (Thu, 10 Jun 2010) | 9 lines Merged revisions 81889 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81889 | ezio.melotti | 2010-06-11 05:21:25 +0300 (Fri, 11 Jun 2010) | 1 line Remove extra ] from itertools.count docstring. ........ ................ r81893 | mark.dickinson | 2010-06-11 03:44:52 -0700 (Fri, 11 Jun 2010) | 3 lines Issue #8188: Comparisons between Decimal objects and other numeric objects (Fraction, float, complex, int) now all function as expected. ................ r81894 | mark.dickinson | 2010-06-11 03:46:57 -0700 (Fri, 11 Jun 2010) | 1 line Fix issue number typo. ................ r81895 | alexander.belopolsky | 2010-06-11 09:04:59 -0700 (Fri, 11 Jun 2010) | 2 lines Issue #3129: Trailing digits in format string are no longer ignored. ................ r81896 | mark.dickinson | 2010-06-11 09:49:20 -0700 (Fri, 11 Jun 2010) | 1 line Fix typo in docstring. ................ r81897 | mark.dickinson | 2010-06-11 09:56:34 -0700 (Fri, 11 Jun 2010) | 1 line Avoid possible undefined behaviour from signed overflow. ................ r81898 | mark.dickinson | 2010-06-11 12:05:08 -0700 (Fri, 11 Jun 2010) | 1 line Fix an incorrect return type. ................ r81901 | victor.stinner | 2010-06-11 12:24:36 -0700 (Fri, 11 Jun 2010) | 8 lines Blocked revisions 81899 via svnmerge ........ r81899 | victor.stinner | 2010-06-11 21:22:28 +0200 (ven., 11 juin 2010) | 2 lines Issue #8362: Add Misc/maintainers.rst: list of module maintainers ........ ................ r81902 | mark.dickinson | 2010-06-11 12:50:30 -0700 (Fri, 11 Jun 2010) | 1 line Fix more undefined-behaviour inducing overflow checks in struct module. ................ r81905 | mark.dickinson | 2010-06-11 13:29:09 -0700 (Fri, 11 Jun 2010) | 10 lines Blocked revisions 81904 via svnmerge ........ r81904 | mark.dickinson | 2010-06-11 21:27:05 +0100 (Fri, 11 Jun 2010) | 4 lines Fix possible undefined behaviour from signed overflow in struct module. Backport of revisions 81897, 81898 and 81902 from py3k. ........ ................ r81908 | antoine.pitrou | 2010-06-11 14:46:32 -0700 (Fri, 11 Jun 2010) | 11 lines Merged revisions 81907 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81907 | antoine.pitrou | 2010-06-11 23:42:26 +0200 (ven., 11 juin 2010) | 5 lines Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). ........ ................ r81911 | victor.stinner | 2010-06-11 14:50:30 -0700 (Fri, 11 Jun 2010) | 3 lines Issue #8966: If a ctypes structure field is an array of c_char, convert its value to bytes instead of str (as done for c_char and c_char_p). ................ r81912 | benjamin.peterson | 2010-06-11 14:53:07 -0700 (Fri, 11 Jun 2010) | 9 lines Merged revisions 81906 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81906 | benjamin.peterson | 2010-06-11 16:40:37 -0500 (Fri, 11 Jun 2010) | 1 line different spellings are just unacceptable ........ ................ r81914 | victor.stinner | 2010-06-11 15:09:51 -0700 (Fri, 11 Jun 2010) | 2 lines locale.bindtextdomain(): use PyUnicode_FSConverter() to parse the filename ................ r81916 | victor.stinner | 2010-06-11 15:17:52 -0700 (Fri, 11 Jun 2010) | 2 lines Issue #8965: Add a regression test to test_sys with LANG=C ................ r81918 | victor.stinner | 2010-06-11 15:27:14 -0700 (Fri, 11 Jun 2010) | 2 lines readline: use PyUnicode_FSConverter() to parse filenames ................ r81920 | victor.stinner | 2010-06-11 16:06:13 -0700 (Fri, 11 Jun 2010) | 2 lines Issue #8965: Write more tests for sys.getfilesystemencoding() ................ r81923 | victor.stinner | 2010-06-11 16:30:12 -0700 (Fri, 11 Jun 2010) | 16 lines Fix some bugs in c-api/arg.rst documentation * replace "the default encoding" by "'utf-8' encoding" * fix "w" / "w*" / "w#" doc: similar to "y" / "y*" / "y#" and not "s" / "s*" / "s#" * "u#": remove "Non-Unicode objects are handled by interpreting their read-buffer pointer ...", it's no more true * "es", "es#": remove "... and objects convertible to Unicode into a character buffer", it's no more true * Py_BuildValue(), "K" and "L" formats: specify the name of the C type on Windows (_int64 / unsigned _int64) as done for PyArg_Parse*() long long types --CETTE ligne, et les suivantes ci-dessous, seront ignor?es-- M Doc/c-api/arg.rst ................ r81925 | victor.stinner | 2010-06-11 16:46:47 -0700 (Fri, 11 Jun 2010) | 4 lines Issue #8784: Set tarfile default encoding to 'utf-8' on Windows. Note: file system encoding cannot be None anymore (since r81190, issue #8610). ................ r81927 | victor.stinner | 2010-06-11 16:56:51 -0700 (Fri, 11 Jun 2010) | 3 lines Issue #8969: On Windows, use mbcs codec in strict mode to encode and decode filenames and enable os.fsencode(). ................ r81929 | brett.cannon | 2010-06-11 17:38:29 -0700 (Fri, 11 Jun 2010) | 5 lines When dealing with __import__ for detecting a global state change made by a test, make sure to check if __builtins__ is a dict or not. Discovered when running importlib.test.regrtest. ................ r81930 | brett.cannon | 2010-06-11 17:39:28 -0700 (Fri, 11 Jun 2010) | 4 lines Calling __import__ as a method technically works, but really should be wrapped in a staticmethod. This is important for when __import__ is set to a function defined in Python instead of C. ................ r81936 | mark.dickinson | 2010-06-12 02:10:14 -0700 (Sat, 12 Jun 2010) | 2 lines Silence 'unused variable' gcc warning. Patch by ?ric Araujo. ................ r81937 | mark.dickinson | 2010-06-12 02:24:01 -0700 (Sat, 12 Jun 2010) | 2 lines Issue #8981: Remove _struct.__version__. ................ r81938 | mark.dickinson | 2010-06-12 02:25:13 -0700 (Sat, 12 Jun 2010) | 1 line Remove unused variable. ................ r81944 | nick.coghlan | 2010-06-12 06:42:46 -0700 (Sat, 12 Jun 2010) | 9 lines Merged revisions 80578 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r80578 | nick.coghlan | 2010-04-29 00:29:06 +1000 (Thu, 29 Apr 2010) | 1 line Issue 7490: make IGNORE_EXCEPTION_DETAIL also ignore details of the module containing the exception under test (original patch by Lennart Regebro) ........ ................ r81946 | nick.coghlan | 2010-06-12 06:46:56 -0700 (Sat, 12 Jun 2010) | 8 lines Blocked revisions 81945 via svnmerge ........ r81945 | nick.coghlan | 2010-06-12 23:45:37 +1000 (Sat, 12 Jun 2010) | 1 line Backport a fix from Py3k for a potentially misleading example ........ ................ r81947 | mark.dickinson | 2010-06-12 08:17:02 -0700 (Sat, 12 Jun 2010) | 3 lines Issue #8973: Add __all__ to struct module, so that help(struct) correctly displays information for the struct.Struct class. ................ r81948 | mark.dickinson | 2010-06-12 08:19:23 -0700 (Sat, 12 Jun 2010) | 1 line Remove accidental (yet-to-be-reviewed) docstring changes included in r81947. ................ r81949 | mark.dickinson | 2010-06-12 08:43:45 -0700 (Sat, 12 Jun 2010) | 1 line Issue #8973: Improve struct module docstrings. ................ r81950 | mark.dickinson | 2010-06-12 09:30:53 -0700 (Sat, 12 Jun 2010) | 1 line More struct module docs and docstring tweaks. ................ r81951 | mark.dickinson | 2010-06-12 09:37:53 -0700 (Sat, 12 Jun 2010) | 1 line Fix mild type confusion in decimal module docstring. ................ r81952 | alexander.belopolsky | 2010-06-12 10:18:45 -0700 (Sat, 12 Jun 2010) | 1 line Added acknowlegement for Issue #3129 ................ r81954 | benjamin.peterson | 2010-06-12 10:54:44 -0700 (Sat, 12 Jun 2010) | 9 lines Merged revisions 81953 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81953 | benjamin.peterson | 2010-06-12 12:47:06 -0500 (Sat, 12 Jun 2010) | 1 line fix warning with ucs4 ........ ................ r81955 | mark.dickinson | 2010-06-12 11:20:47 -0700 (Sat, 12 Jun 2010) | 1 line Issue #8469: add standard sizes to struct docs table. ................ r81956 | mark.dickinson | 2010-06-12 11:37:54 -0700 (Sat, 12 Jun 2010) | 2 lines Issue #8469: Reorder struct module sections for clarity; other minor tweaks. ................ r81958 | mark.dickinson | 2010-06-12 11:54:20 -0700 (Sat, 12 Jun 2010) | 11 lines Blocked revisions 81957 via svnmerge ........ r81957 | mark.dickinson | 2010-06-12 19:50:34 +0100 (Sat, 12 Jun 2010) | 5 lines Issue #8469: Add standard sizes to table in struct documentation; additional clarifications and documentation tweaks. Backport of revisions 81955-81956 from py3k. ........ ................ r81961 | alexander.belopolsky | 2010-06-12 12:36:28 -0700 (Sat, 12 Jun 2010) | 1 line Issue #8973: Expanded Struct.__doc__. ................ r81965 | mark.dickinson | 2010-06-13 02:17:13 -0700 (Sun, 13 Jun 2010) | 1 line Remove unnecessary brackets from docstring optional arguments. ................ r81968 | mark.dickinson | 2010-06-13 03:52:38 -0700 (Sun, 13 Jun 2010) | 11 lines Merged revisions 81967 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81967 | mark.dickinson | 2010-06-13 11:50:29 +0100 (Sun, 13 Jun 2010) | 4 lines Issue #8986: erfc was raising OverflowError on Linux for arguments in the (approximate) range (-27.3, 30.0), as a result of an escaped errno value. ........ ................ r81970 | mark.dickinson | 2010-06-13 04:07:57 -0700 (Sun, 13 Jun 2010) | 9 lines Merged revisions 81969 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81969 | mark.dickinson | 2010-06-13 12:07:00 +0100 (Sun, 13 Jun 2010) | 1 line Add ?ric Araujo to Misc/ACKS for doc work and many patch and commit reviews. ........ ................ r81972 | mark.dickinson | 2010-06-13 05:02:07 -0700 (Sun, 13 Jun 2010) | 9 lines Merged revisions 81971 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81971 | mark.dickinson | 2010-06-13 13:01:34 +0100 (Sun, 13 Jun 2010) | 1 line Ezio Melotti was missing from Misc/ACKS. ........ ................ r81973 | victor.stinner | 2010-06-13 11:21:50 -0700 (Sun, 13 Jun 2010) | 4 lines Issue #8592: PyArg_Parse*() functions raise a TypeError for "y", "u" and "Z" formats if the string contains a null byte/character. Write unit tests for string formats. ................ r81974 | victor.stinner | 2010-06-13 13:31:26 -0700 (Sun, 13 Jun 2010) | 4 lines getargs.c: remove last reference to "t#" format "t#" format was removed from convertitem() (convertsimple) but not skipitem(). ................ r81981 | alexander.belopolsky | 2010-06-14 07:15:50 -0700 (Mon, 14 Jun 2010) | 3 lines Issue #5094: The ``datetime`` module now has a simple concrete class implementing ``datetime.tzinfo`` interface. ................ r81988 | alexander.belopolsky | 2010-06-14 10:32:03 -0700 (Mon, 14 Jun 2010) | 1 line Issue 6280: Tests and simpler implementation for calendar.timegm ................ r81989 | alexander.belopolsky | 2010-06-14 11:33:19 -0700 (Mon, 14 Jun 2010) | 1 line Undo r81988 code change leaving added test. ................ Added: python/branches/py3k-jit/Lib/test/test_sunau.py - copied unchanged from r81989, /python/branches/py3k/Lib/test/test_sunau.py Modified: python/branches/py3k-jit/ (props changed) python/branches/py3k-jit/Doc/c-api/arg.rst python/branches/py3k-jit/Doc/c-api/buffer.rst python/branches/py3k-jit/Doc/distutils/builtdist.rst python/branches/py3k-jit/Doc/extending/newtypes.rst python/branches/py3k-jit/Doc/library/argparse.rst python/branches/py3k-jit/Doc/library/datetime.rst python/branches/py3k-jit/Doc/library/decimal.rst python/branches/py3k-jit/Doc/library/dis.rst python/branches/py3k-jit/Doc/library/doctest.rst python/branches/py3k-jit/Doc/library/ftplib.rst python/branches/py3k-jit/Doc/library/functions.rst python/branches/py3k-jit/Doc/library/io.rst python/branches/py3k-jit/Doc/library/os.rst python/branches/py3k-jit/Doc/library/socket.rst python/branches/py3k-jit/Doc/library/sqlite3.rst python/branches/py3k-jit/Doc/library/ssl.rst python/branches/py3k-jit/Doc/library/struct.rst python/branches/py3k-jit/Doc/library/subprocess.rst python/branches/py3k-jit/Doc/library/sysconfig.rst python/branches/py3k-jit/Doc/library/tarfile.rst python/branches/py3k-jit/Doc/library/time.rst python/branches/py3k-jit/Doc/library/unittest.rst python/branches/py3k-jit/Doc/library/urllib.parse.rst python/branches/py3k-jit/Doc/library/winreg.rst python/branches/py3k-jit/Doc/library/xml.dom.minidom.rst python/branches/py3k-jit/Doc/tools/sphinxext/pyspecific.py python/branches/py3k-jit/Doc/whatsnew/3.2.rst python/branches/py3k-jit/Include/longobject.h python/branches/py3k-jit/Lib/base64.py python/branches/py3k-jit/Lib/ctypes/test/test_bytes.py python/branches/py3k-jit/Lib/ctypes/test/test_structures.py python/branches/py3k-jit/Lib/decimal.py python/branches/py3k-jit/Lib/distutils/unixccompiler.py python/branches/py3k-jit/Lib/doctest.py python/branches/py3k-jit/Lib/email/charset.py python/branches/py3k-jit/Lib/email/encoders.py python/branches/py3k-jit/Lib/email/test/test_email.py python/branches/py3k-jit/Lib/ftplib.py python/branches/py3k-jit/Lib/html/parser.py python/branches/py3k-jit/Lib/http/client.py python/branches/py3k-jit/Lib/logging/config.py python/branches/py3k-jit/Lib/os.py python/branches/py3k-jit/Lib/sqlite3/test/dbapi.py python/branches/py3k-jit/Lib/struct.py python/branches/py3k-jit/Lib/sunau.py python/branches/py3k-jit/Lib/sysconfig.py python/branches/py3k-jit/Lib/tarfile.py python/branches/py3k-jit/Lib/test/math_testcases.txt python/branches/py3k-jit/Lib/test/regrtest.py python/branches/py3k-jit/Lib/test/test_base64.py python/branches/py3k-jit/Lib/test/test_builtin.py python/branches/py3k-jit/Lib/test/test_calendar.py python/branches/py3k-jit/Lib/test/test_capi.py python/branches/py3k-jit/Lib/test/test_codecs.py python/branches/py3k-jit/Lib/test/test_curses.py python/branches/py3k-jit/Lib/test/test_datetime.py python/branches/py3k-jit/Lib/test/test_descr.py python/branches/py3k-jit/Lib/test/test_doctest.py python/branches/py3k-jit/Lib/test/test_enumerate.py python/branches/py3k-jit/Lib/test/test_fractions.py python/branches/py3k-jit/Lib/test/test_ftplib.py python/branches/py3k-jit/Lib/test/test_getargs2.py python/branches/py3k-jit/Lib/test/test_htmlparser.py python/branches/py3k-jit/Lib/test/test_httplib.py python/branches/py3k-jit/Lib/test/test_long.py python/branches/py3k-jit/Lib/test/test_math.py python/branches/py3k-jit/Lib/test/test_minidom.py python/branches/py3k-jit/Lib/test/test_numeric_tower.py python/branches/py3k-jit/Lib/test/test_os.py python/branches/py3k-jit/Lib/test/test_socketserver.py python/branches/py3k-jit/Lib/test/test_ssl.py python/branches/py3k-jit/Lib/test/test_struct.py python/branches/py3k-jit/Lib/test/test_sundry.py python/branches/py3k-jit/Lib/test/test_sys.py python/branches/py3k-jit/Lib/test/test_sysconfig.py python/branches/py3k-jit/Lib/test/test_tarfile.py python/branches/py3k-jit/Lib/test/test_tcl.py python/branches/py3k-jit/Lib/test/test_unicode.py python/branches/py3k-jit/Lib/test/test_urllib2.py python/branches/py3k-jit/Lib/test/test_winreg.py python/branches/py3k-jit/Lib/test/test_winsound.py python/branches/py3k-jit/Lib/test/testtar.tar python/branches/py3k-jit/Lib/tkinter/_fix.py python/branches/py3k-jit/Lib/unittest/case.py python/branches/py3k-jit/Lib/unittest/loader.py python/branches/py3k-jit/Lib/unittest/suite.py python/branches/py3k-jit/Lib/unittest/test/test_case.py python/branches/py3k-jit/Lib/unittest/test/test_runner.py python/branches/py3k-jit/Lib/unittest/test/test_setups.py python/branches/py3k-jit/Lib/unittest/util.py python/branches/py3k-jit/Lib/urllib/request.py python/branches/py3k-jit/Lib/webbrowser.py python/branches/py3k-jit/Lib/xml/dom/minidom.py python/branches/py3k-jit/Mac/Tools/pythonw.c python/branches/py3k-jit/Misc/ACKS python/branches/py3k-jit/Misc/NEWS python/branches/py3k-jit/Misc/developers.txt python/branches/py3k-jit/Misc/maintainers.rst python/branches/py3k-jit/Modules/_codecsmodule.c python/branches/py3k-jit/Modules/_ctypes/_ctypes.c python/branches/py3k-jit/Modules/_ctypes/cfield.c python/branches/py3k-jit/Modules/_localemodule.c python/branches/py3k-jit/Modules/_multiprocessing/multiprocessing.h python/branches/py3k-jit/Modules/_sqlite/connection.c python/branches/py3k-jit/Modules/_struct.c python/branches/py3k-jit/Modules/_testcapimodule.c python/branches/py3k-jit/Modules/config.c.in python/branches/py3k-jit/Modules/datetimemodule.c python/branches/py3k-jit/Modules/itertoolsmodule.c python/branches/py3k-jit/Modules/mathmodule.c python/branches/py3k-jit/Modules/readline.c python/branches/py3k-jit/Modules/timemodule.c python/branches/py3k-jit/Objects/abstract.c python/branches/py3k-jit/Objects/bytearrayobject.c python/branches/py3k-jit/Objects/bytesobject.c python/branches/py3k-jit/Objects/exceptions.c python/branches/py3k-jit/Objects/longobject.c python/branches/py3k-jit/Objects/stringlib/formatter.h python/branches/py3k-jit/Objects/stringlib/string_format.h python/branches/py3k-jit/Objects/typeobject.c python/branches/py3k-jit/Objects/unicodeobject.c python/branches/py3k-jit/PC/winreg.c python/branches/py3k-jit/Parser/asdl_c.py python/branches/py3k-jit/Python/Python-ast.c python/branches/py3k-jit/Python/ceval.c python/branches/py3k-jit/Python/errors.c python/branches/py3k-jit/Python/getargs.c python/branches/py3k-jit/Python/modsupport.c python/branches/py3k-jit/Python/pythonrun.c python/branches/py3k-jit/Python/symtable.c python/branches/py3k-jit/Python/sysmodule.c python/branches/py3k-jit/Tools/i18n/msgfmt.py python/branches/py3k-jit/Tools/scripts/serve.py python/branches/py3k-jit/configure python/branches/py3k-jit/configure.in python/branches/py3k-jit/setup.py Modified: python/branches/py3k-jit/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k-jit/Doc/c-api/arg.rst (original) +++ python/branches/py3k-jit/Doc/c-api/arg.rst Wed Jun 16 18:21:24 2010 @@ -53,13 +53,13 @@ drop int support. It is best to always define :cmacro:`PY_SSIZE_T_CLEAN`. -``s`` (Unicode object) [const char \*] +``s`` (:class:`str`) [const char \*] Convert a Unicode object to a C pointer to a character string. A pointer to an existing string is stored in the character pointer variable whose address you pass. The C string is NUL-terminated. The Python string must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. Unicode objects are converted - to C strings using the default encoding. If this conversion fails, a + to C strings using ``'utf-8'`` encoding. If this conversion fails, a :exc:`UnicodeError` is raised. .. note:: @@ -68,118 +68,111 @@ preferrable to use the ``O&`` format with :cfunc:`PyUnicode_FSConverter` as *converter*. -``s*`` (Unicode object or any buffer compatible object) [Py_buffer] +``s*`` (:class:`str`, :class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer] This format accepts Unicode objects as well as objects supporting the - buffer protocol (such as :class:`bytes` or :class:`bytearray` objects). + buffer protocol. It fills a :ctype:`Py_buffer` structure provided by the caller. - Unicode objects are converted to C strings using the default encoding. In this case the resulting C string may contain embedded NUL bytes. + Unicode objects are converted to C strings using ``'utf-8'`` encoding. -``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int or :ctype:`Py_ssize_t`] +``s#`` (:class:`str`, :class:`bytes` or read-only buffer compatible object) [const char \*, int or :ctype:`Py_ssize_t`] Like ``s*``, except that it doesn't accept mutable buffer-like objects such as :class:`bytearray`. The result is stored into two C variables, the first one a pointer to a C string, the second one its length. - The string may contain embedded null bytes. + The string may contain embedded null bytes. Unicode objects are converted + to C strings using ``'utf-8'`` encoding. -``z`` (Unicode object or ``None``) [const char \*] +``z`` (:class:`str` or ``None``) [const char \*] Like ``s``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``z*`` (Unicode object or ``None`` or any buffer compatible object) [Py_buffer] +``z*`` (:class:`str`, :class:`bytes`, :class:`bytearray`, buffer compatible object or ``None``) [Py_buffer] Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :ctype:`Py_buffer` structure is set to *NULL*. -``z#`` (Unicode object or ``None`` or any read buffer compatible object) [const char \*, int] +``z#`` (:class:`str`, :class:`bytes`, read-only buffer compatible object or ``None``) [const char \*, int] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``y`` (bytes object) [const char \*] +``y`` (:class:`bytes`) [const char \*] This format converts a bytes-like object to a C pointer to a character string; it does not accept Unicode objects. The bytes buffer must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. -``y*`` (any buffer compatible object) [Py_buffer \*] +``y*`` (:class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer \*] This variant on ``s*`` doesn't accept Unicode objects, only objects supporting the buffer protocol. **This is the recommended way to accept binary data.** -``y#`` (bytes object) [const char \*, int] +``y#`` (:class:`bytes`) [const char \*, int] This variant on ``s#`` doesn't accept Unicode objects, only bytes-like objects. -``S`` (bytes object) [PyBytesObject \*] +``S`` (:class:`bytes`) [PyBytesObject \*] Requires that the Python object is a :class:`bytes` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a bytes object. The C variable may also be declared as :ctype:`PyObject\*`. -``Y`` (bytearray object) [PyByteArrayObject \*] +``Y`` (:class:`bytearray`) [PyByteArrayObject \*] Requires that the Python object is a :class:`bytearray` object, without attempting any conversion. Raises :exc:`TypeError` if the object is not - a bytearray object. The C variable may also be declared as :ctype:`PyObject\*`. + a :class:`bytearray` object. The C variable may also be declared as :ctype:`PyObject\*`. -``u`` (Unicode object) [Py_UNICODE \*] +``u`` (:class:`str`) [Py_UNICODE \*] Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of Unicode characters. You must pass the address of a :ctype:`Py_UNICODE` pointer variable, which will be filled with the pointer to an existing Unicode buffer. Please note that the width of a :ctype:`Py_UNICODE` character depends on compilation options (it is either 16 or 32 bits). + The Python string must not contain embedded NUL characters; if it does, + a :exc:`TypeError` exception is raised. - ..note :: + .. note:: Since ``u`` doesn't give you back the length of the string, and it may contain embedded NUL characters, it is recommended to use ``u#`` or ``U`` instead. -``u#`` (Unicode object) [Py_UNICODE \*, int] +``u#`` (:class:`str`) [Py_UNICODE \*, int] This variant on ``u`` stores into two C variables, the first one a pointer to a - Unicode data buffer, the second one its length. Non-Unicode objects are handled - by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` - array. + Unicode data buffer, the second one its length. -``Z`` (Unicode or ``None``) [Py_UNICODE \*] +``Z`` (:class:`str` or ``None``) [Py_UNICODE \*] Like ``u``, but the Python object may also be ``None``, in which case the :ctype:`Py_UNICODE` pointer is set to *NULL*. -``Z#`` (Unicode or ``None``) [Py_UNICODE \*, int] +``Z#`` (:class:`str` or ``None``) [Py_UNICODE \*, int] Like ``u#``, but the Python object may also be ``None``, in which case the :ctype:`Py_UNICODE` pointer is set to *NULL*. -``U`` (Unicode object) [PyUnicodeObject \*] +``U`` (:class:`str`) [PyUnicodeObject \*] Requires that the Python object is a Unicode object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a Unicode object. The C variable may also be declared as :ctype:`PyObject\*`. -``t#`` (read-only character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-only buffer - interface. The :ctype:`char\*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. - -``w`` (read-write character buffer) [char \*] - Similar to ``s``, but accepts any object which implements the read-write buffer +``w`` (:class:`bytearray` or read-write character buffer) [char \*] + Similar to ``y``, but accepts any object which implements the read-write buffer interface. The caller must determine the length of the buffer by other means, or use ``w#`` instead. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``w*`` (read-write byte-oriented buffer) [Py_buffer] - This is to ``w`` what ``s*`` is to ``s``. +``w*`` (:class:`bytearray` or read-write byte-oriented buffer) [Py_buffer] + This is to ``w`` what ``y*`` is to ``y``. -``w#`` (read-write character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-write buffer +``w#`` (:class:`bytearray` or read-write character buffer) [char \*, int] + Like ``y#``, but accepts any object which implements the read-write buffer interface. The :ctype:`char \*` variable is set to point to the first byte of the buffer, and the :ctype:`int` is set to the length of the buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - This variant on ``s`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. It only works for encoded data without embedded - NUL bytes. +``es`` (:class:`str`) [const char \*encoding, char \*\*buffer] + This variant on ``s`` is used for encoding Unicode into a character buffer. + It only works for encoded data without embedded NUL bytes. This format requires two arguments. The first is only used as input, and must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. + NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a :ctype:`char\*\*`; the value of the pointer it references will be set to a buffer with the contents of the argument text. @@ -190,19 +183,19 @@ allocated storage. The caller is responsible for calling :cfunc:`PyMem_Free` to free the allocated buffer after use. -``et`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es`` except that 8-bit string objects are passed through without - recoding them. Instead, the implementation assumes that the string object uses +``et`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer] + Same as ``es`` except that byte string objects are passed through without + recoding them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. -``es#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - This variant on ``s#`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. Unlike the ``es`` format, this variant allows - input data which contains NUL characters. +``es#`` (:class:`str`) [const char \*encoding, char \*\*buffer, int \*buffer_length] + This variant on ``s#`` is used for encoding Unicode into a character buffer. + Unlike the ``es`` format, this variant allows input data which contains NUL + characters. It requires three arguments. The first is only used as input, and must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. + NUL-terminated string, or *NULL*, in which case ``'utf-8'`` encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a :ctype:`char\*\*`; the value of the pointer it references will be set to a buffer with the contents of the argument text. @@ -226,71 +219,71 @@ In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. -``et#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - Same as ``es#`` except that string objects are passed through without recoding - them. Instead, the implementation assumes that the string object uses the +``et#`` (:class:`str`, :class:`bytes` or :class:`bytearray`) [const char \*encoding, char \*\*buffer, int \*buffer_length] + Same as ``es#`` except that byte string objects are passed through without recoding + them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. Numbers ------- -``b`` (integer) [unsigned char] +``b`` (:class:`int`) [unsigned char] Convert a nonnegative Python integer to an unsigned tiny int, stored in a C :ctype:`unsigned char`. -``B`` (integer) [unsigned char] +``B`` (:class:`int`) [unsigned char] Convert a Python integer to a tiny int without overflow checking, stored in a C :ctype:`unsigned char`. -``h`` (integer) [short int] +``h`` (:class:`int`) [short int] Convert a Python integer to a C :ctype:`short int`. -``H`` (integer) [unsigned short int] +``H`` (:class:`int`) [unsigned short int] Convert a Python integer to a C :ctype:`unsigned short int`, without overflow checking. -``i`` (integer) [int] +``i`` (:class:`int`) [int] Convert a Python integer to a plain C :ctype:`int`. -``I`` (integer) [unsigned int] +``I`` (:class:`int`) [unsigned int] Convert a Python integer to a C :ctype:`unsigned int`, without overflow checking. -``l`` (integer) [long int] +``l`` (:class:`int`) [long int] Convert a Python integer to a C :ctype:`long int`. -``k`` (integer) [unsigned long] +``k`` (:class:`int`) [unsigned long] Convert a Python integer to a C :ctype:`unsigned long` without overflow checking. -``L`` (integer) [PY_LONG_LONG] +``L`` (:class:`int`) [PY_LONG_LONG] Convert a Python integer to a C :ctype:`long long`. This format is only available on platforms that support :ctype:`long long` (or :ctype:`_int64` on Windows). -``K`` (integer) [unsigned PY_LONG_LONG] +``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a Python integer to a C :ctype:`unsigned long long` without overflow checking. This format is only available on platforms that support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows). -``n`` (integer) [Py_ssize_t] +``n`` (:class:`int`) [Py_ssize_t] Convert a Python integer to a C :ctype:`Py_ssize_t`. -``c`` (bytes object of length 1) [char] +``c`` (:class:`bytes` of length 1) [char] Convert a Python byte, represented as a :class:`bytes` object of length 1, to a C :ctype:`char`. -``C`` (Unicode object of length 1) [int] - Convert a Python character, represented as a :class:`str`: object of +``C`` (:class:`str` of length 1) [int] + Convert a Python character, represented as a :class:`str` object of length 1, to a C :ctype:`int`. -``f`` (float) [float] +``f`` (:class:`float`) [float] Convert a Python floating point number to a C :ctype:`float`. -``d`` (float) [double] +``d`` (:class:`float`) [double] Convert a Python floating point number to a C :ctype:`double`. -``D`` (complex) [Py_complex] +``D`` (:class:`complex`) [Py_complex] Convert a Python complex number to a C :ctype:`Py_complex` structure. Other objects @@ -330,7 +323,7 @@ .. versionchanged:: 3.1 Py_CLEANUP_SUPPORTED was added. -``(items)`` (tuple) [*matching-items*] +``(items)`` (:class:`tuple`) [*matching-items*] The object must be a Python sequence whose length is the number of format units in *items*. The C arguments must correspond to the individual format units in *items*. Format units for sequences may be nested. @@ -498,95 +491,96 @@ not within format units such as ``s#``). This can be used to make long format strings a tad more readable. - ``s`` (string) [char \*] - Convert a null-terminated C string to a Python object. If the C string pointer - is *NULL*, ``None`` is used. - - ``s#`` (string) [char \*, int] - Convert a C string and its length to a Python object. If the C string pointer - is *NULL*, the length is ignored and ``None`` is returned. + ``s`` (:class:`str` or ``None``) [char \*] + Convert a null-terminated C string to a Python object using ``'utf-8'`` + encoding. If the C string pointer is *NULL*, ``None`` is used. + + ``s#`` (:class:`str` or ``None``) [char \*, int] + Convert a C string and its length to a Python object using ``'utf-8'`` + encoding. If the C string pointer is *NULL*, the length is ignored and + ``None`` is returned. - ``y`` (bytes) [char \*] + ``y`` (:class:`bytes`) [char \*] This converts a C string to a Python :func:`bytes` object. If the C string pointer is *NULL*, ``None`` is returned. - ``y#`` (bytes) [char \*, int] + ``y#`` (:class:`bytes`) [char \*, int] This converts a C string and its lengths to a Python object. If the C string pointer is *NULL*, ``None`` is returned. - ``z`` (string or ``None``) [char \*] + ``z`` (:class:`str` or ``None``) [char \*] Same as ``s``. - ``z#`` (string or ``None``) [char \*, int] + ``z#`` (:class:`str` or ``None``) [char \*, int] Same as ``s#``. - ``u`` (Unicode string) [Py_UNICODE \*] + ``u`` (:class:`str`) [Py_UNICODE \*] Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned. - ``u#`` (Unicode string) [Py_UNICODE \*, int] + ``u#`` (:class:`str`) [Py_UNICODE \*, int] Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored and ``None`` is returned. - ``U`` (string) [char \*] - Convert a null-terminated C string to a Python unicode object. If the C string - pointer is *NULL*, ``None`` is used. - - ``U#`` (string) [char \*, int] - Convert a C string and its length to a Python unicode object. If the C string - pointer is *NULL*, the length is ignored and ``None`` is returned. + ``U`` (:class:`str` or ``None``) [char \*] + Same as ``s``. + + ``U#`` (:class:`str` or ``None``) [char \*, int] + Same as ``s#``. - ``i`` (integer) [int] + ``i`` (:class:`int`) [int] Convert a plain C :ctype:`int` to a Python integer object. - ``b`` (integer) [char] + ``b`` (:class:`int`) [char] Convert a plain C :ctype:`char` to a Python integer object. - ``h`` (integer) [short int] + ``h`` (:class:`int`) [short int] Convert a plain C :ctype:`short int` to a Python integer object. - ``l`` (integer) [long int] + ``l`` (:class:`int`) [long int] Convert a C :ctype:`long int` to a Python integer object. - ``B`` (integer) [unsigned char] + ``B`` (:class:`int`) [unsigned char] Convert a C :ctype:`unsigned char` to a Python integer object. - ``H`` (integer) [unsigned short int] + ``H`` (:class:`int`) [unsigned short int] Convert a C :ctype:`unsigned short int` to a Python integer object. - ``I`` (integer) [unsigned int] + ``I`` (:class:`int`) [unsigned int] Convert a C :ctype:`unsigned int` to a Python integer object. - ``k`` (integer) [unsigned long] + ``k`` (:class:`int`) [unsigned long] Convert a C :ctype:`unsigned long` to a Python integer object. - ``L`` (long) [PY_LONG_LONG] + ``L`` (:class:`int`) [PY_LONG_LONG] Convert a C :ctype:`long long` to a Python integer object. Only available - on platforms that support :ctype:`long long`. + on platforms that support :ctype:`long long` (or :ctype:`_int64` on + Windows). - ``K`` (long) [unsigned PY_LONG_LONG] + ``K`` (:class:`int`) [unsigned PY_LONG_LONG] Convert a C :ctype:`unsigned long long` to a Python integer object. Only - available on platforms that support :ctype:`unsigned long long`. + available on platforms that support :ctype:`unsigned long long` (or + :ctype:`unsigned _int64` on Windows). - ``n`` (int) [Py_ssize_t] + ``n`` (:class:`int`) [Py_ssize_t] Convert a C :ctype:`Py_ssize_t` to a Python integer. - ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a byte to a Python byte string of + ``c`` (:class:`bytes` of length 1) [char] + Convert a C :ctype:`int` representing a byte to a Python :class:`bytes` object of length 1. - ``C`` (string of length 1) [int] - Convert a C :ctype:`int` representing a character to Python unicode - string of length 1. + ``C`` (:class:`str` of length 1) [int] + Convert a C :ctype:`int` representing a character to Python :class:`str` + object of length 1. - ``d`` (float) [double] + ``d`` (:class:`float`) [double] Convert a C :ctype:`double` to a Python floating point number. - ``f`` (float) [float] - Same as ``d``. + ``f`` (:class:`float`) [float] + Convert a C :ctype:`float` to a Python floating point number. - ``D`` (complex) [Py_complex \*] + ``D`` (:class:`complex`) [Py_complex \*] Convert a C :ctype:`Py_complex` structure to a Python complex number. ``O`` (object) [PyObject \*] @@ -611,13 +605,13 @@ \*`) as its argument and should return a "new" Python object, or *NULL* if an error occurred. - ``(items)`` (tuple) [*matching-items*] + ``(items)`` (:class:`tuple`) [*matching-items*] Convert a sequence of C values to a Python tuple with the same number of items. - ``[items]`` (list) [*matching-items*] + ``[items]`` (:class:`list`) [*matching-items*] Convert a sequence of C values to a Python list with the same number of items. - ``{items}`` (dictionary) [*matching-items*] + ``{items}`` (:class:`dict`) [*matching-items*] Convert a sequence of C values to a Python dictionary. Each pair of consecutive C values adds one item to the dictionary, serving as key and value, respectively. Modified: python/branches/py3k-jit/Doc/c-api/buffer.rst ============================================================================== --- python/branches/py3k-jit/Doc/c-api/buffer.rst (original) +++ python/branches/py3k-jit/Doc/c-api/buffer.rst Wed Jun 16 18:21:24 2010 @@ -249,10 +249,10 @@ +------------------------------+---------------------------------------------------+ -.. cfunction:: void PyBuffer_Release(PyObject *obj, Py_buffer *view) +.. cfunction:: void PyBuffer_Release(Py_buffer *view) - Release the buffer *view* over *obj*. This should be called when the buffer - is no longer being used as it may free memory from it. + Release the buffer *view*. This should be called when the buffer is no + longer being used as it may free memory from it. .. cfunction:: Py_ssize_t PyBuffer_SizeFromFormat(const char *) Modified: python/branches/py3k-jit/Doc/distutils/builtdist.rst ============================================================================== --- python/branches/py3k-jit/Doc/distutils/builtdist.rst (original) +++ python/branches/py3k-jit/Doc/distutils/builtdist.rst Wed Jun 16 18:21:24 2010 @@ -322,7 +322,7 @@ option. By default the installer will display the cool "Python Powered" logo when it is -run, but you can also supply your own bitmap which must be a Windows +run, but you can also supply your own 152x161 bitmap which must be a Windows :file:`.bmp` file with the :option:`--bitmap` option. The installer will also display a large title on the desktop background window Modified: python/branches/py3k-jit/Doc/extending/newtypes.rst ============================================================================== --- python/branches/py3k-jit/Doc/extending/newtypes.rst (original) +++ python/branches/py3k-jit/Doc/extending/newtypes.rst Wed Jun 16 18:21:24 2010 @@ -430,7 +430,7 @@ Noddy_members, /* tp_members */ Each member definition has a member name, type, offset, access flags and -documentation string. See the "Generic Attribute Management" section below for +documentation string. See the :ref:`Generic-Attribute-Management` section below for details. A disadvantage of this approach is that it doesn't provide a way to restrict the @@ -1078,6 +1078,8 @@ not been updated to use some of the new generic mechanism that is available. +.. _generic-attribute-management: + Generic Attribute Management ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Modified: python/branches/py3k-jit/Doc/library/argparse.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/argparse.rst (original) +++ python/branches/py3k-jit/Doc/library/argparse.rst Wed Jun 16 18:21:24 2010 @@ -452,7 +452,7 @@ By default, :class:`ArgumentParser` objects uses ``sys.argv[0]`` to determine how to display the name of the program in help messages. This default is almost -always desirable because it will make the help messages match how the pgoram was +always desirable because it will make the help messages match how the program was invoked on the command line. For example, consider a file named ``myprogram.py`` with the following code:: Modified: python/branches/py3k-jit/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/datetime.rst (original) +++ python/branches/py3k-jit/Doc/library/datetime.rst Wed Jun 16 18:21:24 2010 @@ -28,11 +28,14 @@ have an optional time zone information member, :attr:`tzinfo`, that can contain an instance of a subclass of the abstract :class:`tzinfo` class. These :class:`tzinfo` objects capture information about the offset from UTC time, the -time zone name, and whether Daylight Saving Time is in effect. Note that no -concrete :class:`tzinfo` classes are supplied by the :mod:`datetime` module. -Supporting timezones at whatever level of detail is required is up to the -application. The rules for time adjustment across the world are more political -than rational, and there is no standard suitable for every application. +time zone name, and whether Daylight Saving Time is in effect. Note that only +one concrete :class:`tzinfo` class, the :class:`timezone` class, is supplied by the +:mod:`datetime` module. The :class:`timezone` class can reprsent simple +timezones with fixed offset from UTC such as UTC itself or North American EST and +EDT timezones. Supporting timezones at whatever level of detail is +required is up to the application. The rules for time adjustment across the +world are more political than rational, change frequently, and there is no +standard suitable for every application aside from UTC. The :mod:`datetime` module exports the following constants: @@ -99,6 +102,14 @@ time adjustment (for example, to account for time zone and/or daylight saving time). +.. class:: timezone + + A class that implements the :class:`tzinfo` abstract base class as a + fixed offset from the UTC. + + .. versionadded:: 3.2 + + Objects of these types are immutable. Objects of the :class:`date` type are always naive. @@ -116,6 +127,7 @@ object timedelta tzinfo + timezone time date datetime @@ -220,12 +232,20 @@ | | In general, *t1* \* i == *t1* \* (i-1) + *t1* | | | is true. (1) | +--------------------------------+-----------------------------------------------+ +| ``t1 = t2 * f or t1 = f * t2`` | Delta multiplied by a float. The result is | +| | rounded to the nearest multiple of | +| | timedelta.resolution using round-half-to-even.| ++--------------------------------+-----------------------------------------------+ | ``f = t2 / t3`` | Division (3) of *t2* by *t3*. Returns a | | | :class:`float` object. | +--------------------------------+-----------------------------------------------+ +| ``t1 = t2 / f or t1 = t2 / i`` | Delta divided by a float or an int. The result| +| | is rounded to the nearest multiple of | +| | timedelta.resolution using round-half-to-even.| ++--------------------------------+-----------------------------------------------+ | ``t1 = t2 // i`` or | The floor is computed and the remainder (if | | ``t1 = t2 // t3`` | any) is thrown away. In the second case, an | -| | integer is returned (3) | +| | integer is returned. (3) | +--------------------------------+-----------------------------------------------+ | ``t1 = t2 % t3`` | The remainder is computed as a | | | :class:`timedelta` object. (3) | @@ -267,7 +287,9 @@ .. versionadded:: 3.2 Floor division and true division of a :class:`timedelta` object by another :class:`timedelta` object are now supported, as are - remainder operations and the :func:`divmod` function. + remainder operations and the :func:`divmod` function. True + division and multiplication of a :class:`timedelta` object by + a :class:`float` object are now supported. Comparisons of :class:`timedelta` objects are supported with the @@ -470,7 +492,9 @@ Return a :class:`time.struct_time` such as returned by :func:`time.localtime`. The hours, minutes and seconds are 0, and the DST flag is -1. ``d.timetuple()`` is equivalent to ``time.struct_time((d.year, d.month, d.day, 0, 0, 0, - d.weekday(), d.toordinal() - date(d.year, 1, 1).toordinal() + 1, -1))`` + d.weekday(), yday, -1))``, where ``yday = d.toordinal() - date(d.year, 1, + 1).toordinal() + 1`` is the day number within the current year starting with + ``1`` for January 1st. .. method:: date.toordinal() @@ -648,8 +672,8 @@ Return the current UTC date and time, with :attr:`tzinfo` ``None``. This is like :meth:`now`, but returns the current UTC date and time, as a naive - :class:`datetime` object. See also :meth:`now`. - + :class:`datetime` object. An aware current UTC datetime can be obtained by + calling ``datetime.now(timezone.utc)``. See also :meth:`now`. .. classmethod:: datetime.fromtimestamp(timestamp, tz=None) @@ -934,12 +958,13 @@ Return a :class:`time.struct_time` such as returned by :func:`time.localtime`. ``d.timetuple()`` is equivalent to ``time.struct_time((d.year, d.month, d.day, - d.hour, d.minute, d.second, d.weekday(), d.toordinal() - date(d.year, 1, - 1).toordinal() + 1, dst))`` The :attr:`tm_isdst` flag of the result is set - according to the :meth:`dst` method: :attr:`tzinfo` is ``None`` or :meth:`dst` - returns ``None``, :attr:`tm_isdst` is set to ``-1``; else if :meth:`dst` - returns a non-zero value, :attr:`tm_isdst` is set to ``1``; else ``tm_isdst`` is - set to ``0``. + d.hour, d.minute, d.second, d.weekday(), yday, dst))``, where ``yday = + d.toordinal() - date(d.year, 1, 1).toordinal() + 1`` is the day number within + the current year starting with ``1`` for January 1st. The :attr:`tm_isdst` flag + of the result is set according to the :meth:`dst` method: :attr:`tzinfo` is + ``None`` or :meth:`dst`` returns ``None``, :attr:`tm_isdst` is set to ``-1``; + else if :meth:`dst` returns a non-zero value, :attr:`tm_isdst` is set to ``1``; + else :attr:`tm_isdst` is set to ``0``. .. method:: datetime.utctimetuple() @@ -1305,8 +1330,10 @@ :class:`tzinfo` is an abstract base class, meaning that this class should not be instantiated directly. You need to derive a concrete subclass, and (at least) supply implementations of the standard :class:`tzinfo` methods needed by the -:class:`datetime` methods you use. The :mod:`datetime` module does not supply -any concrete subclasses of :class:`tzinfo`. +:class:`datetime` methods you use. The :mod:`datetime` module supplies +a simple concrete subclass of :class:`tzinfo` :class:`timezone` which can reprsent +timezones with fixed offset from UTC such as UTC itself or North American EST and +EDT. An instance of (a concrete subclass of) :class:`tzinfo` can be passed to the constructors for :class:`datetime` and :class:`time` objects. The latter objects @@ -1507,9 +1534,65 @@ standard local time. Applications that can't bear such ambiguities should avoid using hybrid -:class:`tzinfo` subclasses; there are no ambiguities when using UTC, or any -other fixed-offset :class:`tzinfo` subclass (such as a class representing only -EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). +:class:`tzinfo` subclasses; there are no ambiguities when using :class:`timezone`, +or any other fixed-offset :class:`tzinfo` subclass (such as a class representing +only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). + + +.. _datetime-timezone: + +:class:`timezone` Objects +-------------------------- + +A :class:`timezone` object represents a timezone that is defined by a +fixed offset from UTC. Note that objects of this class cannot be used +to represent timezone information in the locations where different +offsets are used in different days of the year or where historical +changes have been made to civil time. + + +.. class:: timezone(offset[, name]) + + The ``offset`` argument must be specified as a :class:`timedelta` + object representing the difference between the local time and UTC. It must + be within the range [``-timedelta(hours=23, minutes=59), + ``timedelta(hours=23, minutes=59)``] and represent whole number of minutes, + otherwise :exc:`ValueError` is raised. + + The ``name`` argument is optional. If specified it must be a string that + used as the value returned by the ``tzname(dt)`` method. Otherwise, + ``tzname(dt)`` returns a string 'UTCsHH:MM', where s is the sign of + ``offset``, HH and MM are two digits of ``offset.hours`` and + ``offset.minutes`` respectively. + +.. method:: timezone.utcoffset(self, dt) + + Returns the fixed value specified when the :class:`timezone` instance is + constructed. The ``dt`` argument is ignored. The return value is a + :class:`timedelta` instance equal to the difference between the + local time and UTC. + +.. method:: timezone.tzname(self, dt) + + Returns the fixed value specified when the :class:`timezone` instance is + constructed or a string 'UTCsHH:MM', where s is the sign of + ``offset``, HH and MM are two digits of ``offset.hours`` and + ``offset.minutes`` respectively. The ``dt`` argument is ignored. + +.. method:: timezone.dst(self, dt) + + Always returns ``None``. + +.. method:: timezone.fromutc(self, dt) + + Returns ``dt + offset``. The ``dt`` argument must be aware with ``tzinfo`` + set to ``self``. + +Class attributes: + +.. attribute:: timezone.utc + + The UTC timezone, ``timezone(0, 'UTC')``. .. _strftime-strptime-behavior: Modified: python/branches/py3k-jit/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/decimal.rst (original) +++ python/branches/py3k-jit/Doc/library/decimal.rst Wed Jun 16 18:21:24 2010 @@ -363,23 +363,17 @@ compared, sorted, and coerced to another type (such as :class:`float` or :class:`int`). - Decimal objects cannot generally be combined with floats in - arithmetic operations: an attempt to add a :class:`Decimal` to a - :class:`float`, for example, will raise a :exc:`TypeError`. - There's one exception to this rule: it's possible to use Python's - comparison operators to compare a :class:`float` instance ``x`` - with a :class:`Decimal` instance ``y``. Without this exception, - comparisons between :class:`Decimal` and :class:`float` instances - would follow the general rules for comparing objects of different - types described in the :ref:`expressions` section of the reference - manual, leading to confusing results. + Decimal objects cannot generally be combined with floats or + instances of :class:`fractions.Fraction` in arithmetic operations: + an attempt to add a :class:`Decimal` to a :class:`float`, for + example, will raise a :exc:`TypeError`. However, it is possible to + use Python's comparison operators to compare a :class:`Decimal` + instance ``x`` with another number ``y``. This avoids confusing results + when doing equality comparisons between numbers of different types. .. versionchanged:: 3.2 - A comparison between a :class:`float` instance ``x`` and a - :class:`Decimal` instance ``y`` now returns a result based on - the values of ``x`` and ``y``. In earlier versions ``x < y`` - returned the same (arbitrary) result for any :class:`Decimal` - instance ``x`` and any :class:`float` instance ``y``. + Mixed-type comparisons between :class:`Decimal` instances and + other numeric types are now fully supported. In addition to the standard numeric properties, decimal floating point objects also have a number of specialized methods: @@ -874,7 +868,7 @@ This context is used by the :class:`Context` constructor as a prototype for new contexts. Changing a field (such a precision) has the effect of changing the - default for new contexts creating by the :class:`Context` constructor. + default for new contexts created by the :class:`Context` constructor. This context is most useful in multi-threaded environments. Changing one of the fields before threads are started has the effect of setting system-wide Modified: python/branches/py3k-jit/Doc/library/dis.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/dis.rst (original) +++ python/branches/py3k-jit/Doc/library/dis.rst Wed Jun 16 18:21:24 2010 @@ -383,13 +383,6 @@ the stack so that it is available for further iterations of the loop. -.. opcode:: LOAD_LOCALS () - - Pushes a reference to the locals of the current scope on the stack. This is used - in the code for a class definition: After the class body is evaluated, the - locals are passed to the class definition. - - .. opcode:: RETURN_VALUE () Returns with TOS to the caller of the function. Modified: python/branches/py3k-jit/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/doctest.rst (original) +++ python/branches/py3k-jit/Doc/library/doctest.rst Wed Jun 16 18:21:24 2010 @@ -444,8 +444,9 @@ with an alphanumeric is taken to be the start of the exception detail. Of course this does the right thing for genuine tracebacks. -* When the :const:`IGNORE_EXCEPTION_DETAIL` doctest option is is specified, - everything following the leftmost colon is ignored. +* When the :const:`IGNORE_EXCEPTION_DETAIL` doctest option is specified, + everything following the leftmost colon and any module information in the + exception name is ignored. * The interactive shell omits the traceback header line for some :exc:`SyntaxError`\ s. But doctest uses the traceback header line to @@ -535,20 +536,38 @@ exception raised is ``ValueError: 3*14``, but will fail, e.g., if :exc:`TypeError` is raised. - Note that a similar effect can be obtained using :const:`ELLIPSIS`, and - :const:`IGNORE_EXCEPTION_DETAIL` may go away when Python releases prior to 2.4 - become uninteresting. Until then, :const:`IGNORE_EXCEPTION_DETAIL` is the only - clear way to write a doctest that doesn't care about the exception detail yet - continues to pass under Python releases prior to 2.4 (doctest directives appear - to be comments to them). For example, :: + It will also ignore the module name used in Python 3 doctest reports. Hence + both these variations will work regardless of whether the test is run under + Python 2.7 or Python 3.2 (or later versions): + + >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + CustomError: message + + >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + my_module.CustomError: message + + Note that :const:`ELLIPSIS` can also be used to ignore the + details of the exception message, but such a test may still fail based + on whether or not the module details are printed as part of the + exception name. Using :const:`IGNORE_EXCEPTION_DETAIL` and the details + from Python 2.3 is also the only clear way to write a doctest that doesn't + care about the exception detail yet continues to pass under Python 2.3 or + earlier (those releases do not support doctest directives and ignore them + as irrelevant comments). For example, :: >>> (1, 2)[3] = 'moo' #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): File "", line 1, in ? TypeError: object doesn't support item assignment - passes under Python 2.4 and Python 2.3. The detail changed in 2.4, to say "does - not" instead of "doesn't". + passes under Python 2.3 and later Python versions, even though the detail + changed in Python 2.4 to say "does not" instead of "doesn't". + + .. versionchanged:: 3.2 + :const:`IGNORE_EXCEPTION_DETAIL` now also ignores any information + relating to the module containing the exception under test .. data:: SKIP @@ -663,7 +682,6 @@ functions that run doctests, establishing different defaults. In such cases, disabling an option via ``-`` in a directive can be useful. - There's also a way to register new option flag names, although this isn't useful unless you intend to extend :mod:`doctest` internals via subclassing: Modified: python/branches/py3k-jit/Doc/library/ftplib.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/ftplib.rst (original) +++ python/branches/py3k-jit/Doc/library/ftplib.rst Wed Jun 16 18:21:24 2010 @@ -65,7 +65,7 @@ Support for the :keyword:`with` statement was added. -.. class:: FTP_TLS(host='', user='', passwd='', acct='', [keyfile[, certfile[, timeout]]]) +.. class:: FTP_TLS(host='', user='', passwd='', acct='', [keyfile[, certfile[, context[, timeout]]]]) A :class:`FTP` subclass which adds TLS support to FTP as described in :rfc:`4217`. @@ -74,6 +74,9 @@ explicitly ask for it by calling the :meth:`prot_p` method. *keyfile* and *certfile* are optional -- they can contain a PEM formatted private key and certificate chain file name for the SSL connection. + *context* parameter is a :class:`ssl.SSLContext` object which allows + bundling SSL configuration options, certificates and private keys into a + single (potentially long-lived) structure. .. versionadded:: 3.2 Modified: python/branches/py3k-jit/Doc/library/functions.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/functions.rst (original) +++ python/branches/py3k-jit/Doc/library/functions.rst Wed Jun 16 18:21:24 2010 @@ -1227,7 +1227,7 @@ True -.. function:: __import__(name, globals={}, locals={}, fromlist=[], level=-1) +.. function:: __import__(name, globals={}, locals={}, fromlist=[], level=0) .. index:: statement: import Modified: python/branches/py3k-jit/Doc/library/io.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/io.rst (original) +++ python/branches/py3k-jit/Doc/library/io.rst Wed Jun 16 18:21:24 2010 @@ -314,10 +314,12 @@ .. method:: truncate(size=None) - Truncate the file to at most *size* bytes. *size* defaults to the current - file position, as returned by :meth:`tell`. Note that the current file - position isn't changed; if you want to change it to the new end of - file, you have to :meth:`seek()` explicitly. + Resize the stream to the given *size* in bytes (or the current position + if *size* is not specified). The current stream position isn't changed. + This resizing can extend or reduce the current file size. In case of + extension, the contents of the new file area depend on the platform + (on most systems, additional bytes are zero-filled, on Windows they're + undetermined). The new file size is returned. .. method:: writable() Modified: python/branches/py3k-jit/Doc/library/os.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/os.rst (original) +++ python/branches/py3k-jit/Doc/library/os.rst Wed Jun 16 18:21:24 2010 @@ -159,10 +159,10 @@ .. function:: fsencode(value) Encode *value* to bytes for use in the file system, environment variables or - the command line. Uses :func:`sys.getfilesystemencoding` and - ``'surrogateescape'`` error handler for strings and returns bytes unchanged. - - Availability: Unix. + the command line. Use :func:`sys.getfilesystemencoding` and + ``'surrogateescape'`` error handler for strings and return bytes unchanged. + On Windows, use ``'strict'`` error handler for strings if the file system + encoding is ``'mbcs'`` (which is the default encoding). .. versionadded:: 3.2 Modified: python/branches/py3k-jit/Doc/library/socket.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/socket.rst (original) +++ python/branches/py3k-jit/Doc/library/socket.rst Wed Jun 16 18:21:24 2010 @@ -211,27 +211,44 @@ *source_address* was added. -.. function:: getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]]) +.. function:: getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0) - Resolves the *host*/*port* argument, into a sequence of 5-tuples that contain - all the necessary arguments for creating the corresponding socket. *host* is a domain - name, a string representation of an IPv4/v6 address or ``None``. *port* is a string - service name such as ``'http'``, a numeric port number or ``None``. - The rest of the arguments are optional and must be numeric if specified. - By passing ``None`` as the value of *host* and *port*, , you can pass ``NULL`` to the C API. + Translate the *host*/*port* argument into a sequence of 5-tuples that contain + all the necessary arguments for creating a socket connected to that service. + *host* is a domain name, a string representation of an IPv4/v6 address + or ``None``. *port* is a string service name such as ``'http'``, a numeric + port number or ``None``. By passing ``None`` as the value of *host* + and *port*, you can pass ``NULL`` to the underlying C API. + + The *family*, *socktype* and *proto* arguments can be optionally specified + in order to narrow the list of addresses returned. Passing zero as a + value for each of these arguments selects the full range of results. + The *flags* argument can be one or several of the ``AI_*`` constants, + and will influence how results are computed and returned. + For example, :const:`AI_NUMERICHOST` will disable domain name resolution + and will raise an error if *host* is a domain name. - The :func:`getaddrinfo` function returns a list of 5-tuples with the following - structure: + The function returns a list of 5-tuples with the following structure: ``(family, socktype, proto, canonname, sockaddr)`` - *family*, *socktype*, *proto* are all integers and are meant to be passed to the - :func:`socket` function. *canonname* is a string representing the canonical name - of the *host*. It can be a numeric IPv4/v6 address when :const:`AI_CANONNAME` is - specified for a numeric *host*. *sockaddr* is a tuple describing a socket - address, as described above. See the source for :mod:`socket` and other - library modules for a typical usage of the function. - + In these tuples, *family*, *socktype*, *proto* are all integers and are + meant to be passed to the :func:`socket` function. *canonname* will be + a string representing the canonical name of the *host* if + :const:`AI_CANONNAME` is part of the *flags* argument; else *canonname* + will be empty. *sockaddr* is a tuple describing a socket address, whose + format depends on the returned *family* (a ``(address, port)`` 2-tuple for + :const:`AF_INET`, a ``(address, port, flow info, scope id)`` 4-tuple for + :const:`AF_INET6`), and is meant to be passed to the :meth:`socket.connect` + method. + + The following example fetches address information for a hypothetical TCP + connection to ``www.python.org`` on port 80 (results may differ on your + system if IPv6 isn't enabled):: + + >>> socket.getaddrinfo("www.python.org", 80, 0, 0, socket.SOL_TCP) + [(2, 1, 6, '', ('82.94.164.162', 80)), + (10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0))] .. function:: getfqdn([name]) Modified: python/branches/py3k-jit/Doc/library/sqlite3.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/sqlite3.rst (original) +++ python/branches/py3k-jit/Doc/library/sqlite3.rst Wed Jun 16 18:21:24 2010 @@ -227,6 +227,13 @@ one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". See section :ref:`sqlite3-controlling-transactions` for a more detailed explanation. +.. attribute:: Connection.in_transaction + + .. versionadded:: 3.2 + + :const:`True` if a transaction is active (there are uncommitted changes), + :const:`False` otherwise. Read-only attribute. + .. method:: Connection.cursor([cursorClass]) @@ -806,7 +813,8 @@ before executing that command. There are two reasons for doing that. The first is that some of these commands don't work within transactions. The other reason is that sqlite3 needs to keep track of the transaction state (if a transaction -is active or not). +is active or not). The current transaction state is exposed through the +:attr:`Connection.in_transaction` attribute of the connection object. You can control which kind of ``BEGIN`` statements sqlite3 implicitly executes (or none at all) via the *isolation_level* parameter to the :func:`connect` Modified: python/branches/py3k-jit/Doc/library/ssl.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/ssl.rst (original) +++ python/branches/py3k-jit/Doc/library/ssl.rst Wed Jun 16 18:21:24 2010 @@ -407,6 +407,16 @@ other side of the connection, rather than the original socket. +.. attribute:: SSLSocket.context + + The :class:`SSLContext` object this SSL socket is tied to. If the SSL + socket was created using the top-level :func:`wrap_socket` function + (rather than :meth:`SSLContext.wrap_socket`), this is a custom context + object created for this SSL socket. + + .. versionadded:: 3.2 + + SSL Contexts ------------ Modified: python/branches/py3k-jit/Doc/library/struct.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/struct.rst (original) +++ python/branches/py3k-jit/Doc/library/struct.rst Wed Jun 16 18:21:24 2010 @@ -38,38 +38,38 @@ .. function:: pack(fmt, v1, v2, ...) - Return a bytes containing the values ``v1, v2, ...`` packed according to the - given format. The arguments must match the values required by the format - exactly. + Return a bytes object containing the values *v1*, *v2*, ... packed according + to the format string *fmt*. The arguments must match the values required by + the format exactly. .. function:: pack_into(fmt, buffer, offset, v1, v2, ...) - Pack the values ``v1, v2, ...`` according to the given format, write the - packed bytes into the writable *buffer* starting at *offset*. Note that the - offset is a required argument. + Pack the values *v1*, *v2*, ... according to the format string *fmt* and + write the packed bytes into the writable buffer *buffer* starting at + position *offset*. Note that *offset* is a required argument. -.. function:: unpack(fmt, bytes) +.. function:: unpack(fmt, buffer) - Unpack the bytes (presumably packed by ``pack(fmt, ...)``) according to the - given format. The result is a tuple even if it contains exactly one item. - The bytes must contain exactly the amount of data required by the format - (``len(bytes)`` must equal ``calcsize(fmt)``). + Unpack from the buffer *buffer* (presumably packed by ``pack(fmt, ...)``) + according to the format string *fmt*. The result is a tuple even if it + contains exactly one item. The buffer must contain exactly the amount of + data required by the format (``len(bytes)`` must equal ``calcsize(fmt)``). .. function:: unpack_from(fmt, buffer, offset=0) - Unpack the *buffer* according to the given format. The result is a tuple even - if it contains exactly one item. The *buffer* must contain at least the - amount of data required by the format (``len(buffer[offset:])`` must be at - least ``calcsize(fmt)``). + Unpack from *buffer* starting at position *offset*, according to the format + string *fmt*. The result is a tuple even if it contains exactly one + item. *buffer* must contain at least the amount of data required by the + format (``len(buffer[offset:])`` must be at least ``calcsize(fmt)``). .. function:: calcsize(fmt) - Return the size of the struct (and hence of the bytes) corresponding to the - given format. + Return the size of the struct (and hence of the bytes object produced by + ``pack(fmt, ...)``) corresponding to the format string *fmt*. .. _struct-format-strings: @@ -77,9 +77,84 @@ -------------- Format strings are the mechanism used to specify the expected layout when -packing and unpacking data. They are built up from format characters, which -specify the type of data being packed/unpacked. In addition, there are -special characters for controlling the byte order, size, and alignment. +packing and unpacking data. They are built up from :ref:`format-characters`, +which specify the type of data being packed/unpacked. In addition, there are +special characters for controlling the :ref:`struct-alignment`. + + +.. _struct-alignment: + +Byte Order, Size, and Alignment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, C types are represented in the machine's native format and byte +order, and properly aligned by skipping pad bytes if necessary (according to the +rules used by the C compiler). + +Alternatively, the first character of the format string can be used to indicate +the byte order, size and alignment of the packed data, according to the +following table: + ++-----------+------------------------+--------------------+ +| Character | Byte order | Size and alignment | ++===========+========================+====================+ +| ``@`` | native | native | ++-----------+------------------------+--------------------+ +| ``=`` | native | standard | ++-----------+------------------------+--------------------+ +| ``<`` | little-endian | standard | ++-----------+------------------------+--------------------+ +| ``>`` | big-endian | standard | ++-----------+------------------------+--------------------+ +| ``!`` | network (= big-endian) | standard | ++-----------+------------------------+--------------------+ + +If the first character is not one of these, ``'@'`` is assumed. + +Native byte order is big-endian or little-endian, depending on the host +system. For example, Intel x86 and AMD64 (x86-64) are little-endian; +Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature +switchable endianness (bi-endian). Use ``sys.byteorder`` to check the +endianness of your system. + +Native size and alignment are determined using the C compiler's +``sizeof`` expression. This is always combined with native byte order. + +Standard size and alignment are as follows: no alignment is required for any +type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and +:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 +bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating +point numbers, respectively. :ctype:`_Bool` is 1 byte. + +Note the difference between ``'@'`` and ``'='``: both use native byte order, but +the size and alignment of the latter is standardized. + +The form ``'!'`` is available for those poor souls who claim they can't remember +whether network byte order is big-endian or little-endian. + +There is no way to indicate non-native byte order (force byte-swapping); use the +appropriate choice of ``'<'`` or ``'>'``. + +The ``'P'`` format character is only available for the native byte ordering +(selected as the default or with the ``'@'`` byte order character). The byte +order character ``'='`` chooses to use little- or big-endian ordering based on +the host system. The struct module does not interpret this as native ordering, +so the ``'P'`` format is not available. + +Notes: + +(1) Padding is only automatically added between successive structure members. + No padding is added at the beginning or the end of the encoded struct. + +(2) No padding is added when using non-native size and alignment, e.g. + with '<', '>', '=', and '!'. + +(3) To align the end of a structure to the alignment requirement of a + particular type, end the format with the code for that type with a repeat + count of zero. See :ref:`struct-examples`. + + +.. _format-characters: Format Characters ^^^^^^^^^^^^^^^^^ @@ -87,46 +162,46 @@ Format characters have the following meaning; the conversion between C and Python values should be obvious given their types: -+--------+-------------------------+--------------------+------------+ -| Format | C Type | Python | Notes | -+========+=========================+====================+============+ -| ``x`` | pad byte | no value | | -+--------+-------------------------+--------------------+------------+ -| ``c`` | :ctype:`char` | bytes of length 1 | | -+--------+-------------------------+--------------------+------------+ -| ``b`` | :ctype:`signed char` | integer | \(1),\(4) | -+--------+-------------------------+--------------------+------------+ -| ``B`` | :ctype:`unsigned char` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``?`` | :ctype:`_Bool` | bool | \(2) | -+--------+-------------------------+--------------------+------------+ -| ``h`` | :ctype:`short` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``H`` | :ctype:`unsigned short` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``i`` | :ctype:`int` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``I`` | :ctype:`unsigned int` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``l`` | :ctype:`long` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``L`` | :ctype:`unsigned long` | integer | \(4) | -+--------+-------------------------+--------------------+------------+ -| ``q`` | :ctype:`long long` | integer | \(3), \(4) | -+--------+-------------------------+--------------------+------------+ -| ``Q`` | :ctype:`unsigned long | integer | \(3), \(4) | -| | long` | | | -+--------+-------------------------+--------------------+------------+ -| ``f`` | :ctype:`float` | float | | -+--------+-------------------------+--------------------+------------+ -| ``d`` | :ctype:`double` | float | | -+--------+-------------------------+--------------------+------------+ -| ``s`` | :ctype:`char[]` | bytes | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``p`` | :ctype:`char[]` | bytes | \(1) | -+--------+-------------------------+--------------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | -+--------+-------------------------+--------------------+------------+ ++--------+-------------------------+--------------------+----------------+------------+ +| Format | C Type | Python type | Standard size | Notes | ++========+=========================+====================+================+============+ +| ``x`` | pad byte | no value | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``c`` | :ctype:`char` | bytes of length 1 | 1 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``b`` | :ctype:`signed char` | integer | 1 | \(1),\(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``B`` | :ctype:`unsigned char` | integer | 1 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``?`` | :ctype:`_Bool` | bool | 1 | \(2) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``h`` | :ctype:`short` | integer | 2 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``H`` | :ctype:`unsigned short` | integer | 2 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``i`` | :ctype:`int` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``I`` | :ctype:`unsigned int` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``l`` | :ctype:`long` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``L`` | :ctype:`unsigned long` | integer | 4 | \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``q`` | :ctype:`long long` | integer | 8 | \(3), \(4) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``Q`` | :ctype:`unsigned long | integer | 8 | \(3), \(4) | +| | long` | | | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``f`` | :ctype:`float` | float | 4 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``d`` | :ctype:`double` | float | 8 | | ++--------+-------------------------+--------------------+----------------+------------+ +| ``s`` | :ctype:`char[]` | bytes | | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``p`` | :ctype:`char[]` | bytes | | \(1) | ++--------+-------------------------+--------------------+----------------+------------+ +| ``P`` | :ctype:`void \*` | integer | | | ++--------+-------------------------+--------------------+----------------+------------+ Notes: @@ -196,77 +271,6 @@ any non-zero value will be True when unpacking. -.. _struct-alignment: - -Byte Order, Size, and Alignment -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -By default, C types are represented in the machine's native format and byte -order, and properly aligned by skipping pad bytes if necessary (according to the -rules used by the C compiler). - -Alternatively, the first character of the format string can be used to indicate -the byte order, size and alignment of the packed data, according to the -following table: - -+-----------+------------------------+--------------------+ -| Character | Byte order | Size and alignment | -+===========+========================+====================+ -| ``@`` | native | native | -+-----------+------------------------+--------------------+ -| ``=`` | native | standard | -+-----------+------------------------+--------------------+ -| ``<`` | little-endian | standard | -+-----------+------------------------+--------------------+ -| ``>`` | big-endian | standard | -+-----------+------------------------+--------------------+ -| ``!`` | network (= big-endian) | standard | -+-----------+------------------------+--------------------+ - -If the first character is not one of these, ``'@'`` is assumed. - -Native byte order is big-endian or little-endian, depending on the host -system. For example, Intel x86 and AMD64 (x86-64) are little-endian; -Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature -switchable endianness (bi-endian). Use ``sys.byteorder`` to check the -endianness of your system. - -Native size and alignment are determined using the C compiler's -``sizeof`` expression. This is always combined with native byte order. - -Standard size and alignment are as follows: no alignment is required for any -type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and -:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 -bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating -point numbers, respectively. :ctype:`_Bool` is 1 byte. - -Note the difference between ``'@'`` and ``'='``: both use native byte order, but -the size and alignment of the latter is standardized. - -The form ``'!'`` is available for those poor souls who claim they can't remember -whether network byte order is big-endian or little-endian. - -There is no way to indicate non-native byte order (force byte-swapping); use the -appropriate choice of ``'<'`` or ``'>'``. - -The ``'P'`` format character is only available for the native byte ordering -(selected as the default or with the ``'@'`` byte order character). The byte -order character ``'='`` chooses to use little- or big-endian ordering based on -the host system. The struct module does not interpret this as native ordering, -so the ``'P'`` format is not available. - -Notes: - -(1) Padding is only automatically added between successive structure members. - No padding is added at the beginning or the end of the encoded struct. - -(2) No padding is added when using non-native size and alignment, e.g. - with '<', '>', '=', and '!'. - -(3) To align the end of a structure to the alignment requirement of a - particular type, end the format with the code for that type with a repeat - count of zero. See :ref:`struct-examples`. - .. _struct-examples: @@ -331,7 +335,7 @@ .. _struct-objects: -Objects +Classes ------- The :mod:`struct` module also defines the following type: @@ -358,10 +362,10 @@ Identical to the :func:`pack_into` function, using the compiled format. - .. method:: unpack(bytes) + .. method:: unpack(buffer) Identical to the :func:`unpack` function, using the compiled format. - (``len(bytes)`` must equal :attr:`self.size`). + (``len(buffer)`` must equal :attr:`self.size`). .. method:: unpack_from(buffer, offset=0) @@ -376,6 +380,6 @@ .. attribute:: size - The calculated size of the struct (and hence of the bytes) corresponding - to :attr:`format`. + The calculated size of the struct (and hence of the bytes object produced + by the :meth:`pack` method) corresponding to :attr:`format`. Modified: python/branches/py3k-jit/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/subprocess.rst (original) +++ python/branches/py3k-jit/Doc/library/subprocess.rst Wed Jun 16 18:21:24 2010 @@ -89,6 +89,12 @@ size. A negative *bufsize* means to use the system default, which usually means fully buffered. The default value for *bufsize* is :const:`0` (unbuffered). + .. note:: + + If you experience performance issues, it is recommended that you try to + enable buffering by setting *bufsize* to either -1 or a large enough + positive value (such as 4096). + The *executable* argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the *args* argument. If ``shell=True``, the *executable* argument specifies which shell to use. On Unix, Modified: python/branches/py3k-jit/Doc/library/sysconfig.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/sysconfig.rst (original) +++ python/branches/py3k-jit/Doc/library/sysconfig.rst Wed Jun 16 18:21:24 2010 @@ -216,3 +216,35 @@ .. function:: get_config_h_filename() Return the path of :file:`pyconfig.h`. + +Using :mod:`sysconfig` as a script +---------------------------------- + +You can use :mod:`sysconfig` as a script with Python's *-m* option:: + + $ python -m sysconfig + Platform: "macosx-10.4-i386" + Python version: "3.2" + Current installation scheme: "posix_prefix" + + Paths: + data = "/usr/local" + include = "/Users/tarek/Dev/svn.python.org/py3k/Include" + platinclude = "." + platlib = "/usr/local/lib/python3.2/site-packages" + platstdlib = "/usr/local/lib/python3.2" + purelib = "/usr/local/lib/python3.2/site-packages" + scripts = "/usr/local/bin" + stdlib = "/usr/local/lib/python3.2" + + Variables: + AC_APPLE_UNIVERSAL_BUILD = "0" + AIX_GENUINE_CPLUSPLUS = "0" + AR = "ar" + ARFLAGS = "rc" + ASDLGEN = "./Parser/asdl_c.py" + ... + +This call will print in the standard output the information returned by +:func:`get_platform`, :func:`get_python_version`, :func:`get_path` and +:func:`get_config_vars`. Modified: python/branches/py3k-jit/Doc/library/tarfile.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/tarfile.rst (original) +++ python/branches/py3k-jit/Doc/library/tarfile.rst Wed Jun 16 18:21:24 2010 @@ -185,8 +185,8 @@ .. data:: ENCODING - The default character encoding i.e. the value from either - :func:`sys.getfilesystemencoding` or :func:`sys.getdefaultencoding`. + The default character encoding: ``'utf-8'`` on Windows, + :func:`sys.getfilesystemencoding` otherwise. .. seealso:: Modified: python/branches/py3k-jit/Doc/library/time.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/time.rst (original) +++ python/branches/py3k-jit/Doc/library/time.rst Wed Jun 16 18:21:24 2010 @@ -81,30 +81,31 @@ :func:`gmtime`, :func:`localtime`, and :func:`strptime` also offer attribute names for individual fields. - +-------+------------------+------------------------------+ - | Index | Attribute | Values | - +=======+==================+==============================+ - | 0 | :attr:`tm_year` | (for example, 1993) | - +-------+------------------+------------------------------+ - | 1 | :attr:`tm_mon` | range [1,12] | - +-------+------------------+------------------------------+ - | 2 | :attr:`tm_mday` | range [1,31] | - +-------+------------------+------------------------------+ - | 3 | :attr:`tm_hour` | range [0,23] | - +-------+------------------+------------------------------+ - | 4 | :attr:`tm_min` | range [0,59] | - +-------+------------------+------------------------------+ - | 5 | :attr:`tm_sec` | range [0,61]; see **(1)** in | - | | | :func:`strftime` description | - +-------+------------------+------------------------------+ - | 6 | :attr:`tm_wday` | range [0,6], Monday is 0 | - +-------+------------------+------------------------------+ - | 7 | :attr:`tm_yday` | range [1,366] | - +-------+------------------+------------------------------+ - | 8 | :attr:`tm_isdst` | 0, 1 or -1; see below | - +-------+------------------+------------------------------+ + +-------+-------------------+---------------------------------+ + | Index | Attribute | Values | + +=======+===================+=================================+ + | 0 | :attr:`tm_year` | (for example, 1993) | + +-------+-------------------+---------------------------------+ + | 1 | :attr:`tm_mon` | range [1, 12] | + +-------+-------------------+---------------------------------+ + | 2 | :attr:`tm_mday` | range [1, 31] | + +-------+-------------------+---------------------------------+ + | 3 | :attr:`tm_hour` | range [0, 23] | + +-------+-------------------+---------------------------------+ + | 4 | :attr:`tm_min` | range [0, 59] | + +-------+-------------------+---------------------------------+ + | 5 | :attr:`tm_sec` | range [0, 61]; see **(1)** in | + | | | :func:`strftime` description | + +-------+-------------------+---------------------------------+ + | 6 | :attr:`tm_wday` | range [0, 6], Monday is 0 | + +-------+-------------------+---------------------------------+ + | 7 | :attr:`tm_yday` | range [1, 366] | + +-------+-------------------+---------------------------------+ + | 8 | :attr:`tm_isdst` | 0, 1 or -1; see below | + +-------+-------------------+---------------------------------+ - Note that unlike the C structure, the month value is a range of 1-12, not 0-11. + Note that unlike the C structure, the month value is a range of [1, 12], + not [0, 11]. A year value will be handled as described under "Year 2000 (Y2K) issues" above. A ``-1`` argument as the daylight savings flag, passed to :func:`mktime` will usually result in the correct daylight savings state to be filled in. Modified: python/branches/py3k-jit/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/unittest.rst (original) +++ python/branches/py3k-jit/Doc/library/unittest.rst Wed Jun 16 18:21:24 2010 @@ -1168,6 +1168,21 @@ .. versionadded:: 3.1 + .. attribute:: maxDiff + + This attribute controls the maximum length of diffs output by assert + methods that report diffs on failure. It defaults to 80*8 characters. + Assert methods affected by this attribute are + :meth:`assertSequenceEqual` (including all the sequence comparison + methods that delegate to it), :meth:`assertDictEqual` and + :meth:`assertMultiLineEqual`. + + Setting ``maxDiff`` to None means that there is no maximum length of + diffs. + + .. versionadded:: 3.2 + + Testing frameworks can use the following methods to collect information on the test: @@ -1862,7 +1877,9 @@ If an exception is raised during a ``setUpClass`` then the tests in the class are not run and the ``tearDownClass`` is not run. Skipped classes will not -have ``setUpClass`` or ``tearDownClass`` run. +have ``setUpClass`` or ``tearDownClass`` run. If the exception is a +``SkipTest`` exception then the class will be reported as having been skipped +instead of as an error. setUpModule and tearDownModule @@ -1877,7 +1894,9 @@ closeConnection() If an exception is raised in a ``setUpModule`` then none of the tests in the -module will be run and the ``tearDownModule`` will not be run. +module will be run and the ``tearDownModule`` will not be run. If the exception is a +``SkipTest`` exception then the module will be reported as having been skipped +instead of as an error. Signal Handling Modified: python/branches/py3k-jit/Doc/library/urllib.parse.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/urllib.parse.rst (original) +++ python/branches/py3k-jit/Doc/library/urllib.parse.rst Wed Jun 16 18:21:24 2010 @@ -26,7 +26,7 @@ The :mod:`urllib.parse` module defines the following functions: -.. function:: urlparse(urlstring, default_scheme='', allow_fragments=True) +.. function:: urlparse(urlstring, scheme='', allow_fragments=True) Parse a URL into six components, returning a 6-tuple. This corresponds to the general structure of a URL: ``scheme://netloc/path;parameters?query#fragment``. @@ -48,7 +48,7 @@ >>> o.geturl() 'http://www.cwi.nl:80/%7Eguido/Python.html' - If the *default_scheme* argument is specified, it gives the default addressing + If the *scheme* argument is specified, it gives the default addressing scheme, to be used only if the URL does not specify one. The default value for this argument is the empty string. @@ -142,7 +142,7 @@ states that these are equivalent). -.. function:: urlsplit(urlstring, default_scheme='', allow_fragments=True) +.. function:: urlsplit(urlstring, scheme='', allow_fragments=True) This is similar to :func:`urlparse`, but does not split the params from the URL. This should generally be used instead of :func:`urlparse` if the more recent URL @@ -312,19 +312,21 @@ .. function:: urlencode(query, doseq=False) - Convert a mapping object or a sequence of two-element tuples to a "url-encoded" - string, suitable to pass to :func:`urlopen` above as the optional *data* - argument. This is useful to pass a dictionary of form fields to a ``POST`` - request. The resulting string is a series of ``key=value`` pairs separated by - ``'&'`` characters, where both *key* and *value* are quoted using - :func:`quote_plus` above. If the optional parameter *doseq* is present and - evaluates to true, individual ``key=value`` pairs are generated for each element - of the sequence. When a sequence of two-element tuples is used as the *query* - argument, the first element of each tuple is a key and the second is a value. - The order of parameters in the encoded string will match the order of parameter - tuples in the sequence. This module provides the functions - :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings - into Python data structures. + Convert a mapping object or a sequence of two-element tuples to a + "url-encoded" string, suitable to pass to :func:`urlopen` above as the + optional *data* argument. This is useful to pass a dictionary of form + fields to a ``POST`` request. The resulting string is a series of + ``key=value`` pairs separated by ``'&'`` characters, where both *key* and + *value* are quoted using :func:`quote_plus` above. When a sequence of + two-element tuples is used as the *query* argument, the first element of + each tuple is a key and the second is a value. The value element in itself + can be a sequence and in that case, if the optional parameter *doseq* is + evaluates to *True*, individual ``key=value`` pairs separated by ``'&'`` are + generated for each element of the value sequence for the key. The order of + parameters in the encoded string will match the order of parameter tuples in + the sequence. This module provides the functions :func:`parse_qs` and + :func:`parse_qsl` which are used to parse query strings into Python data + structures. .. seealso:: Modified: python/branches/py3k-jit/Doc/library/winreg.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/winreg.rst (original) +++ python/branches/py3k-jit/Doc/library/winreg.rst Wed Jun 16 18:21:24 2010 @@ -111,7 +111,7 @@ The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx Windows API function, which is specific to 64-bit versions of Windows. See the `RegDeleteKeyEx documentation - `__. + `__. *key* is an already open key, or one of the predefined :ref:`HKEY_* constants `. Modified: python/branches/py3k-jit/Doc/library/xml.dom.minidom.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/xml.dom.minidom.rst (original) +++ python/branches/py3k-jit/Doc/library/xml.dom.minidom.rst Wed Jun 16 18:21:24 2010 @@ -114,6 +114,13 @@ to be called on the :class:`Document` object, but may be called on child nodes to discard children of that node. + You can avoid calling this method explicitly by using the :keyword:`with` + statement. The following code will automatically unlink *dom* when the + :keyword:`with` block is exited:: + + with xml.dom.minidom.parse(datasource) as dom: + ... # Work with dom. + .. method:: Node.writexml(writer, indent="", addindent="", newl="", encoding="") Modified: python/branches/py3k-jit/Doc/tools/sphinxext/pyspecific.py ============================================================================== --- python/branches/py3k-jit/Doc/tools/sphinxext/pyspecific.py (original) +++ python/branches/py3k-jit/Doc/tools/sphinxext/pyspecific.py Wed Jun 16 18:21:24 2010 @@ -78,7 +78,7 @@ 'assert', 'assignment', 'atom-identifiers', 'atom-literals', 'attribute-access', 'attribute-references', 'augassign', 'binary', 'bitwise', 'bltin-code-objects', 'bltin-ellipsis-object', - 'bltin-file-objects', 'bltin-null-object', 'bltin-type-objects', 'booleans', + 'bltin-null-object', 'bltin-type-objects', 'booleans', 'break', 'callable-types', 'calls', 'class', 'comparisons', 'compound', 'context-managers', 'continue', 'conversions', 'customization', 'debugger', 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'execmodel', Modified: python/branches/py3k-jit/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k-jit/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k-jit/Doc/whatsnew/3.2.rst Wed Jun 16 18:21:24 2010 @@ -100,6 +100,18 @@ (Contributed by Tarek Ziade.) +* The *sqlite3* module has some new features: + + * XXX *enable_load_extension* + + * XXX *load_extension* + + * New :class:`~sqlite3.Connection` attribute + :attr:`~sqlite3.Connection.in_transaction` is :const:`True` when there + are uncommitted changes, and :const:`False` otherwise. (Contributed + by R. David Murray and Shashwat Anand, :issue:`8845`.) + + Multi-threading =============== @@ -161,4 +173,7 @@ * bytearray objects cannot be used anymore as filenames: convert them to bytes +* "t#" format of PyArg_Parse*() functions has been removed: use "s#" or "s*" + instead + * Stub Modified: python/branches/py3k-jit/Include/longobject.h ============================================================================== --- python/branches/py3k-jit/Include/longobject.h (original) +++ python/branches/py3k-jit/Include/longobject.h Wed Jun 16 18:21:24 2010 @@ -101,6 +101,14 @@ */ PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); +/* _PyLong_DivmodNear. Given integers a and b, compute the nearest + integer q to the exact quotient a / b, rounding to the nearest even integer + in the case of a tie. Return (q, r), where r = a - q*b. The remainder r + will satisfy abs(r) <= abs(b)/2, with equality possible only if q is + even. +*/ +PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *); + /* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in base 256, and return a Python long with the same numeric value. If n is 0, the integer is 0. Else: Modified: python/branches/py3k-jit/Lib/base64.py ============================================================================== --- python/branches/py3k-jit/Lib/base64.py (original) +++ python/branches/py3k-jit/Lib/base64.py Wed Jun 16 18:21:24 2010 @@ -383,9 +383,9 @@ if o == '-u': func = decode if o == '-t': test(); return if args and args[0] != '-': - func(open(args[0], 'rb'), sys.stdout) + func(open(args[0], 'rb'), sys.stdout.buffer) else: - func(sys.stdin, sys.stdout) + func(sys.stdin.buffer, sys.stdout.buffer) def test(): Modified: python/branches/py3k-jit/Lib/ctypes/test/test_bytes.py ============================================================================== --- python/branches/py3k-jit/Lib/ctypes/test/test_bytes.py (original) +++ python/branches/py3k-jit/Lib/ctypes/test/test_bytes.py Wed Jun 16 18:21:24 2010 @@ -30,8 +30,8 @@ X("abc") x = X(b"abc") - self.assertEqual(x.a, "abc") - self.assertEqual(type(x.a), str) + self.assertEqual(x.a, b"abc") + self.assertEqual(type(x.a), bytes) def test_struct_W(self): class X(Structure): Modified: python/branches/py3k-jit/Lib/ctypes/test/test_structures.py ============================================================================== --- python/branches/py3k-jit/Lib/ctypes/test/test_structures.py (original) +++ python/branches/py3k-jit/Lib/ctypes/test/test_structures.py Wed Jun 16 18:21:24 2010 @@ -209,9 +209,9 @@ self.assertRaises(TypeError, Person, "Name", "HI") # short enough - self.assertEqual(Person("12345", 5).name, "12345") + self.assertEqual(Person("12345", 5).name, b"12345") # exact fit - self.assertEqual(Person("123456", 5).name, "123456") + self.assertEqual(Person("123456", 5).name, b"123456") # too long self.assertRaises(ValueError, Person, "1234567", 5) @@ -269,9 +269,9 @@ p = Person("Someone", ("1234", "5678"), 5) - self.assertEqual(p.name, "Someone") - self.assertEqual(p.phone.areacode, "1234") - self.assertEqual(p.phone.number, "5678") + self.assertEqual(p.name, b"Someone") + self.assertEqual(p.phone.areacode, b"1234") + self.assertEqual(p.phone.number, b"5678") self.assertEqual(p.age, 5) def test_structures_with_wchar(self): Modified: python/branches/py3k-jit/Lib/decimal.py ============================================================================== --- python/branches/py3k-jit/Lib/decimal.py (original) +++ python/branches/py3k-jit/Lib/decimal.py Wed Jun 16 18:21:24 2010 @@ -31,7 +31,8 @@ useful for financial applications or for contexts where users have expectations that are at odds with binary floating point (for instance, in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead -of the expected Decimal('0.00') returned by decimal floating point). +of 0.0; Decimal('1.00') % Decimal('0.1') returns the expected +Decimal('0.00')). Here are some examples of using the decimal module: @@ -862,7 +863,7 @@ # that specified by IEEE 754. def __eq__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other, equality_op=True) if other is NotImplemented: return other if self._check_nans(other, context): @@ -870,7 +871,7 @@ return self._cmp(other) == 0 def __ne__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other, equality_op=True) if other is NotImplemented: return other if self._check_nans(other, context): @@ -879,7 +880,7 @@ def __lt__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -888,7 +889,7 @@ return self._cmp(other) < 0 def __le__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -897,7 +898,7 @@ return self._cmp(other) <= 0 def __gt__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -906,7 +907,7 @@ return self._cmp(other) > 0 def __ge__(self, other, context=None): - other = _convert_other(other, allow_float = True) + self, other = _convert_for_comparison(self, other) if other is NotImplemented: return other ans = self._compare_check_nans(other, context) @@ -5860,6 +5861,37 @@ raise TypeError("Unable to convert %s to Decimal" % other) return NotImplemented +def _convert_for_comparison(self, other, equality_op=False): + """Given a Decimal instance self and a Python object other, return + a pair (s, o) of Decimal instances such that "s op o" is + equivalent to "self op other" for any of the 6 comparison + operators "op". + + """ + if isinstance(other, Decimal): + return self, other + + # Comparison with a Rational instance (also includes integers): + # self op n/d <=> self*d op n (for n and d integers, d positive). + # A NaN or infinity can be left unchanged without affecting the + # comparison result. + if isinstance(other, _numbers.Rational): + if not self._is_special: + self = _dec_from_triple(self._sign, + str(int(self._int) * other.denominator), + self._exp) + return self, Decimal(other.numerator) + + # Comparisons with float and complex types. == and != comparisons + # with complex numbers should succeed, returning either True or False + # as appropriate. Other comparisons return NotImplemented. + if equality_op and isinstance(other, _numbers.Complex) and other.imag == 0: + other = other.real + if isinstance(other, float): + return self, Decimal.from_float(other) + return NotImplemented, NotImplemented + + ##### Setup Specific Contexts ############################################ # The default context prototype used by Context() Modified: python/branches/py3k-jit/Lib/distutils/unixccompiler.py ============================================================================== --- python/branches/py3k-jit/Lib/distutils/unixccompiler.py (original) +++ python/branches/py3k-jit/Lib/distutils/unixccompiler.py Wed Jun 16 18:21:24 2010 @@ -15,7 +15,7 @@ __revision__ = "$Id$" -import os, sys +import os, sys, re from distutils.dep_util import newer from distutils.ccompiler import \ @@ -320,10 +320,31 @@ dylib_f = self.library_filename(lib, lib_type='dylib') static_f = self.library_filename(lib, lib_type='static') + if sys.platform == 'darwin': + # On OSX users can specify an alternate SDK using + # '-isysroot', calculate the SDK root if it is specified + # (and use it further on) + _sysconfig = __import__('sysconfig') + cflags = _sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + + + for dir in dirs: shared = os.path.join(dir, shared_f) dylib = os.path.join(dir, dylib_f) static = os.path.join(dir, static_f) + + if sys.platform == 'darwin' and ( + dir.startswith('/System/') or dir.startswith('/usr/')): + shared = os.path.join(sysroot, dir[1:], shared_f) + dylib = os.path.join(sysroot, dir[1:], dylib_f) + static = os.path.join(sysroot, dir[1:], static_f) + # We're second-guessing the linker here, with not much hard # data to go on: GCC seems to prefer the shared library, so I'm # assuming that *all* Unix C compilers do. And of course I'm Modified: python/branches/py3k-jit/Lib/doctest.py ============================================================================== --- python/branches/py3k-jit/Lib/doctest.py (original) +++ python/branches/py3k-jit/Lib/doctest.py Wed Jun 16 18:21:24 2010 @@ -1277,9 +1277,9 @@ # Another chance if they didn't care about the detail. elif self.optionflags & IGNORE_EXCEPTION_DETAIL: - m1 = re.match(r'[^:]*:', example.exc_msg) - m2 = re.match(r'[^:]*:', exc_msg) - if m1 and m2 and check(m1.group(0), m2.group(0), + m1 = re.match(r'(?:[^:]*\.)?([^:]*:)', example.exc_msg) + m2 = re.match(r'(?:[^:]*\.)?([^:]*:)', exc_msg) + if m1 and m2 and check(m1.group(1), m2.group(1), self.optionflags): outcome = SUCCESS Modified: python/branches/py3k-jit/Lib/email/charset.py ============================================================================== --- python/branches/py3k-jit/Lib/email/charset.py (original) +++ python/branches/py3k-jit/Lib/email/charset.py Wed Jun 16 18:21:24 2010 @@ -377,6 +377,8 @@ """ # 7bit/8bit encodings return the string unchanged (module conversions) if self.body_encoding is BASE64: + if isinstance(string, str): + string = string.encode(self.output_charset) return email.base64mime.body_encode(string) elif self.body_encoding is QP: return email.quoprimime.body_encode(string) Modified: python/branches/py3k-jit/Lib/email/encoders.py ============================================================================== --- python/branches/py3k-jit/Lib/email/encoders.py (original) +++ python/branches/py3k-jit/Lib/email/encoders.py Wed Jun 16 18:21:24 2010 @@ -29,7 +29,7 @@ Also, add an appropriate Content-Transfer-Encoding header. """ orig = msg.get_payload() - encdata = _bencode(orig) + encdata = str(_bencode(orig), 'ascii') msg.set_payload(encdata) msg['Content-Transfer-Encoding'] = 'base64' Modified: python/branches/py3k-jit/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k-jit/Lib/email/test/test_email.py (original) +++ python/branches/py3k-jit/Lib/email/test/test_email.py Wed Jun 16 18:21:24 2010 @@ -535,7 +535,7 @@ # whose output character set is 7bit gets a transfer-encoding # of 7bit. eq = self.assertEqual - msg = MIMEText('\xca\xb8', _charset='euc-jp') + msg = MIMEText('?', _charset='euc-jp') eq(msg['content-transfer-encoding'], '7bit') @@ -970,7 +970,8 @@ def test_encoding(self): payload = self._au.get_payload() - self.assertEqual(base64.decodebytes(payload), self._audiodata) + self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), + self._audiodata) def test_checkSetMinor(self): au = MIMEAudio(self._audiodata, 'fish') @@ -1010,7 +1011,8 @@ def test_encoding(self): payload = self._im.get_payload() - self.assertEqual(base64.decodebytes(payload), self._imgdata) + self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), + self._imgdata) def test_checkSetMinor(self): im = MIMEImage(self._imgdata, 'fish') @@ -1050,7 +1052,7 @@ eq = self.assertEqual bytes = b'\xfa\xfb\xfc\xfd\xfe\xff' msg = MIMEApplication(bytes) - eq(msg.get_payload(), b'+vv8/f7/') + eq(msg.get_payload(), '+vv8/f7/') eq(msg.get_payload(decode=True), bytes) @@ -1080,6 +1082,33 @@ eq(msg.get_charset().input_charset, 'us-ascii') eq(msg['content-type'], 'text/plain; charset="us-ascii"') + def test_7bit_input(self): + eq = self.assertEqual + msg = MIMEText('hello there', _charset='us-ascii') + eq(msg.get_charset().input_charset, 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + + def test_7bit_input_no_charset(self): + eq = self.assertEqual + msg = MIMEText('hello there') + eq(msg.get_charset(), 'us-ascii') + eq(msg['content-type'], 'text/plain; charset="us-ascii"') + self.assertTrue('hello there' in msg.as_string()) + + def test_utf8_input(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + eq = self.assertEqual + msg = MIMEText(teststr, _charset='utf-8') + eq(msg.get_charset().output_charset, 'utf-8') + eq(msg['content-type'], 'text/plain; charset="utf-8"') + eq(msg.get_payload(decode=True), teststr.encode('utf-8')) + + @unittest.skip("can't fix because of backward compat in email5, " + "will fix in email6") + def test_utf8_input_no_charset(self): + teststr = '\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' + self.assertRaises(UnicodeEncodeError, MIMEText, teststr) + # Test complicated multipart/* messages Modified: python/branches/py3k-jit/Lib/ftplib.py ============================================================================== --- python/branches/py3k-jit/Lib/ftplib.py (original) +++ python/branches/py3k-jit/Lib/ftplib.py Wed Jun 16 18:21:24 2010 @@ -638,9 +638,17 @@ ssl_version = ssl.PROTOCOL_TLSv1 def __init__(self, host='', user='', passwd='', acct='', keyfile=None, - certfile=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): + certfile=None, context=None, + timeout=_GLOBAL_DEFAULT_TIMEOUT): + if context is not None and keyfile is not None: + raise ValueError("context and keyfile arguments are mutually " + "exclusive") + if context is not None and certfile is not None: + raise ValueError("context and certfile arguments are mutually " + "exclusive") self.keyfile = keyfile self.certfile = certfile + self.context = context self._prot_p = False FTP.__init__(self, host, user, passwd, acct, timeout) @@ -657,8 +665,12 @@ resp = self.voidcmd('AUTH TLS') else: resp = self.voidcmd('AUTH SSL') - self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, - ssl_version=self.ssl_version) + if self.context is not None: + self.sock = self.context.wrap_socket(self.sock) + else: + self.sock = ssl.wrap_socket(self.sock, self.keyfile, + self.certfile, + ssl_version=self.ssl_version) self.file = self.sock.makefile(mode='r', encoding=self.encoding) return resp @@ -689,8 +701,11 @@ def ntransfercmd(self, cmd, rest=None): conn, size = FTP.ntransfercmd(self, cmd, rest) if self._prot_p: - conn = ssl.wrap_socket(conn, self.keyfile, self.certfile, - ssl_version=self.ssl_version) + if self.context is not None: + conn = self.context.wrap_socket(conn) + else: + conn = ssl.wrap_socket(conn, self.keyfile, self.certfile, + ssl_version=self.ssl_version) return conn, size def retrbinary(self, cmd, callback, blocksize=8192, rest=None): Modified: python/branches/py3k-jit/Lib/html/parser.py ============================================================================== --- python/branches/py3k-jit/Lib/html/parser.py (original) +++ python/branches/py3k-jit/Lib/html/parser.py Wed Jun 16 18:21:24 2010 @@ -175,6 +175,9 @@ i = self.updatepos(i, k) continue else: + if ";" in rawdata[i:]: #bail by consuming &# + self.handle_data(rawdata[0:2]) + i = self.updatepos(i, 2) break elif startswith('&', i): match = entityref.match(rawdata, i) Modified: python/branches/py3k-jit/Lib/http/client.py ============================================================================== --- python/branches/py3k-jit/Lib/http/client.py (original) +++ python/branches/py3k-jit/Lib/http/client.py Wed Jun 16 18:21:24 2010 @@ -488,6 +488,7 @@ return b"" if self._method == "HEAD": + self.close() return b"" if self.chunked: Modified: python/branches/py3k-jit/Lib/logging/config.py ============================================================================== --- python/branches/py3k-jit/Lib/logging/config.py (original) +++ python/branches/py3k-jit/Lib/logging/config.py Wed Jun 16 18:21:24 2010 @@ -373,7 +373,7 @@ } # We might want to use a different one, e.g. importlib - importer = __import__ + importer = staticmethod(__import__) def __init__(self, config): self.config = ConvertingDict(config) Modified: python/branches/py3k-jit/Lib/os.py ============================================================================== --- python/branches/py3k-jit/Lib/os.py (original) +++ python/branches/py3k-jit/Lib/os.py Wed Jun 16 18:21:24 2010 @@ -533,16 +533,19 @@ return environb.get(key, default) __all__.append("getenvb") -if name != 'nt': - def fsencode(value): - """Encode value for use in the file system, environment variables - or the command line.""" - if isinstance(value, bytes): - return value - elif isinstance(value, str): - return value.encode(sys.getfilesystemencoding(), 'surrogateescape') +def fsencode(value): + """Encode value for use in the file system, environment variables + or the command line.""" + if isinstance(value, bytes): + return value + elif isinstance(value, str): + encoding = sys.getfilesystemencoding() + if encoding == 'mbcs': + return value.encode(encoding) else: - raise TypeError("expect bytes or str, not %s" % type(value).__name__) + return value.encode(encoding, 'surrogateescape') + else: + raise TypeError("expect bytes or str, not %s" % type(value).__name__) def _exists(name): return name in globals() Modified: python/branches/py3k-jit/Lib/sqlite3/test/dbapi.py ============================================================================== --- python/branches/py3k-jit/Lib/sqlite3/test/dbapi.py (original) +++ python/branches/py3k-jit/Lib/sqlite3/test/dbapi.py Wed Jun 16 18:21:24 2010 @@ -84,6 +84,7 @@ "NotSupportedError is not a subclass of DatabaseError") class ConnectionTests(unittest.TestCase): + def setUp(self): self.cx = sqlite.connect(":memory:") cu = self.cx.cursor() @@ -140,6 +141,28 @@ self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError) self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError) + def CheckInTransaction(self): + # Can't use db from setUp because we want to test initial state. + cx = sqlite.connect(":memory:") + cu = cx.cursor() + self.assertEqual(cx.in_transaction, False) + cu.execute("create table transactiontest(id integer primary key, name text)") + self.assertEqual(cx.in_transaction, False) + cu.execute("insert into transactiontest(name) values (?)", ("foo",)) + self.assertEqual(cx.in_transaction, True) + cu.execute("select name from transactiontest where name=?", ["foo"]) + row = cu.fetchone() + self.assertEqual(cx.in_transaction, True) + cx.commit() + self.assertEqual(cx.in_transaction, False) + cu.execute("select name from transactiontest where name=?", ["foo"]) + row = cu.fetchone() + self.assertEqual(cx.in_transaction, False) + + def CheckInTransactionRO(self): + with self.assertRaises(AttributeError): + self.cx.in_transaction = True + class CursorTests(unittest.TestCase): def setUp(self): self.cx = sqlite.connect(":memory:") Modified: python/branches/py3k-jit/Lib/struct.py ============================================================================== --- python/branches/py3k-jit/Lib/struct.py (original) +++ python/branches/py3k-jit/Lib/struct.py Wed Jun 16 18:21:24 2010 @@ -1,3 +1,14 @@ +__all__ = [ + # Functions + 'calcsize', 'pack', 'unpack', 'unpack', 'unpack_from', + + # Classes + 'Struct', + + # Exceptions + 'error' + ] + from _struct import * from _struct import _clearcache from _struct import __doc__ Modified: python/branches/py3k-jit/Lib/sunau.py ============================================================================== --- python/branches/py3k-jit/Lib/sunau.py (original) +++ python/branches/py3k-jit/Lib/sunau.py Wed Jun 16 18:21:24 2010 @@ -299,7 +299,7 @@ self._nframeswritten = 0 self._datawritten = 0 self._datalength = 0 - self._info = '' + self._info = b'' self._comptype = 'ULAW' # default is U-law def setnchannels(self, nchannels): Modified: python/branches/py3k-jit/Lib/sysconfig.py ============================================================================== --- python/branches/py3k-jit/Lib/sysconfig.py (original) +++ python/branches/py3k-jit/Lib/sysconfig.py Wed Jun 16 18:21:24 2010 @@ -5,6 +5,10 @@ import os from os.path import pardir, realpath +__all__ = ['parse_config_h', 'get_config_h_filename', 'get_scheme_names', + 'get_path_names', 'get_paths', 'get_path', 'get_config_vars', + 'get_config_var', 'get_platform', 'get_python_version'] + _INSTALL_SCHEMES = { 'posix_prefix': { 'stdlib': '{base}/lib/python{py_version_short}', @@ -712,3 +716,22 @@ def get_python_version(): return _PY_VERSION_SHORT + +def _print_dict(title, data): + for index, (key, value) in enumerate(sorted(data.items())): + if index == 0: + print('{0}: '.format(title)) + print('\t{0} = "{1}"'.format(key, value)) + +def _main(): + """Displays all information sysconfig detains.""" + print('Platform: "{0}"'.format(get_platform())) + print('Python version: "{0}"'.format(get_python_version())) + print('Current installation scheme: "{0}"'.format(_get_default_scheme())) + print('') + _print_dict('Paths', get_paths()) + print('') + _print_dict('Variables', get_config_vars()) + +if __name__ == '__main__': + _main() Modified: python/branches/py3k-jit/Lib/tarfile.py ============================================================================== --- python/branches/py3k-jit/Lib/tarfile.py (original) +++ python/branches/py3k-jit/Lib/tarfile.py Wed Jun 16 18:21:24 2010 @@ -159,9 +159,10 @@ #--------------------------------------------------------- # initialization #--------------------------------------------------------- -ENCODING = sys.getfilesystemencoding() -if ENCODING is None: - ENCODING = "ascii" +if os.name in ("nt", "ce"): + ENCODING = "utf-8" +else: + ENCODING = sys.getfilesystemencoding() #--------------------------------------------------------- # Some useful functions @@ -1920,7 +1921,7 @@ tarinfo.mode = stmd tarinfo.uid = statres.st_uid tarinfo.gid = statres.st_gid - if stat.S_ISREG(stmd): + if type == REGTYPE: tarinfo.size = statres.st_size else: tarinfo.size = 0 @@ -2163,8 +2164,7 @@ raise StreamError("cannot extract (sym)link as file object") else: # A (sym)link's file object is its target's file object. - return self.extractfile(self._getmember(tarinfo.linkname, - tarinfo)) + return self.extractfile(self._find_link_target(tarinfo)) else: # If there's no data associated with the member (directory, chrdev, # blkdev, etc.), return None instead of a file object. @@ -2273,27 +2273,21 @@ (platform limitation), we try to make a copy of the referenced file instead of a link. """ - try: + if hasattr(os, "symlink") and hasattr(os, "link"): + # For systems that support symbolic and hard links. if tarinfo.issym(): os.symlink(tarinfo.linkname, targetpath) else: # See extract(). - os.link(tarinfo._link_target, targetpath) - except AttributeError: - if tarinfo.issym(): - linkpath = os.path.dirname(tarinfo.name) + "/" + \ - tarinfo.linkname - else: - linkpath = tarinfo.linkname - + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), targetpath) + else: try: - self._extract_member(self.getmember(linkpath), targetpath) - except (EnvironmentError, KeyError) as e: - linkpath = linkpath.replace("/", os.sep) - try: - shutil.copy2(linkpath, targetpath) - except EnvironmentError as e: - raise IOError("link could not be created") + self._extract_member(self._find_link_target(tarinfo), targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") def chown(self, tarinfo, targetpath): """Set owner of targetpath according to tarinfo. @@ -2392,21 +2386,28 @@ #-------------------------------------------------------------------------- # Little helper methods: - def _getmember(self, name, tarinfo=None): + def _getmember(self, name, tarinfo=None, normalize=False): """Find an archive member by name from bottom to top. If tarinfo is given, it is used as the starting point. """ # Ensure that all members have been loaded. members = self.getmembers() - if tarinfo is None: - end = len(members) - else: - end = members.index(tarinfo) + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] - for i in range(end - 1, -1, -1): - if name == members[i].name: - return members[i] + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member def _load(self): """Read through the entire archive file and look for readable @@ -2427,6 +2428,25 @@ if mode is not None and self.mode not in mode: raise IOError("bad operation for mode %r" % self.mode) + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + def __iter__(self): """Provide an iterator object. """ Modified: python/branches/py3k-jit/Lib/test/math_testcases.txt ============================================================================== --- python/branches/py3k-jit/Lib/test/math_testcases.txt (original) +++ python/branches/py3k-jit/Lib/test/math_testcases.txt Wed Jun 16 18:21:24 2010 @@ -84,6 +84,25 @@ erf0042 erf -1e150 -> -1.0 erf0043 erf 1.7e308 -> 1.0 +-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold +-- incorrectly signalled overflow on some platforms. +erf0100 erf 26.2 -> 1.0 +erf0101 erf 26.4 -> 1.0 +erf0102 erf 26.6 -> 1.0 +erf0103 erf 26.8 -> 1.0 +erf0104 erf 27.0 -> 1.0 +erf0105 erf 27.2 -> 1.0 +erf0106 erf 27.4 -> 1.0 +erf0107 erf 27.6 -> 1.0 + +erf0110 erf -26.2 -> -1.0 +erf0111 erf -26.4 -> -1.0 +erf0112 erf -26.6 -> -1.0 +erf0113 erf -26.8 -> -1.0 +erf0114 erf -27.0 -> -1.0 +erf0115 erf -27.2 -> -1.0 +erf0116 erf -27.4 -> -1.0 +erf0117 erf -27.6 -> -1.0 ---------------------------------------- -- erfc: complementary error function -- @@ -127,6 +146,25 @@ erfc0052 erfc -1e150 -> 2.0 erfc0053 erfc 1.7e308 -> 0.0 +-- Issue 8986: inputs x with exp(-x*x) near the underflow threshold +-- incorrectly signalled overflow on some platforms. +erfc0100 erfc 26.2 -> 1.6432507924389461e-300 +erfc0101 erfc 26.4 -> 4.4017768588035426e-305 +erfc0102 erfc 26.6 -> 1.0885125885442269e-309 +erfc0103 erfc 26.8 -> 2.4849621571966629e-314 +erfc0104 erfc 27.0 -> 5.2370464393526292e-319 +erfc0105 erfc 27.2 -> 9.8813129168249309e-324 +erfc0106 erfc 27.4 -> 0.0 +erfc0107 erfc 27.6 -> 0.0 + +erfc0110 erfc -26.2 -> 2.0 +erfc0111 erfc -26.4 -> 2.0 +erfc0112 erfc -26.6 -> 2.0 +erfc0113 erfc -26.8 -> 2.0 +erfc0114 erfc -27.0 -> 2.0 +erfc0115 erfc -27.2 -> 2.0 +erfc0116 erfc -27.4 -> 2.0 +erfc0117 erfc -27.6 -> 2.0 --------------------------------------------------------- -- lgamma: log of absolute value of the gamma function -- Modified: python/branches/py3k-jit/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k-jit/Lib/test/regrtest.py (original) +++ python/branches/py3k-jit/Lib/test/regrtest.py Wed Jun 16 18:21:24 2010 @@ -859,9 +859,15 @@ sys.path_hooks[:] = saved_hooks[2] def get___import__(self): - return __builtins__.__import__ + if isinstance(__builtins__, dict): + return __builtins__['__import__'] + else: + return __builtins__.__import__ def restore___import__(self, import_): - __builtins__.__import__ = import_ + if isinstance(__builtins__, dict): + __builtins__['__import__'] = import_ + else: + __builtins__.__import__ = import_ def get_warnings_filters(self): return id(warnings.filters), warnings.filters, warnings.filters[:] Modified: python/branches/py3k-jit/Lib/test/test_base64.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_base64.py (original) +++ python/branches/py3k-jit/Lib/test/test_base64.py Wed Jun 16 18:21:24 2010 @@ -2,6 +2,8 @@ from test import support import base64 import binascii +import sys +import subprocess @@ -208,6 +210,38 @@ +class TestMain(unittest.TestCase): + def get_output(self, *args, **options): + args = (sys.executable, '-m', 'base64') + args + return subprocess.check_output(args, **options) + + def test_encode_decode(self): + output = self.get_output('-t') + self.assertSequenceEqual(output.splitlines(), ( + b"b'Aladdin:open sesame'", + br"b'QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n'", + b"b'Aladdin:open sesame'", + )) + + def test_encode_file(self): + with open(support.TESTFN, 'wb') as fp: + fp.write(b'a\xffb\n') + + output = self.get_output('-e', support.TESTFN) + self.assertEquals(output.rstrip(), b'Yf9iCg==') + + with open(support.TESTFN, 'rb') as fp: + output = self.get_output('-e', stdin=fp) + self.assertEquals(output.rstrip(), b'Yf9iCg==') + + def test_decode(self): + with open(support.TESTFN, 'wb') as fp: + fp.write(b'Yf9iCg==') + output = self.get_output('-d', support.TESTFN) + self.assertEquals(output.rstrip(), b'a\xffb') + + + def test_main(): support.run_unittest(__name__) Modified: python/branches/py3k-jit/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_builtin.py (original) +++ python/branches/py3k-jit/Lib/test/test_builtin.py Wed Jun 16 18:21:24 2010 @@ -124,6 +124,16 @@ self.assertEqual(abs(-3.14), 3.14) # str self.assertRaises(TypeError, abs, 'a') + # bool + self.assertEqual(abs(True), 1) + self.assertEqual(abs(False), 0) + # other + self.assertRaises(TypeError, abs) + self.assertRaises(TypeError, abs, None) + class AbsClass(object): + def __abs__(self): + return -5 + self.assertEqual(abs(AbsClass()), -5) def test_all(self): self.assertEqual(all([2, 4, 6]), True) @@ -600,6 +610,8 @@ def __len__(self): return sys.maxsize + 1 self.assertRaises(OverflowError, len, HugeLen()) + class NoLenMethod(object): pass + self.assertRaises(TypeError, len, NoLenMethod()) def test_map(self): self.assertEqual( @@ -1187,6 +1199,11 @@ b = 2 return vars() + class C_get_vars(object): + def getDict(self): + return {'a':2} + __dict__ = property(fget=getDict) + def test_vars(self): self.assertEqual(set(vars()), set(dir())) import sys @@ -1195,6 +1212,7 @@ self.assertEqual(self.get_vars_f2(), {'a': 1, 'b': 2}) self.assertRaises(TypeError, vars, 42, 42) self.assertRaises(TypeError, vars, 42) + self.assertEqual(vars(self.C_get_vars()), {'a':2}) def test_zip(self): a = (1, 2, 3) Modified: python/branches/py3k-jit/Lib/test/test_calendar.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_calendar.py (original) +++ python/branches/py3k-jit/Lib/test/test_calendar.py Wed Jun 16 18:21:24 2010 @@ -2,7 +2,7 @@ import unittest from test import support - +import time result_2004_text = """ 2004 @@ -381,13 +381,21 @@ # A 31-day december starting on friday (2+7+7+7+7+1 days) self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1)) +class TimegmTestCase(unittest.TestCase): + TIMESTAMPS = [0, 10, 100, 1000, 10000, 100000, 1000000, + 1234567890, 1262304000, 1275785153,] + def test_timegm(self): + for secs in self.TIMESTAMPS: + tuple = time.gmtime(secs) + self.assertEqual(secs, calendar.timegm(tuple)) def test_main(): support.run_unittest( OutputTestCase, CalendarTestCase, MondayTestCase, - SundayTestCase + SundayTestCase, + TimegmTestCase, ) Modified: python/branches/py3k-jit/Lib/test/test_capi.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_capi.py (original) +++ python/branches/py3k-jit/Lib/test/test_capi.py Wed Jun 16 18:21:24 2010 @@ -36,6 +36,7 @@ self.assertEqual(testfunction.attribute, "test") self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test") + @unittest.skipUnless(threading, 'Threading required for this test.') def test_no_FatalError_infinite_loop(self): p = subprocess.Popen([sys.executable, "-c", 'import _testcapi;' Modified: python/branches/py3k-jit/Lib/test/test_codecs.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_codecs.py (original) +++ python/branches/py3k-jit/Lib/test/test_codecs.py Wed Jun 16 18:21:24 2010 @@ -72,7 +72,6 @@ # check that there's nothing left in the buffers self.assertEqual(r.read(), "") self.assertEqual(r.bytebuffer, b"") - self.assertEqual(r.charbuffer, "") # do the check again, this time using a incremental decoder d = codecs.getincrementaldecoder(self.encoding)() @@ -354,6 +353,16 @@ self.check_state_handling_decode(self.encoding, "spamspam", self.spambe) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded_le = b'\xff\xfe\x00\x00' + b'\x00\x00\x01\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_decode(encoded_le)[0]) + encoded_be = b'\x00\x00\xfe\xff' + b'\x00\x01\x00\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_decode(encoded_be)[0]) + class UTF32LETest(ReadTest): encoding = "utf-32-le" @@ -387,6 +396,13 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_le_decode, b"\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = b'\x00\x00\x01\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_le_decode(encoded)[0]) + class UTF32BETest(ReadTest): encoding = "utf-32-be" @@ -420,6 +436,14 @@ self.assertRaises(UnicodeDecodeError, codecs.utf_32_be_decode, b"\xff", "strict", True) + def test_issue8941(self): + # Issue #8941: insufficient result allocation when decoding into + # surrogate pairs on UCS-2 builds. + encoded = b'\x00\x01\x00\x00' * 1024 + self.assertEqual('\U00010000' * 1024, + codecs.utf_32_be_decode(encoded)[0]) + + class UTF16Test(ReadTest): encoding = "utf-16" @@ -628,18 +652,6 @@ self.assertRaises(TypeError, codecs.readbuffer_encode) self.assertRaises(TypeError, codecs.readbuffer_encode, 42) -class CharBufferTest(unittest.TestCase): - - def test_string(self): - self.assertEqual(codecs.charbuffer_encode(b"spam"), (b"spam", 4)) - - def test_empty(self): - self.assertEqual(codecs.charbuffer_encode(b""), (b"", 0)) - - def test_bad_args(self): - self.assertRaises(TypeError, codecs.charbuffer_encode) - self.assertRaises(TypeError, codecs.charbuffer_encode, 42) - class UTF8SigTest(ReadTest): encoding = "utf-8-sig" @@ -1663,7 +1675,6 @@ UTF7Test, UTF16ExTest, ReadBufferTest, - CharBufferTest, RecodingTest, PunycodeTest, UnicodeInternalTest, Modified: python/branches/py3k-jit/Lib/test/test_curses.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_curses.py (original) +++ python/branches/py3k-jit/Lib/test/test_curses.py Wed Jun 16 18:21:24 2010 @@ -23,11 +23,6 @@ curses = import_module('curses') curses.panel = import_module('curses.panel') -# skip all these tests on FreeBSD: test_curses currently hangs the -# FreeBSD buildbots, preventing other tests from running. See issue -# #7384. -if 'freebsd' in sys.platform: - raise unittest.SkipTest('The curses module is broken on FreeBSD. See http://bugs.python.org/issue7384.') # XXX: if newterm was supported we could use it instead of initscr and not exit term = os.environ.get('TERM') Modified: python/branches/py3k-jit/Lib/test/test_datetime.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_datetime.py (original) +++ python/branches/py3k-jit/Lib/test/test_datetime.py Wed Jun 16 18:21:24 2010 @@ -3,7 +3,7 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ -import os +import sys import pickle import unittest @@ -15,6 +15,7 @@ from datetime import timedelta from datetime import tzinfo from datetime import time +from datetime import timezone from datetime import date, datetime pickle_choices = [(pickle, pickle, proto) for proto in range(3)] @@ -25,6 +26,16 @@ OTHERSTUFF = (10, 34.5, "abc", {}, [], ()) +# XXX Copied from test_float. +INF = float("inf") +NAN = float("nan") + +# decorator for skipping tests on non-IEEE 754 platforms +requires_IEEE_754 = unittest.skipUnless( + float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + + ############################################################################# # module tests @@ -39,6 +50,7 @@ # tzinfo tests class FixedOffset(tzinfo): + def __init__(self, offset, name, dstoffset=42): if isinstance(offset, int): offset = timedelta(minutes=offset) @@ -57,6 +69,7 @@ return self.__dstoffset class PicklableFixedOffset(FixedOffset): + def __init__(self, offset=None, name=None, dstoffset=None): FixedOffset.__init__(self, offset, name, dstoffset) @@ -121,6 +134,97 @@ self.assertEqual(derived.utcoffset(None), offset) self.assertEqual(derived.tzname(None), 'cookie') +class TestTimeZone(unittest.TestCase): + + def setUp(self): + self.ACDT = timezone(timedelta(hours=9.5), 'ACDT') + self.EST = timezone(-timedelta(hours=5), 'EST') + self.DT = datetime(2010, 1, 1) + + def test_str(self): + for tz in [self.ACDT, self.EST, timezone.utc, + timezone.min, timezone.max]: + self.assertEqual(str(tz), tz.tzname(None)) + + def test_class_members(self): + limit = timedelta(hours=23, minutes=59) + self.assertEquals(timezone.utc.utcoffset(None), ZERO) + self.assertEquals(timezone.min.utcoffset(None), -limit) + self.assertEquals(timezone.max.utcoffset(None), limit) + + + def test_constructor(self): + self.assertEquals(timezone.utc, timezone(timedelta(0))) + # invalid offsets + for invalid in [timedelta(microseconds=1), timedelta(1, 1), + timedelta(seconds=1), timedelta(1), -timedelta(1)]: + self.assertRaises(ValueError, timezone, invalid) + self.assertRaises(ValueError, timezone, -invalid) + + with self.assertRaises(TypeError): timezone(None) + with self.assertRaises(TypeError): timezone(42) + with self.assertRaises(TypeError): timezone(ZERO, None) + with self.assertRaises(TypeError): timezone(ZERO, 42) + + def test_inheritance(self): + self.assertTrue(isinstance(timezone.utc, tzinfo)) + self.assertTrue(isinstance(self.EST, tzinfo)) + + def test_utcoffset(self): + dummy = self.DT + for h in [0, 1.5, 12]: + offset = h * HOUR + self.assertEquals(offset, timezone(offset).utcoffset(dummy)) + self.assertEquals(-offset, timezone(-offset).utcoffset(dummy)) + + with self.assertRaises(TypeError): self.EST.utcoffset('') + with self.assertRaises(TypeError): self.EST.utcoffset(5) + + + def test_dst(self): + self.assertEquals(None, timezone.utc.dst(self.DT)) + + with self.assertRaises(TypeError): self.EST.dst('') + with self.assertRaises(TypeError): self.EST.dst(5) + + def test_tzname(self): + self.assertEquals('UTC+00:00', timezone(ZERO).tzname(None)) + self.assertEquals('UTC-05:00', timezone(-5 * HOUR).tzname(None)) + self.assertEquals('UTC+09:30', timezone(9.5 * HOUR).tzname(None)) + self.assertEquals('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None)) + self.assertEquals('XYZ', timezone(-5 * HOUR, 'XYZ').tzname(None)) + + with self.assertRaises(TypeError): self.EST.tzname('') + with self.assertRaises(TypeError): self.EST.tzname(5) + + def test_fromutc(self): + with self.assertRaises(ValueError): + timezone.utc.fromutc(self.DT) + for tz in [self.EST, self.ACDT, Eastern]: + utctime = self.DT.replace(tzinfo=tz) + local = tz.fromutc(utctime) + self.assertEquals(local - utctime, tz.utcoffset(local)) + self.assertEquals(local, + self.DT.replace(tzinfo=timezone.utc)) + + def test_comparison(self): + self.assertNotEqual(timezone(ZERO), timezone(HOUR)) + self.assertEqual(timezone(HOUR), timezone(HOUR)) + self.assertEqual(timezone(-5 * HOUR), timezone(-5 * HOUR, 'EST')) + with self.assertRaises(TypeError): timezone(ZERO) < timezone(ZERO) + self.assertIn(timezone(ZERO), {timezone(ZERO)}) + + def test_aware_datetime(self): + # test that timezone instances can be used by datetime + t = datetime(1, 1, 1) + for tz in [timezone.min, timezone.max, timezone.utc]: + self.assertEquals(tz.tzname(t), + t.replace(tzinfo=tz).tzname()) + self.assertEquals(tz.utcoffset(t), + t.replace(tzinfo=tz).utcoffset()) + self.assertEquals(tz.dst(t), + t.replace(tzinfo=tz).dst()) + ############################################################################# # Base clase for testing a particular aspect of timedelta, time, date and # datetime comparisons. @@ -225,6 +329,36 @@ eq(c//1000, td(0, 0, 1)) eq(a//10, td(0, 7*24*360)) eq(a//3600000, td(0, 0, 7*24*1000)) + eq(a/0.5, td(14)) + eq(b/0.5, td(0, 120)) + eq(a/7, td(1)) + eq(b/10, td(0, 6)) + eq(c/1000, td(0, 0, 1)) + eq(a/10, td(0, 7*24*360)) + eq(a/3600000, td(0, 0, 7*24*1000)) + + # Multiplication by float + us = td(microseconds=1) + eq((3*us) * 0.5, 2*us) + eq((5*us) * 0.5, 2*us) + eq(0.5 * (3*us), 2*us) + eq(0.5 * (5*us), 2*us) + eq((-3*us) * 0.5, -2*us) + eq((-5*us) * 0.5, -2*us) + + # Division by int and float + eq((3*us) / 2, 2*us) + eq((5*us) / 2, 2*us) + eq((-3*us) / 2.0, -2*us) + eq((-5*us) / 2.0, -2*us) + eq((3*us) / -2, -2*us) + eq((5*us) / -2, -2*us) + eq((3*us) / -2.0, -2*us) + eq((5*us) / -2.0, -2*us) + for i in range(-10, 10): + eq((i*us/3)//us, round(i/3)) + for i in range(-10, 10): + eq((i*us/-3)//us, round(i/-3)) def test_disallowed_computations(self): a = timedelta(42) @@ -236,20 +370,19 @@ self.assertRaises(TypeError, lambda: i+a) self.assertRaises(TypeError, lambda: i-a) - # Mul/div by float isn't supported. - x = 2.3 - self.assertRaises(TypeError, lambda: a*x) - self.assertRaises(TypeError, lambda: x*a) - self.assertRaises(TypeError, lambda: a/x) - self.assertRaises(TypeError, lambda: x/a) - self.assertRaises(TypeError, lambda: a // x) - self.assertRaises(TypeError, lambda: x // a) - # Division of int by timedelta doesn't make sense. # Division by zero doesn't make sense. zero = 0 self.assertRaises(TypeError, lambda: zero // a) self.assertRaises(ZeroDivisionError, lambda: a // zero) + self.assertRaises(ZeroDivisionError, lambda: a / zero) + self.assertRaises(ZeroDivisionError, lambda: a / 0.0) + + @requires_IEEE_754 + def test_disallowed_special(self): + a = timedelta(42) + self.assertRaises(ValueError, a.__mul__, NAN) + self.assertRaises(ValueError, a.__truediv__, NAN) def test_basic_attributes(self): days, seconds, us = 1, 7, 31 @@ -410,6 +543,19 @@ self.assertRaises(OverflowError, lambda: -timedelta.max) + day = timedelta(1) + self.assertRaises(OverflowError, day.__mul__, 10**9) + self.assertRaises(OverflowError, day.__mul__, 1e9) + self.assertRaises(OverflowError, day.__truediv__, 1e-20) + self.assertRaises(OverflowError, day.__truediv__, 1e-10) + self.assertRaises(OverflowError, day.__truediv__, 9e-10) + + @requires_IEEE_754 + def _test_overflow_special(self): + day = timedelta(1) + self.assertRaises(OverflowError, day.__mul__, INF) + self.assertRaises(OverflowError, day.__mul__, -INF) + def test_microsecond_rounding(self): td = timedelta eq = self.assertEqual @@ -489,7 +635,7 @@ self.assertRaises(ZeroDivisionError, truediv, t, zerotd) self.assertRaises(ZeroDivisionError, floordiv, t, zerotd) - self.assertRaises(TypeError, truediv, t, 2) + # self.assertRaises(TypeError, truediv, t, 2) # note: floor division of a timedelta by an integer *is* # currently permitted. @@ -761,15 +907,16 @@ def test_overflow(self): tiny = self.theclass.resolution - dt = self.theclass.min + tiny - dt -= tiny # no problem - self.assertRaises(OverflowError, dt.__sub__, tiny) - self.assertRaises(OverflowError, dt.__add__, -tiny) - - dt = self.theclass.max - tiny - dt += tiny # no problem - self.assertRaises(OverflowError, dt.__add__, tiny) - self.assertRaises(OverflowError, dt.__sub__, -tiny) + for delta in [tiny, timedelta(1), timedelta(2)]: + dt = self.theclass.min + delta + dt -= delta # no problem + self.assertRaises(OverflowError, dt.__sub__, delta) + self.assertRaises(OverflowError, dt.__add__, -delta) + + dt = self.theclass.max - delta + dt += delta # no problem + self.assertRaises(OverflowError, dt.__add__, delta) + self.assertRaises(OverflowError, dt.__sub__, -delta) def test_fromtimestamp(self): import time @@ -1554,19 +1701,14 @@ for insane in -1e200, 1e200: self.assertRaises(ValueError, self.theclass.utcfromtimestamp, insane) - + @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_fromtimestamp(self): - # Windows doesn't accept negative timestamps - if os.name == "nt": - return # The result is tz-dependent; at least test that this doesn't # fail (like it did before bug 1646728 was fixed). self.theclass.fromtimestamp(-1.05) + @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_utcfromtimestamp(self): - # Windows doesn't accept negative timestamps - if os.name == "nt": - return d = self.theclass.utcfromtimestamp(-1.05) self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) @@ -2681,20 +2823,21 @@ # We don't know which time zone we're in, and don't have a tzinfo # class to represent it, so seeing whether a tz argument actually # does a conversion is tricky. - weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0) utc = FixedOffset(0, "utc", 0) - for dummy in range(3): - now = datetime.now(weirdtz) - self.assertTrue(now.tzinfo is weirdtz) - utcnow = datetime.utcnow().replace(tzinfo=utc) - now2 = utcnow.astimezone(weirdtz) - if abs(now - now2) < timedelta(seconds=30): - break - # Else the code is broken, or more than 30 seconds passed between - # calls; assuming the latter, just try again. - else: - # Three strikes and we're out. - self.fail("utcnow(), now(tz), or astimezone() may be broken") + for weirdtz in [FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0), + timezone(timedelta(hours=15, minutes=58), "weirdtz"),]: + for dummy in range(3): + now = datetime.now(weirdtz) + self.assertTrue(now.tzinfo is weirdtz) + utcnow = datetime.utcnow().replace(tzinfo=utc) + now2 = utcnow.astimezone(weirdtz) + if abs(now - now2) < timedelta(seconds=30): + break + # Else the code is broken, or more than 30 seconds passed between + # calls; assuming the latter, just try again. + else: + # Three strikes and we're out. + self.fail("utcnow(), now(tz), or astimezone() may be broken") def test_tzinfo_fromtimestamp(self): import time Modified: python/branches/py3k-jit/Lib/test/test_descr.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_descr.py (original) +++ python/branches/py3k-jit/Lib/test/test_descr.py Wed Jun 16 18:21:24 2010 @@ -1557,6 +1557,8 @@ self.assertEqual(key, "hi") return 4 def swallow(*args): pass + def format_impl(self, spec): + return "hello" # It would be nice to have every special method tested here, but I'm # only listing the ones I can remember outside of typeobject.c, since it @@ -1575,6 +1577,7 @@ ("__enter__", run_context, iden, set(), {"__exit__" : swallow}), ("__exit__", run_context, swallow, set(), {"__enter__" : iden}), ("__complex__", complex, complex_num, set(), {}), + ("__format__", format, format_impl, set(), {}), ] class Checker(object): Modified: python/branches/py3k-jit/Lib/test/test_doctest.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_doctest.py (original) +++ python/branches/py3k-jit/Lib/test/test_doctest.py Wed Jun 16 18:21:24 2010 @@ -864,6 +864,77 @@ >>> doctest.DocTestRunner(verbose=False).run(test) TestResults(failed=0, attempted=1) +IGNORE_EXCEPTION_DETAIL also ignores difference in exception formatting +between Python versions. For example, in Python 2.x, the module path of +the exception is not in the output, but this will fail under Python 3: + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') + ... Traceback (most recent call last): + ... HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 4, in f + Failed example: + raise HTTPException('message') + Expected: + Traceback (most recent call last): + HTTPException: message + Got: + Traceback (most recent call last): + ... + http.client.HTTPException: message + TestResults(failed=1, attempted=2) + +But in Python 3 the module path is included, and therefore a test must look +like the following test to succeed in Python 3. But that test will fail under +Python 2. + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') + ... Traceback (most recent call last): + ... http.client.HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + +However, with IGNORE_EXCEPTION_DETAIL, the module name of the exception +(or its unexpected absence) will be ignored: + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + +The module path will be completely ignored, so two different module paths will +still pass if IGNORE_EXCEPTION_DETAIL is given. This is intentional, so it can +be used when exceptions have changed module. + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException('message') #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... foo.bar.HTTPException: message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type: >>> def f(x): Modified: python/branches/py3k-jit/Lib/test/test_enumerate.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_enumerate.py (original) +++ python/branches/py3k-jit/Lib/test/test_enumerate.py Wed Jun 16 18:21:24 2010 @@ -198,6 +198,18 @@ self.fail("non-callable __reversed__ didn't raise!") self.assertEqual(rc, sys.getrefcount(r)) + def test_objmethods(self): + # Objects must have __len__() and __getitem__() implemented. + class NoLen(object): + def __getitem__(self): return 1 + nl = NoLen() + self.assertRaises(TypeError, reversed, nl) + + class NoGetItem(object): + def __len__(self): return 2 + ngi = NoGetItem() + self.assertRaises(TypeError, reversed, ngi) + class EnumerateStartTestCase(EnumerateTestCase): @@ -227,7 +239,7 @@ if verbose and hasattr(sys, "gettotalrefcount"): counts = [None] * 5 for i in range(len(counts)): - support.run_unittest(*testclasses) + support.run_unittest(__name__) counts[i] = sys.gettotalrefcount() print(counts) Modified: python/branches/py3k-jit/Lib/test/test_fractions.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_fractions.py (original) +++ python/branches/py3k-jit/Lib/test/test_fractions.py Wed Jun 16 18:21:24 2010 @@ -395,12 +395,11 @@ self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10)) def testMixingWithDecimal(self): - # Decimal refuses mixed comparisons. + # Decimal refuses mixed arithmetic (but not mixed comparisons) self.assertRaisesMessage( TypeError, "unsupported operand type(s) for +: 'Fraction' and 'Decimal'", operator.add, F(3,11), Decimal('3.1415926')) - self.assertNotEquals(F(5, 2), Decimal('2.5')) def testComparisons(self): self.assertTrue(F(1, 2) < F(2, 3)) Modified: python/branches/py3k-jit/Lib/test/test_ftplib.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_ftplib.py (original) +++ python/branches/py3k-jit/Lib/test/test_ftplib.py Wed Jun 16 18:21:24 2010 @@ -719,6 +719,29 @@ finally: self.client.ssl_version = ssl.PROTOCOL_TLSv1 + def test_context(self): + self.client.quit() + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + self.assertRaises(ValueError, ftplib.FTP_TLS, keyfile=CERTFILE, + context=ctx) + self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE, + context=ctx) + self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE, + keyfile=CERTFILE, context=ctx) + + self.client = ftplib.FTP_TLS(context=ctx, timeout=2) + self.client.connect(self.server.host, self.server.port) + self.assertNotIsInstance(self.client.sock, ssl.SSLSocket) + self.client.auth() + self.assertIs(self.client.sock.context, ctx) + self.assertIsInstance(self.client.sock, ssl.SSLSocket) + + self.client.prot_p() + sock = self.client.transfercmd('list') + self.assertIs(sock.context, ctx) + self.assertIsInstance(sock, ssl.SSLSocket) + sock.close() + class TestTimeouts(TestCase): Modified: python/branches/py3k-jit/Lib/test/test_getargs2.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_getargs2.py (original) +++ python/branches/py3k-jit/Lib/test/test_getargs2.py Wed Jun 16 18:21:24 2010 @@ -1,7 +1,6 @@ import unittest from test import support from _testcapi import getargs_keywords -import warnings """ > How about the following counterproposal. This also changes some of @@ -190,21 +189,7 @@ from _testcapi import getargs_L # L returns 'long long', and does range checking (LLONG_MIN # ... LLONG_MAX) - with warnings.catch_warnings(): - warnings.filterwarnings( - "ignore", - category=DeprecationWarning, - message=".*integer argument expected, got float", - module=__name__) - self.assertEqual(3, getargs_L(3.14)) - with warnings.catch_warnings(): - warnings.filterwarnings( - "error", - category=DeprecationWarning, - message=".*integer argument expected, got float", - module="unittest") - self.assertRaises(DeprecationWarning, getargs_L, 3.14) - + self.assertRaises(TypeError, getargs_L, 3.14) self.assertRaises(TypeError, getargs_L, "Hello") self.assertEqual(99, getargs_L(Int())) @@ -308,8 +293,136 @@ else: self.fail('TypeError should have been raised') +class Bytes_TestCase(unittest.TestCase): + def test_s(self): + from _testcapi import getargs_s + self.assertEqual(getargs_s('abc\xe9'), b'abc\xc3\xa9') + self.assertRaises(TypeError, getargs_s, 'nul:\0') + self.assertRaises(TypeError, getargs_s, b'bytes') + self.assertRaises(TypeError, getargs_s, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_s, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_s, None) + + def test_s_star(self): + from _testcapi import getargs_s_star + self.assertEqual(getargs_s_star('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_s_star('nul:\0'), b'nul:\0') + self.assertEqual(getargs_s_star(b'bytes'), b'bytes') + self.assertEqual(getargs_s_star(bytearray(b'bytearray')), b'bytearray') + self.assertEqual(getargs_s_star(memoryview(b'memoryview')), b'memoryview') + self.assertRaises(TypeError, getargs_s_star, None) + + def test_s_hash(self): + from _testcapi import getargs_s_hash + self.assertEqual(getargs_s_hash('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_s_hash('nul:\0'), b'nul:\0') + self.assertEqual(getargs_s_hash(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_s_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_s_hash, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_s_hash, None) + + def test_z(self): + from _testcapi import getargs_z + self.assertEqual(getargs_z('abc\xe9'), b'abc\xc3\xa9') + self.assertRaises(TypeError, getargs_z, 'nul:\0') + self.assertEqual(getargs_z(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_z, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_z, memoryview(b'memoryview')) + self.assertIsNone(getargs_z(None)) + + def test_z_star(self): + from _testcapi import getargs_z_star + self.assertEqual(getargs_z_star('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_z_star('nul:\0'), b'nul:\0') + self.assertEqual(getargs_z_star(b'bytes'), b'bytes') + self.assertEqual(getargs_z_star(bytearray(b'bytearray')), b'bytearray') + self.assertEqual(getargs_z_star(memoryview(b'memoryview')), b'memoryview') + self.assertIsNone(getargs_z_star(None)) + + def test_z_hash(self): + from _testcapi import getargs_z_hash + self.assertEqual(getargs_z_hash('abc\xe9'), b'abc\xc3\xa9') + self.assertEqual(getargs_z_hash('nul:\0'), b'nul:\0') + self.assertEqual(getargs_z_hash(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_z_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_z_hash, memoryview(b'memoryview')) + self.assertIsNone(getargs_z_hash(None)) + + def test_y(self): + from _testcapi import getargs_y + self.assertRaises(TypeError, getargs_y, 'abc\xe9') + self.assertEqual(getargs_y(b'bytes'), b'bytes') + self.assertRaises(TypeError, getargs_y, b'nul:\0') + self.assertRaises(TypeError, getargs_y, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_y, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_y, None) + + def test_y_star(self): + from _testcapi import getargs_y_star + self.assertRaises(TypeError, getargs_y_star, 'abc\xe9') + self.assertEqual(getargs_y_star(b'bytes'), b'bytes') + self.assertEqual(getargs_y_star(b'nul:\0'), b'nul:\0') + self.assertEqual(getargs_y_star(bytearray(b'bytearray')), b'bytearray') + self.assertEqual(getargs_y_star(memoryview(b'memoryview')), b'memoryview') + self.assertRaises(TypeError, getargs_y_star, None) + + def test_y_hash(self): + from _testcapi import getargs_y_hash + self.assertRaises(TypeError, getargs_y_hash, 'abc\xe9') + self.assertEqual(getargs_y_hash(b'bytes'), b'bytes') + self.assertEqual(getargs_y_hash(b'nul:\0'), b'nul:\0') + self.assertRaises(TypeError, getargs_y_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_y_hash, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_y_hash, None) + + +class Unicode_TestCase(unittest.TestCase): + def test_u(self): + from _testcapi import getargs_u + self.assertEqual(getargs_u('abc\xe9'), 'abc\xe9') + self.assertRaises(TypeError, getargs_u, 'nul:\0') + self.assertRaises(TypeError, getargs_u, b'bytes') + self.assertRaises(TypeError, getargs_u, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_u, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_u, None) + + def test_u_hash(self): + from _testcapi import getargs_u_hash + self.assertEqual(getargs_u_hash('abc\xe9'), 'abc\xe9') + self.assertEqual(getargs_u_hash('nul:\0'), 'nul:\0') + self.assertRaises(TypeError, getargs_u_hash, b'bytes') + self.assertRaises(TypeError, getargs_u_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_u_hash, memoryview(b'memoryview')) + self.assertRaises(TypeError, getargs_u_hash, None) + + def test_Z(self): + from _testcapi import getargs_Z + self.assertEqual(getargs_Z('abc\xe9'), 'abc\xe9') + self.assertRaises(TypeError, getargs_Z, 'nul:\0') + self.assertRaises(TypeError, getargs_Z, b'bytes') + self.assertRaises(TypeError, getargs_Z, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_Z, memoryview(b'memoryview')) + self.assertIsNone(getargs_Z(None)) + + def test_Z_hash(self): + from _testcapi import getargs_Z_hash + self.assertEqual(getargs_Z_hash('abc\xe9'), 'abc\xe9') + self.assertEqual(getargs_Z_hash('nul:\0'), 'nul:\0') + self.assertRaises(TypeError, getargs_Z_hash, b'bytes') + self.assertRaises(TypeError, getargs_Z_hash, bytearray(b'bytearray')) + self.assertRaises(TypeError, getargs_Z_hash, memoryview(b'memoryview')) + self.assertIsNone(getargs_Z_hash(None)) + + def test_main(): - tests = [Signed_TestCase, Unsigned_TestCase, Tuple_TestCase, Keywords_TestCase] + tests = [ + Signed_TestCase, + Unsigned_TestCase, + Tuple_TestCase, + Keywords_TestCase, + Bytes_TestCase, + Unicode_TestCase, + ] try: from _testcapi import getargs_L, getargs_K except ImportError: Modified: python/branches/py3k-jit/Lib/test/test_htmlparser.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_htmlparser.py (original) +++ python/branches/py3k-jit/Lib/test/test_htmlparser.py Wed Jun 16 18:21:24 2010 @@ -136,6 +136,13 @@ ("data", "\n"), ]) + def test_malformatted_charref(self): + self._run_check("

&#bad;

", [ + ("starttag", "p", []), + ("data", "&#bad;"), + ("endtag", "p"), + ]) + def test_unclosed_entityref(self): self._run_check("&entityref foo", [ ("entityref", "entityref"), Modified: python/branches/py3k-jit/Lib/test/test_httplib.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_httplib.py (original) +++ python/branches/py3k-jit/Lib/test/test_httplib.py Wed Jun 16 18:21:24 2010 @@ -239,7 +239,7 @@ self.assertEquals(resp.read(), b'') self.assertEquals(resp.status, 200) self.assertEquals(resp.reason, 'OK') - resp.close() + self.assertTrue(resp.isclosed()) def test_negative_content_length(self): sock = FakeSocket( Modified: python/branches/py3k-jit/Lib/test/test_long.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_long.py (original) +++ python/branches/py3k-jit/Lib/test/test_long.py Wed Jun 16 18:21:24 2010 @@ -330,6 +330,31 @@ # ... but it's just a normal digit if base >= 22 self.assertEqual(int('1L', 22), 43) + # tests with base 0 + self.assertEqual(int('000', 0), 0) + self.assertEqual(int('0o123', 0), 83) + self.assertEqual(int('0x123', 0), 291) + self.assertEqual(int('0b100', 0), 4) + self.assertEqual(int(' 0O123 ', 0), 83) + self.assertEqual(int(' 0X123 ', 0), 291) + self.assertEqual(int(' 0B100 ', 0), 4) + self.assertEqual(int('0', 0), 0) + self.assertEqual(int('+0', 0), 0) + self.assertEqual(int('-0', 0), 0) + self.assertEqual(int('00', 0), 0) + self.assertRaises(ValueError, int, '08', 0) + self.assertRaises(ValueError, int, '-012395', 0) + + # invalid bases + invalid_bases = [-909, + 2**31-1, 2**31, -2**31, -2**31-1, + 2**63-1, 2**63, -2**63, -2**63-1, + 2**100, -2**100, + ] + for base in invalid_bases: + self.assertRaises(ValueError, int, '42', base) + + def test_conversion(self): class JustLong: Modified: python/branches/py3k-jit/Lib/test/test_math.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_math.py (original) +++ python/branches/py3k-jit/Lib/test/test_math.py Wed Jun 16 18:21:24 2010 @@ -1042,6 +1042,15 @@ accuracy_failure = acc_check(expected, got, rel_err = 5e-15, abs_err = 5e-15) + elif fn == 'erfc': + # erfc has less-than-ideal accuracy for large + # arguments (x ~ 25 or so), mainly due to the + # error involved in computing exp(-x*x). + # + # XXX Would be better to weaken this test only + # for large x, instead of for all x. + accuracy_failure = ulps_check(expected, got, 2000) + else: accuracy_failure = ulps_check(expected, got, 20) if accuracy_failure is None: Modified: python/branches/py3k-jit/Lib/test/test_minidom.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_minidom.py (original) +++ python/branches/py3k-jit/Lib/test/test_minidom.py Wed Jun 16 18:21:24 2010 @@ -228,7 +228,14 @@ def testUnlink(self): dom = parse(tstfile) + self.assertTrue(dom.childNodes) dom.unlink() + self.assertFalse(dom.childNodes) + + def testContext(self): + with parse(tstfile) as dom: + self.assertTrue(dom.childNodes) + self.assertFalse(dom.childNodes) def testElement(self): dom = Document() Modified: python/branches/py3k-jit/Lib/test/test_numeric_tower.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_numeric_tower.py (original) +++ python/branches/py3k-jit/Lib/test/test_numeric_tower.py Wed Jun 16 18:21:24 2010 @@ -143,9 +143,64 @@ x = {'halibut', HalibutProxy()} self.assertEqual(len(x), 1) +class ComparisonTest(unittest.TestCase): + def test_mixed_comparisons(self): + + # ordered list of distinct test values of various types: + # int, float, Fraction, Decimal + test_values = [ + float('-inf'), + D('-1e999999999'), + -1e308, + F(-22, 7), + -3.14, + -2, + 0.0, + 1e-320, + True, + F('1.2'), + D('1.3'), + float('1.4'), + F(275807, 195025), + D('1.414213562373095048801688724'), + F(114243, 80782), + F(473596569, 84615), + 7e200, + D('infinity'), + ] + for i, first in enumerate(test_values): + for second in test_values[i+1:]: + self.assertLess(first, second) + self.assertLessEqual(first, second) + self.assertGreater(second, first) + self.assertGreaterEqual(second, first) + + def test_complex(self): + # comparisons with complex are special: equality and inequality + # comparisons should always succeed, but order comparisons should + # raise TypeError. + z = 1.0 + 0j + w = -3.14 + 2.7j + + for v in 1, 1.0, F(1), D(1), complex(1): + self.assertEqual(z, v) + self.assertEqual(v, z) + + for v in 2, 2.0, F(2), D(2), complex(2): + self.assertNotEqual(z, v) + self.assertNotEqual(v, z) + self.assertNotEqual(w, v) + self.assertNotEqual(v, w) + + for v in (1, 1.0, F(1), D(1), complex(1), + 2, 2.0, F(2), D(2), complex(2), w): + for op in operator.le, operator.lt, operator.ge, operator.gt: + self.assertRaises(TypeError, op, z, v) + self.assertRaises(TypeError, op, v, z) + def test_main(): - run_unittest(HashTest) + run_unittest(HashTest, ComparisonTest) if __name__ == '__main__': test_main() Modified: python/branches/py3k-jit/Lib/test/test_os.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_os.py (original) +++ python/branches/py3k-jit/Lib/test/test_os.py Wed Jun 16 18:21:24 2010 @@ -933,20 +933,64 @@ @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") class Win32KillTests(unittest.TestCase): - def _kill(self, sig, *args): - # Send a subprocess a signal (or in some cases, just an int to be - # the return value) - proc = subprocess.Popen(*args) + def _kill(self, sig): + # Start sys.executable as a subprocess and communicate from the + # subprocess to the parent that the interpreter is ready. When it + # becomes ready, send *sig* via os.kill to the subprocess and check + # that the return code is equal to *sig*. + import ctypes + from ctypes import wintypes + import msvcrt + + # Since we can't access the contents of the process' stdout until the + # process has exited, use PeekNamedPipe to see what's inside stdout + # without waiting. This is done so we can tell that the interpreter + # is started and running at a point where it could handle a signal. + PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe + PeekNamedPipe.restype = wintypes.BOOL + PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle + ctypes.POINTER(ctypes.c_char), # stdout buf + wintypes.DWORD, # Buffer size + ctypes.POINTER(wintypes.DWORD), # bytes read + ctypes.POINTER(wintypes.DWORD), # bytes avail + ctypes.POINTER(wintypes.DWORD)) # bytes left + msg = "running" + proc = subprocess.Popen([sys.executable, "-c", + "import sys;" + "sys.stdout.write('{}');" + "sys.stdout.flush();" + "input()".format(msg)], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE) + + count, max = 0, 100 + while count < max and proc.poll() is None: + # Create a string buffer to store the result of stdout from the pipe + buf = ctypes.create_string_buffer(len(msg)) + # Obtain the text currently in proc.stdout + # Bytes read/avail/left are left as NULL and unused + rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()), + buf, ctypes.sizeof(buf), None, None, None) + self.assertNotEqual(rslt, 0, "PeekNamedPipe failed") + if buf.value: + self.assertEqual(msg, buf.value.decode()) + break + time.sleep(0.1) + count += 1 + else: + self.fail("Did not receive communication from the subprocess") + os.kill(proc.pid, sig) self.assertEqual(proc.wait(), sig) def test_kill_sigterm(self): # SIGTERM doesn't mean anything special, but make sure it works - self._kill(signal.SIGTERM, [sys.executable]) + self._kill(signal.SIGTERM) def test_kill_int(self): # os.kill on Windows can take an int which gets set as the exit code - self._kill(100, [sys.executable]) + self._kill(100) def _kill_with_event(self, event, name): # Run a script which has console control handling enabled. Modified: python/branches/py3k-jit/Lib/test/test_socketserver.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_socketserver.py (original) +++ python/branches/py3k-jit/Lib/test/test_socketserver.py Wed Jun 16 18:21:24 2010 @@ -61,6 +61,7 @@ testcase.assertEquals(72 << 8, status) + at unittest.skipUnless(threading, 'Threading required for this test.') class SocketServerTest(unittest.TestCase): """Test all socket servers.""" Modified: python/branches/py3k-jit/Lib/test/test_ssl.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_ssl.py (original) +++ python/branches/py3k-jit/Lib/test/test_ssl.py Wed Jun 16 18:21:24 2010 @@ -33,16 +33,15 @@ HOST = support.HOST data_file = lambda name: os.path.join(os.path.dirname(__file__), name) -fsencode = lambda name: name.encode(sys.getfilesystemencoding(), "surrogateescape") CERTFILE = data_file("keycert.pem") -BYTES_CERTFILE = fsencode(CERTFILE) +BYTES_CERTFILE = os.fsencode(CERTFILE) ONLYCERT = data_file("ssl_cert.pem") ONLYKEY = data_file("ssl_key.pem") -BYTES_ONLYCERT = fsencode(ONLYCERT) -BYTES_ONLYKEY = fsencode(ONLYKEY) +BYTES_ONLYCERT = os.fsencode(ONLYCERT) +BYTES_ONLYKEY = os.fsencode(ONLYKEY) CAPATH = data_file("capath") -BYTES_CAPATH = fsencode(CAPATH) +BYTES_CAPATH = os.fsencode(CAPATH) SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem") Modified: python/branches/py3k-jit/Lib/test/test_struct.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_struct.py (original) +++ python/branches/py3k-jit/Lib/test/test_struct.py Wed Jun 16 18:21:24 2010 @@ -443,7 +443,7 @@ # Test bogus offset (issue 3694) sb = small_buf - self.assertRaises(TypeError, struct.pack_into, b'1', sb, None) + self.assertRaises(TypeError, struct.pack_into, b'', sb, None) def test_pack_into_fn(self): test_string = b'Reykjavik rocks, eow!' @@ -506,10 +506,43 @@ for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']: self.assertTrue(struct.unpack('>?', c)[0]) + def test_count_overflow(self): + hugecount = '{}b'.format(sys.maxsize+1) + self.assertRaises(struct.error, struct.calcsize, hugecount) + + hugecount2 = '{}b{}H'.format(sys.maxsize//2, sys.maxsize//2) + self.assertRaises(struct.error, struct.calcsize, hugecount2) + if IS32BIT: def test_crasher(self): self.assertRaises(MemoryError, struct.pack, "357913941b", "a") + def test_trailing_counter(self): + store = array.array('b', b' '*100) + + # format lists containing only count spec should result in an error + self.assertRaises(struct.error, struct.pack, '12345') + self.assertRaises(struct.error, struct.unpack, '12345', '') + self.assertRaises(struct.error, struct.pack_into, '12345', store, 0) + self.assertRaises(struct.error, struct.unpack_from, '12345', store, 0) + + # Format lists with trailing count spec should result in an error + self.assertRaises(struct.error, struct.pack, 'c12345', 'x') + self.assertRaises(struct.error, struct.unpack, 'c12345', 'x') + self.assertRaises(struct.error, struct.pack_into, 'c12345', store, 0, + 'x') + self.assertRaises(struct.error, struct.unpack_from, 'c12345', store, + 0) + + # Mixed format tests + self.assertRaises(struct.error, struct.pack, '14s42', 'spam and eggs') + self.assertRaises(struct.error, struct.unpack, '14s42', + 'spam and eggs') + self.assertRaises(struct.error, struct.pack_into, '14s42', store, 0, + 'spam and eggs') + self.assertRaises(struct.error, struct.unpack_from, '14s42', store, 0) + + def test_main(): run_unittest(StructTest) Modified: python/branches/py3k-jit/Lib/test/test_sundry.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_sundry.py (original) +++ python/branches/py3k-jit/Lib/test/test_sundry.py Wed Jun 16 18:21:24 2010 @@ -60,7 +60,6 @@ import rlcompleter import sched import sndhdr - import sunau import symbol import tabnanny import timeit Modified: python/branches/py3k-jit/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_sys.py (original) +++ python/branches/py3k-jit/Lib/test/test_sys.py Wed Jun 16 18:21:24 2010 @@ -867,6 +867,35 @@ # sys.flags check(sys.flags, size(vh) + self.P * len(sys.flags)) + def test_getfilesystemencoding(self): + import codecs + + def check_fsencoding(fs_encoding): + self.assertIsNotNone(fs_encoding) + if sys.platform == 'darwin': + self.assertEqual(fs_encoding, 'utf-8') + codecs.lookup(fs_encoding) + + fs_encoding = sys.getfilesystemencoding() + check_fsencoding(fs_encoding) + + # Even in C locale + try: + sys.executable.encode('ascii') + except UnicodeEncodeError: + # Python doesn't start with ASCII locale if its path is not ASCII, + # see issue #8611 + pass + else: + env = os.environ.copy() + env['LANG'] = 'C' + output = subprocess.check_output( + [sys.executable, "-c", + "import sys; print(sys.getfilesystemencoding())"], + env=env) + fs_encoding = output.rstrip().decode('ascii') + check_fsencoding(fs_encoding) + def test_setfilesystemencoding(self): old = sys.getfilesystemencoding() try: Modified: python/branches/py3k-jit/Lib/test/test_sysconfig.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_sysconfig.py (original) +++ python/branches/py3k-jit/Lib/test/test_sysconfig.py Wed Jun 16 18:21:24 2010 @@ -11,13 +11,14 @@ import shutil from copy import copy, deepcopy -from test.support import run_unittest, TESTFN, unlink, get_attribute +from test.support import (run_unittest, TESTFN, unlink, get_attribute, + captured_stdout) import sysconfig from sysconfig import (get_paths, get_platform, get_config_vars, get_path, get_path_names, _INSTALL_SCHEMES, _get_default_scheme, _expand_vars, - get_scheme_names, get_config_var) + get_scheme_names, get_config_var, _main) class TestSysConfig(unittest.TestCase): @@ -264,6 +265,13 @@ user_path = get_path(name, 'posix_user') self.assertEquals(user_path, global_path.replace(base, user)) + def test_main(self): + # just making sure _main() runs and returns things in the stdout + with captured_stdout() as output: + _main() + self.assertTrue(len(output.getvalue().split('\n')) > 0) + + def test_main(): run_unittest(TestSysConfig) Modified: python/branches/py3k-jit/Lib/test/test_tarfile.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_tarfile.py (original) +++ python/branches/py3k-jit/Lib/test/test_tarfile.py Wed Jun 16 18:21:24 2010 @@ -133,6 +133,26 @@ "read() after readline() failed") fobj.close() + # Test if symbolic and hard links are resolved by extractfile(). The + # test link members each point to a regular member whose data is + # supposed to be exported. + def _test_fileobj_link(self, lnktype, regtype): + a = self.tar.extractfile(lnktype) + b = self.tar.extractfile(regtype) + self.assertEqual(a.name, b.name) + + def test_fileobj_link1(self): + self._test_fileobj_link("ustar/lnktype", "ustar/regtype") + + def test_fileobj_link2(self): + self._test_fileobj_link("./ustar/linktest2/lnktype", "ustar/linktest1/regtype") + + def test_fileobj_symlink1(self): + self._test_fileobj_link("ustar/symtype", "ustar/regtype") + + def test_fileobj_symlink2(self): + self._test_fileobj_link("./ustar/linktest2/symtype", "ustar/linktest1/regtype") + class CommonReadTest(ReadTest): @@ -661,10 +681,14 @@ if hasattr(os, "link"): link = os.path.join(TEMPDIR, "link") target = os.path.join(TEMPDIR, "link_target") - open(target, "wb").close() + fobj = open(target, "wb") + fobj.write(b"aaa") + fobj.close() os.link(target, link) try: tar = tarfile.open(tmpname, self.mode) + # Record the link target in the inodes list. + tar.gettarinfo(target) tarinfo = tar.gettarinfo(link) self.assertEqual(tarinfo.size, 0) finally: @@ -1374,6 +1398,29 @@ fobj.close() +class LinkEmulationTest(ReadTest): + + # Test for issue #8741 regression. On platforms that do not support + # symbolic or hard links tarfile tries to extract these types of members as + # the regular files they point to. + def _test_link_extraction(self, name): + self.tar.extract(name, TEMPDIR) + data = open(os.path.join(TEMPDIR, name), "rb").read() + self.assertEqual(md5sum(data), md5_regtype) + + def test_hardlink_extraction1(self): + self._test_link_extraction("ustar/lnktype") + + def test_hardlink_extraction2(self): + self._test_link_extraction("./ustar/linktest2/lnktype") + + def test_symlink_extraction1(self): + self._test_link_extraction("ustar/symtype") + + def test_symlink_extraction2(self): + self._test_link_extraction("./ustar/linktest2/symtype") + + class GzipMiscReadTest(MiscReadTest): tarname = gzipname mode = "r:gz" @@ -1459,6 +1506,8 @@ if hasattr(os, "link"): tests.append(HardlinkTest) + else: + tests.append(LinkEmulationTest) fobj = open(tarname, "rb") data = fobj.read() Modified: python/branches/py3k-jit/Lib/test/test_tcl.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_tcl.py (original) +++ python/branches/py3k-jit/Lib/test/test_tcl.py Wed Jun 16 18:21:24 2010 @@ -127,6 +127,31 @@ tcl = self.interp self.assertRaises(TclError,tcl.eval,'package require DNE') + def testLoadWithUNC(self): + import sys + if sys.platform != 'win32': + return + + # Build a UNC path from the regular path. + # Something like + # \\%COMPUTERNAME%\c$\python27\python.exe + + fullname = os.path.abspath(sys.executable) + if fullname[1] != ':': + return + unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'], + fullname[0], + fullname[3:]) + + with test_support.EnvironmentVarGuard() as env: + env.unset("TCL_LIBRARY") + f = os.popen('%s -c "import Tkinter; print Tkinter"' % (unc_name,)) + + self.assert_('Tkinter.py' in f.read()) + # exit code must be zero + self.assertEqual(f.close(), None) + + def test_main(): support.run_unittest(TclTest, TkinterTest) Modified: python/branches/py3k-jit/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_unicode.py (original) +++ python/branches/py3k-jit/Lib/test/test_unicode.py Wed Jun 16 18:21:24 2010 @@ -681,6 +681,9 @@ self.assertRaises(IndexError, "{:}".format) self.assertRaises(IndexError, "{:s}".format) self.assertRaises(IndexError, "{}".format) + big = "23098475029384702983476098230754973209482573" + self.assertRaises(ValueError, ("{" + big + "}").format) + self.assertRaises(ValueError, ("{[" + big + "]}").format, [0]) # issue 6089 self.assertRaises(ValueError, "{0[0]x}".format, [None]) Modified: python/branches/py3k-jit/Lib/test/test_urllib2.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_urllib2.py (original) +++ python/branches/py3k-jit/Lib/test/test_urllib2.py Wed Jun 16 18:21:24 2010 @@ -1151,7 +1151,6 @@ self.assertEqual(len(http_handler.requests), 1) self.assertFalse(http_handler.requests[0].has_header(auth_header)) - class MiscTests(unittest.TestCase): def test_build_opener(self): Modified: python/branches/py3k-jit/Lib/test/test_winreg.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_winreg.py (original) +++ python/branches/py3k-jit/Lib/test/test_winreg.py Wed Jun 16 18:21:24 2010 @@ -5,6 +5,7 @@ import os, sys import unittest from test import support +threading = support.import_module("threading") from platform import machine # Do this first so test will be skipped if module doesn't exist @@ -227,6 +228,58 @@ except WindowsError: self.assertEqual(h.handle, 0) + def test_changing_value(self): + # Issue2810: A race condition in 2.6 and 3.1 may cause + # EnumValue or QueryValue to throw "WindowsError: More data is + # available" + done = False + + class VeryActiveThread(threading.Thread): + def run(self): + with CreateKey(HKEY_CURRENT_USER, test_key_name) as key: + use_short = True + long_string = 'x'*2000 + while not done: + s = 'x' if use_short else long_string + use_short = not use_short + SetValue(key, 'changing_value', REG_SZ, s) + + thread = VeryActiveThread() + thread.start() + try: + with CreateKey(HKEY_CURRENT_USER, + test_key_name+'\\changing_value') as key: + for _ in range(1000): + num_subkeys, num_values, t = QueryInfoKey(key) + for i in range(num_values): + name = EnumValue(key, i) + QueryValue(key, name[0]) + finally: + done = True + thread.join() + DeleteKey(HKEY_CURRENT_USER, test_key_name+'\\changing_value') + DeleteKey(HKEY_CURRENT_USER, test_key_name) + + def test_long_key(self): + # Issue2810, in 2.6 and 3.1 when the key name was exactly 256 + # characters, EnumKey threw "WindowsError: More data is + # available" + name = 'x'*256 + try: + with CreateKey(HKEY_CURRENT_USER, test_key_name) as key: + SetValue(key, name, REG_SZ, 'x') + num_subkeys, num_values, t = QueryInfoKey(key) + EnumKey(key, 0) + finally: + DeleteKey(HKEY_CURRENT_USER, '\\'.join((test_key_name, name))) + DeleteKey(HKEY_CURRENT_USER, test_key_name) + + def test_dynamic_key(self): + # Issue2810, when the value is dynamically generated, these + # throw "WindowsError: More data is available" in 2.6 and 3.1 + EnumValue(HKEY_PERFORMANCE_DATA, 0) + QueryValueEx(HKEY_PERFORMANCE_DATA, "") + # Reflection requires XP x64/Vista at a minimum. XP doesn't have this stuff # or DeleteKeyEx so make sure their use raises NotImplementedError @unittest.skipUnless(WIN_VER < (5, 2), "Requires Windows XP") Modified: python/branches/py3k-jit/Lib/test/test_winsound.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_winsound.py (original) +++ python/branches/py3k-jit/Lib/test/test_winsound.py Wed Jun 16 18:21:24 2010 @@ -6,6 +6,7 @@ import time import os import subprocess +import ctypes winsound = support.import_module('winsound') import winreg @@ -13,6 +14,11 @@ def has_sound(sound): """Find out if a particular event is configured with a default sound""" try: + # Ask the mixer API for the number of devices it knows about. + # When there are no devices, PlaySound will fail. + if ctypes.windll.winmm.mixerGetNumDevs() is 0: + return False + key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, "AppEvents\Schemes\Apps\.Default\{0}\.Default".format(sound)) value = winreg.EnumValue(key, 0)[1] Modified: python/branches/py3k-jit/Lib/test/testtar.tar ============================================================================== Binary files. No diff available. Modified: python/branches/py3k-jit/Lib/tkinter/_fix.py ============================================================================== --- python/branches/py3k-jit/Lib/tkinter/_fix.py (original) +++ python/branches/py3k-jit/Lib/tkinter/_fix.py Wed Jun 16 18:21:24 2010 @@ -42,6 +42,8 @@ # Ignore leading \\?\ if s.startswith("\\\\?\\"): s = s[4:] + if s.startswith("UNC"): + s = "\\" + s[3:] return s prefix = os.path.join(sys.prefix,"tcl") Modified: python/branches/py3k-jit/Lib/unittest/case.py ============================================================================== --- python/branches/py3k-jit/Lib/unittest/case.py (original) +++ python/branches/py3k-jit/Lib/unittest/case.py Wed Jun 16 18:21:24 2010 @@ -14,6 +14,9 @@ __unittest = True +DIFF_OMITTED = ('\nDiff is %s characters long. ' + 'Set self.maxDiff to None to see it.') + class SkipTest(Exception): """ Raise this exception in a test to skip it. @@ -169,6 +172,12 @@ longMessage = False + # This attribute sets the maximum length of a diff in failure messages + # by assert methods using difflib. It is looked up as an instance attribute + # so can be configured by individual tests if required. + + maxDiff = 80*8 + # Attribute used by TestSuite for classSetUp _classSetupFailed = False @@ -380,6 +389,9 @@ self.setUp() getattr(self, self._testMethodName)() self.tearDown() + while self._cleanups: + function, args, kwargs = self._cleanups.pop(-1) + function(*args, **kwargs) def skipTest(self, reason): """Skip this test.""" @@ -694,12 +706,21 @@ except (TypeError, IndexError, NotImplementedError): differing += ('Unable to index element %d ' 'of second %s\n' % (len1, seq_type_name)) - standardMsg = differing + '\n' + '\n'.join( + standardMsg = differing + diffMsg = '\n' + '\n'.join( difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) + + standardMsg = self._truncateMessage(standardMsg, diffMsg) msg = self._formatMessage(msg, standardMsg) self.fail(msg) + def _truncateMessage(self, message, diff): + max_diff = self.maxDiff + if max_diff is None or len(diff) <= max_diff: + return message + diff + return message + (DIFF_OMITTED % len(diff)) + def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. @@ -798,9 +819,11 @@ self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') if d1 != d2: - standardMsg = ('\n' + '\n'.join(difflib.ndiff( + standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) + diff = ('\n' + '\n'.join(difflib.ndiff( pprint.pformat(d1).splitlines(), pprint.pformat(d2).splitlines()))) + standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertDictContainsSubset(self, expected, actual, msg=None): @@ -917,8 +940,10 @@ 'Second argument is not a string')) if first != second: - standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), + standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True)) + diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) + standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertLess(self, a, b, msg=None): Modified: python/branches/py3k-jit/Lib/unittest/loader.py ============================================================================== --- python/branches/py3k-jit/Lib/unittest/loader.py (original) +++ python/branches/py3k-jit/Lib/unittest/loader.py Wed Jun 16 18:21:24 2010 @@ -235,6 +235,10 @@ __import__(name) return sys.modules[name] + def _match_path(self, path, full_path, pattern): + # override this method to use alternative matching strategy + return fnmatch(path, pattern) + def _find_tests(self, start_dir, pattern): """Used by discovery. Yields test suites it loads.""" paths = os.listdir(start_dir) @@ -245,26 +249,26 @@ if not VALID_MODULE_NAME.match(path): # valid Python identifiers only continue - - if fnmatch(path, pattern): - # if the test file matches, load it - name = self._get_name_from_path(full_path) - try: - module = self._get_module_from_name(name) - except: - yield _make_failed_import_test(name, self.suiteClass) - else: - mod_file = os.path.abspath(getattr(module, '__file__', full_path)) - realpath = os.path.splitext(mod_file)[0] - fullpath_noext = os.path.splitext(full_path)[0] - if realpath.lower() != fullpath_noext.lower(): - module_dir = os.path.dirname(realpath) - mod_name = os.path.splitext(os.path.basename(full_path))[0] - expected_dir = os.path.dirname(full_path) - msg = ("%r module incorrectly imported from %r. Expected %r. " - "Is this module globally installed?") - raise ImportError(msg % (mod_name, module_dir, expected_dir)) - yield self.loadTestsFromModule(module) + if not self._match_path(path, full_path, pattern): + continue + # if the test file matches, load it + name = self._get_name_from_path(full_path) + try: + module = self._get_module_from_name(name) + except: + yield _make_failed_import_test(name, self.suiteClass) + else: + mod_file = os.path.abspath(getattr(module, '__file__', full_path)) + realpath = os.path.splitext(mod_file)[0] + fullpath_noext = os.path.splitext(full_path)[0] + if realpath.lower() != fullpath_noext.lower(): + module_dir = os.path.dirname(realpath) + mod_name = os.path.splitext(os.path.basename(full_path))[0] + expected_dir = os.path.dirname(full_path) + msg = ("%r module incorrectly imported from %r. Expected %r. " + "Is this module globally installed?") + raise ImportError(msg % (mod_name, module_dir, expected_dir)) + yield self.loadTestsFromModule(module) elif os.path.isdir(full_path): if not os.path.isfile(os.path.join(full_path, '__init__.py')): continue Modified: python/branches/py3k-jit/Lib/unittest/suite.py ============================================================================== --- python/branches/py3k-jit/Lib/unittest/suite.py (original) +++ python/branches/py3k-jit/Lib/unittest/suite.py Wed Jun 16 18:21:24 2010 @@ -84,9 +84,16 @@ self._handleModuleTearDown(result) return result + def debug(self): + """Run the tests without collecting errors in a TestResult""" + debug = _DebugResult() + self._wrapped_run(debug, True) + self._tearDownPreviousClass(None, debug) + self._handleModuleTearDown(debug) + ################################ # private methods - def _wrapped_run(self, result): + def _wrapped_run(self, result, debug=False): for test in self: if result.shouldStop: break @@ -102,9 +109,11 @@ continue if hasattr(test, '_wrapped_run'): - test._wrapped_run(result) - else: + test._wrapped_run(result, debug) + elif not debug: test(result) + else: + test.debug() def _handleClassSetUp(self, test, result): previousClass = getattr(result, '_previousTestClass', None) @@ -127,9 +136,13 @@ if setUpClass is not None: try: setUpClass() - except: + except Exception as e: + if isinstance(result, _DebugResult): + raise currentClass._classSetupFailed = True - self._addClassSetUpError(result, currentClass) + className = util.strclass(currentClass) + errorName = 'setUpClass (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) def _get_previous_module(self, result): previousModule = None @@ -157,10 +170,20 @@ if setUpModule is not None: try: setUpModule() - except: + except Exception as e: + if isinstance(result, _DebugResult): + raise result._moduleSetUpFailed = True - error = _ErrorHolder('setUpModule (%s)' % currentModule) - result.addError(error, sys.exc_info()) + errorName = 'setUpModule (%s)' % currentModule + self._addClassOrModuleLevelException(result, e, errorName) + + def _addClassOrModuleLevelException(self, result, exception, errorName): + error = _ErrorHolder(errorName) + addSkip = getattr(result, 'addSkip', None) + if addSkip is not None and isinstance(exception, case.SkipTest): + addSkip(error, str(exception)) + else: + result.addError(error, sys.exc_info()) def _handleModuleTearDown(self, result): previousModule = self._get_previous_module(result) @@ -178,9 +201,11 @@ if tearDownModule is not None: try: tearDownModule() - except: - error = _ErrorHolder('tearDownModule (%s)' % previousModule) - result.addError(error, sys.exc_info()) + except Exception as e: + if isinstance(result, _DebugResult): + raise + errorName = 'tearDownModule (%s)' % previousModule + self._addClassOrModuleLevelException(result, e, errorName) def _tearDownPreviousClass(self, test, result): previousClass = getattr(result, '_previousTestClass', None) @@ -198,18 +223,13 @@ if tearDownClass is not None: try: tearDownClass() - except: - self._addClassTearDownError(result) + except Exception as e: + if isinstance(result, _DebugResult): + raise + className = util.strclass(previousClass) + errorName = 'tearDownClass (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) - def _addClassTearDownError(self, result): - className = util.strclass(result._previousTestClass) - error = _ErrorHolder('classTearDown (%s)' % className) - result.addError(error, sys.exc_info()) - - def _addClassSetUpError(self, result, klass): - className = util.strclass(klass) - error = _ErrorHolder('classSetUp (%s)' % className) - result.addError(error, sys.exc_info()) class _ErrorHolder(object): @@ -257,3 +277,10 @@ except TypeError: return True return False + + +class _DebugResult(object): + "Used by the TestSuite to hold previous class when running in debug." + _previousTestClass = None + _moduleSetUpFailed = False + shouldStop = False Modified: python/branches/py3k-jit/Lib/unittest/test/test_case.py ============================================================================== --- python/branches/py3k-jit/Lib/unittest/test/test_case.py (original) +++ python/branches/py3k-jit/Lib/unittest/test/test_case.py Wed Jun 16 18:21:24 2010 @@ -1,3 +1,5 @@ +import difflib +import pprint import re import sys @@ -589,6 +591,84 @@ self.assertRaises(self.failureException, self.assertDictEqual, [], d) self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) + def testAssertSequenceEqualMaxDiff(self): + self.assertEqual(self.maxDiff, 80*8) + seq1 = 'a' + 'x' * 80**2 + seq2 = 'b' + 'x' * 80**2 + diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), + pprint.pformat(seq2).splitlines())) + # the +1 is the leading \n added by assertSequenceEqual + omitted = unittest.case.DIFF_OMITTED % (len(diff) + 1,) + + self.maxDiff = len(diff)//2 + try: + + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: + msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') + self.assertTrue(len(msg) < len(diff)) + self.assertIn(omitted, msg) + + self.maxDiff = len(diff) * 2 + try: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: + msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') + self.assertTrue(len(msg) > len(diff)) + self.assertNotIn(omitted, msg) + + self.maxDiff = None + try: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: + msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') + self.assertTrue(len(msg) > len(diff)) + self.assertNotIn(omitted, msg) + + def testTruncateMessage(self): + self.maxDiff = 1 + message = self._truncateMessage('foo', 'bar') + omitted = unittest.case.DIFF_OMITTED % len('bar') + self.assertEqual(message, 'foo' + omitted) + + self.maxDiff = None + message = self._truncateMessage('foo', 'bar') + self.assertEqual(message, 'foobar') + + self.maxDiff = 4 + message = self._truncateMessage('foo', 'bar') + self.assertEqual(message, 'foobar') + + def testAssertDictEqualTruncates(self): + test = unittest.TestCase('assertEqual') + def truncate(msg, diff): + return 'foo' + test._truncateMessage = truncate + try: + test.assertDictEqual({}, {1: 0}) + except self.failureException as e: + self.assertEqual(str(e), 'foo') + else: + self.fail('assertDictEqual did not fail') + + def testAssertMultiLineEqualTruncates(self): + test = unittest.TestCase('assertEqual') + def truncate(msg, diff): + return 'foo' + test._truncateMessage = truncate + try: + test.assertMultiLineEqual('foo', 'bar') + except self.failureException as e: + self.assertEqual(str(e), 'foo') + else: + self.fail('assertMultiLineEqual did not fail') + def testAssertItemsEqual(self): a = object() self.assertItemsEqual([1, 2, 3], [3, 2, 1]) @@ -739,7 +819,7 @@ A test case is the smallest unit of testing. [...] You may provide your own implementation that does not subclass from TestCase, of course. """ - sample_text_error = """ + sample_text_error = """\ - http://www.python.org/doc/2.3/lib/module-unittest.html ? ^ + http://www.python.org/doc/2.4.1/lib/module-unittest.html @@ -750,13 +830,16 @@ ? +++++++++++++++++++++ + own implementation that does not subclass from TestCase, of course. """ - + self.maxDiff = None try: self.assertMultiLineEqual(sample_text, revised_sample_text) except self.failureException as e: + # need to remove the first line of the error message + error = str(e).split('\n', 1)[1] + # no fair testing ourself with ourself, and assertEqual is used for strings # so can't use assertEqual either. Just use assertTrue. - self.assertTrue(sample_text_error == str(e)) + self.assertTrue(sample_text_error == error) def testAssertIsNone(self): self.assertIsNone(None) Modified: python/branches/py3k-jit/Lib/unittest/test/test_runner.py ============================================================================== --- python/branches/py3k-jit/Lib/unittest/test/test_runner.py (original) +++ python/branches/py3k-jit/Lib/unittest/test/test_runner.py Wed Jun 16 18:21:24 2010 @@ -110,6 +110,31 @@ test.run(result) self.assertEqual(ordering, ['setUp', 'cleanup1']) + def testTestCaseDebugExecutesCleanups(self): + ordering = [] + + class TestableTest(unittest.TestCase): + def setUp(self): + ordering.append('setUp') + self.addCleanup(cleanup1) + + def testNothing(self): + ordering.append('test') + + def tearDown(self): + ordering.append('tearDown') + + test = TestableTest('testNothing') + + def cleanup1(): + ordering.append('cleanup1') + test.addCleanup(cleanup2) + def cleanup2(): + ordering.append('cleanup2') + + test.debug() + self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2']) + class Test_TextTestRunner(unittest.TestCase): """Tests for TextTestRunner.""" Modified: python/branches/py3k-jit/Lib/unittest/test/test_setups.py ============================================================================== --- python/branches/py3k-jit/Lib/unittest/test/test_setups.py (original) +++ python/branches/py3k-jit/Lib/unittest/test/test_setups.py Wed Jun 16 18:21:24 2010 @@ -111,7 +111,7 @@ self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), - 'classSetUp (%s.BrokenTest)' % __name__) + 'setUpClass (%s.BrokenTest)' % __name__) def test_error_in_teardown_class(self): class Test(unittest.TestCase): @@ -144,7 +144,7 @@ error, _ = result.errors[0] self.assertEqual(str(error), - 'classTearDown (%s.Test)' % __name__) + 'tearDownClass (%s.Test)' % __name__) def test_class_not_torndown_when_setup_fails(self): class Test(unittest.TestCase): @@ -398,3 +398,110 @@ self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), 'tearDownModule (Module)') + + def test_skiptest_in_setupclass(self): + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + raise unittest.SkipTest('foo') + def test_one(self): + pass + def test_two(self): + pass + + result = self.runTests(Test) + self.assertEqual(result.testsRun, 0) + self.assertEqual(len(result.errors), 0) + self.assertEqual(len(result.skipped), 1) + skipped = result.skipped[0][0] + self.assertEqual(str(skipped), 'setUpClass (%s.Test)' % __name__) + + def test_skiptest_in_setupmodule(self): + class Test(unittest.TestCase): + def test_one(self): + pass + def test_two(self): + pass + + class Module(object): + @staticmethod + def setUpModule(): + raise unittest.SkipTest('foo') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + result = self.runTests(Test) + self.assertEqual(result.testsRun, 0) + self.assertEqual(len(result.errors), 0) + self.assertEqual(len(result.skipped), 1) + skipped = result.skipped[0][0] + self.assertEqual(str(skipped), 'setUpModule (Module)') + + def test_suite_debug_executes_setups_and_teardowns(self): + ordering = [] + + class Module(object): + @staticmethod + def setUpModule(): + ordering.append('setUpModule') + @staticmethod + def tearDownModule(): + ordering.append('tearDownModule') + + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('setUpClass') + @classmethod + def tearDownClass(cls): + ordering.append('tearDownClass') + def test_something(self): + ordering.append('test_something') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + suite.debug() + expectedOrder = ['setUpModule', 'setUpClass', 'test_something', 'tearDownClass', 'tearDownModule'] + self.assertEqual(ordering, expectedOrder) + + def test_suite_debug_propagates_exceptions(self): + class Module(object): + @staticmethod + def setUpModule(): + if phase == 0: + raise Exception('setUpModule') + @staticmethod + def tearDownModule(): + if phase == 1: + raise Exception('tearDownModule') + + class Test(unittest.TestCase): + @classmethod + def setUpClass(cls): + if phase == 2: + raise Exception('setUpClass') + @classmethod + def tearDownClass(cls): + if phase == 3: + raise Exception('tearDownClass') + def test_something(self): + if phase == 4: + raise Exception('test_something') + + Test.__module__ = 'Module' + sys.modules['Module'] = Module + + _suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test) + suite = unittest.TestSuite() + suite.addTest(_suite) + + messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something') + for phase, msg in enumerate(messages): + with self.assertRaisesRegexp(Exception, msg): + suite.debug() + +if __name__ == '__main__': + unittest.main() Modified: python/branches/py3k-jit/Lib/unittest/util.py ============================================================================== --- python/branches/py3k-jit/Lib/unittest/util.py (original) +++ python/branches/py3k-jit/Lib/unittest/util.py Wed Jun 16 18:21:24 2010 @@ -2,12 +2,16 @@ __unittest = True - -def safe_repr(obj): +_MAX_LENGTH = 80 +def safe_repr(obj, short=False): try: - return repr(obj) + result = repr(obj) except Exception: - return object.__repr__(obj) + result = object.__repr__(obj) + if not short or len(result) < _MAX_LENGTH: + return result + return result[:_MAX_LENGTH] + ' [truncated]...' + def strclass(cls): return "%s.%s" % (cls.__module__, cls.__name__) Modified: python/branches/py3k-jit/Lib/urllib/request.py ============================================================================== --- python/branches/py3k-jit/Lib/urllib/request.py (original) +++ python/branches/py3k-jit/Lib/urllib/request.py Wed Jun 16 18:21:24 2010 @@ -775,12 +775,21 @@ password_mgr = HTTPPasswordMgr() self.passwd = password_mgr self.add_password = self.passwd.add_password + self.retried = 0 def http_error_auth_reqed(self, authreq, host, req, headers): # host may be an authority (without userinfo) or a URL with an # authority # XXX could be multiple headers authreq = headers.get(authreq, None) + + if self.retried > 5: + # retry sending the username:password 5 times before failing. + raise HTTPError(req.get_full_url(), 401, "basic auth failed", + headers, None) + else: + self.retried += 1 + if authreq: mo = AbstractBasicAuthHandler.rx.search(authreq) if mo: Modified: python/branches/py3k-jit/Lib/webbrowser.py ============================================================================== --- python/branches/py3k-jit/Lib/webbrowser.py (original) +++ python/branches/py3k-jit/Lib/webbrowser.py Wed Jun 16 18:21:24 2010 @@ -540,18 +540,6 @@ # Platform support for MacOS # -try: - import ic -except ImportError: - pass -else: - class InternetConfig(BaseBrowser): - def open(self, url, new=0, autoraise=True): - ic.launchurl(url) - return True # Any way to get status? - - register("internet-config", InternetConfig, update_tryorder=-1) - if sys.platform == 'darwin': # Adapted from patch submitted to SourceForge by Steven J. Burr class MacOSX(BaseBrowser): Modified: python/branches/py3k-jit/Lib/xml/dom/minidom.py ============================================================================== --- python/branches/py3k-jit/Lib/xml/dom/minidom.py (original) +++ python/branches/py3k-jit/Lib/xml/dom/minidom.py Wed Jun 16 18:21:24 2010 @@ -268,6 +268,14 @@ self.previousSibling = None self.nextSibling = None + # A Node is its own context manager, to ensure that an unlink() call occurs. + # This is similar to how a file object works. + def __enter__(self): + return self + + def __exit__(self, et, ev, tb): + self.unlink() + defproperty(Node, "firstChild", doc="First child node, or None.") defproperty(Node, "lastChild", doc="Last child node, or None.") defproperty(Node, "localName", doc="Namespace-local name of this node.") Modified: python/branches/py3k-jit/Mac/Tools/pythonw.c ============================================================================== --- python/branches/py3k-jit/Mac/Tools/pythonw.c (original) +++ python/branches/py3k-jit/Mac/Tools/pythonw.c Wed Jun 16 18:21:24 2010 @@ -151,6 +151,14 @@ main(int argc, char **argv) { char* exec_path = get_python_path(); + /* + * Let argv[0] refer to the new interpreter. This is needed to + * get the effect we want on OSX 10.5 or earlier. That is, without + * changing argv[0] the real interpreter won't have access to + * the Window Server. + */ + argv[0] = exec_path; + #ifdef HAVE_SPAWN_H /* We're weak-linking to posix-spawnv to ensure that * an executable build on 10.5 can work on 10.4. Modified: python/branches/py3k-jit/Misc/ACKS ============================================================================== --- python/branches/py3k-jit/Misc/ACKS (original) +++ python/branches/py3k-jit/Misc/ACKS Wed Jun 16 18:21:24 2010 @@ -21,11 +21,13 @@ Kevin Altis Joe Amenta Mark Anacker +Shashwat Anand Anders Andersen John Anderson Erik Anders?n Oliver Andrich Ross Andrus +?ric Araujo Jason Asbahr David Ascher Chris AtLee @@ -84,6 +86,7 @@ Paul Boddie Matthew Boedicker David Bolen +Forest Bond Gawain Bolton Gregory Bond Jurjen Bos @@ -153,6 +156,7 @@ Jeffery Collins Robert Collins Paul Colomiets +Geremy Condra Juan Jos? Conti Matt Conway David M. Cooke @@ -188,6 +192,7 @@ Erik Demaine Roger Dev Raghuram Devarakonda +Caleb Deveraux Toby Dickenson Mark Dickinson Jack Diederich @@ -366,6 +371,7 @@ Eric Huss Jeremy Hylton Gerhard H?ring +Fredrik H??rd Mihai Ibanescu Lars Immisch Meador Inge @@ -390,6 +396,7 @@ Fredrik Johansson Gregory K. Johnson Simon Johnston +Thomas Jollans Evan Jones Jeremy Jones Richard Jones @@ -403,6 +410,7 @@ Kurt B. Kaiser Tamito Kajiyama Peter van Kampen +Rafe Kaplan Jacob Kaplan-Moss Lou Kates Hiroaki Kawai @@ -429,6 +437,7 @@ Damon Kohler Joseph Koshy Maksim Kozyarchuk +Stefan Krah Bob Kras Holger Krekel Michael Kremer @@ -520,6 +529,7 @@ Lambert Meertens Bill van Melle Lucas Prado Melo +Ezio Melotti Brian Merrell Luke Mewburn Mike Meyer @@ -640,6 +650,7 @@ John Redford Terry Reedy Steve Reeves +Lennart Regebro Ofir Reichenberg Sean Reifschneider Michael P. Reilly Modified: python/branches/py3k-jit/Misc/NEWS ============================================================================== --- python/branches/py3k-jit/Misc/NEWS (original) +++ python/branches/py3k-jit/Misc/NEWS Wed Jun 16 18:21:24 2010 @@ -31,6 +31,46 @@ Core and Builtins ----------------- +- Issue #8592: PyArg_Parse*() functions raise a TypeError for "y", "u" and "Z" + formats if the string contains a null byte/character. Write unit tests for + string formats. + +- Issue #7490: to facilitate sharing of doctests between 2.x and 3.x test + suites, the IGNORE_EXCEPTION_DETAIL directive now also ignores the module + location of the raised exception. + +- Issue #8969: On Windows, use mbcs codec in strict mode to encode and decode + filenames and enable os.fsencode(). + +- Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash + the interpreter with characters outside the Basic Multilingual Plane + (higher than 0x10000). + +- Issue #8950: (See also issue #5080). Py_ArgParse*() functions now + raise TypeError instead of giving a DeprecationWarning when a float + is parsed using the 'L' code (for long long). (All other integer + codes already raise TypeError in this case.) + +- Issue #8922: Normalize the encoding name in PyUnicode_AsEncodedString() to + enable shortcuts for upper case encoding name. Add also a shortcut for + "iso-8859-1" in PyUnicode_AsEncodedString() and PyUnicode_Decode(). + +- Issue #8838: Remove codecs.charbuffer_encode() function. The buffer protocol + doesn't support "char buffer" anymore in Python3. + +- Issue #8339: Remove "t#" format of PyArg_Parse*() functions, use "s#" or "s*" + instead. codecs.charbuffer_encode() now accepts modifiable buffer objects + like bytearray. + +- Issue #8837: Remove "O?" format of PyArg_Parse*() functions. The format is no + used anymore and it was never documented. + +- In the str.format(), raise a ValueError when indexes to arguments are too + large. + +- Issue #2844: Make int('42', n) consistently raise ValueError for + invalid integers n (including n = -909). + - Issue #8188: Introduce a new scheme for computing hashes of numbers (instances of int, float, complex, decimal.Decimal and fractions.Fraction) that makes it easy to maintain the invariant @@ -411,6 +451,61 @@ Library ------- +- Issue #8986: math.erfc was incorrectly raising OverflowError for + values between -27.3 and -30.0 on some platforms. + +- Issue #8784: Set tarfile default encoding to 'utf-8' on Windows. + +- Issue #8966: If a ctypes structure field is an array of c_char, convert its + value to bytes instead of str (as done for c_char and c_char_p). + +- Issue #8188: Comparisons between Decimal and Fraction objects are + now permitted, returning a result based on the exact numerical + values of the operands. This builds on issue #2531, which allowed + Decimal-to-float comparisons; all comparisons involving numeric + types (bool, int, float, complex, Decimal, Fraction) should now + act as expected. + +- Issue #8897: Fix sunau module, use bytes to write the header. Patch written + by Thomas Jollans. + +- Issue #8899: time.struct_time now has class and atribute docstrings. + +- Issue #6470: Drop UNC prefix in FixTk. + +- Issue #4768: base64 encoded email body parts were incorrectly stored as + binary strings. They are now correctly converted to strings. + +- Issue #8833: tarfile created hard link entries with a size field != 0 by + mistake. + +- Charset.body_encode now correctly handles base64 encoding by encoding + with the output_charset before calling base64mime.encode. Passes the + tests from 2.x issue 1368247. + +- Issue #8845: sqlite3 Connection objects now have a read-only in_transaction + attribute that is True iff there are uncommitted changes. + +- Issue #1289118: datetime.timedelta objects can now be multiplied by float + and divided by float and int objects. Results are rounded to the nearest + multiple of timedelta.resolution with ties resolved using round-half-to-even + method. + +- Issue #7150: Raise OverflowError if the result of adding or subtracting + timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range. + +- Issue #8806: add SSL contexts support to ftplib. + +- Issue #4769: Fix main() function of the base64 module, use sys.stdin.buffer + and sys.stdout.buffer (instead of sys.stdin and sys.stdout) to use the bytes + API + +- Issue #8770: now sysconfig displays information when it's called as + a script. Initial idea by Sridhar Ratnakumar. + +- Issue #6662: Fix parsing of malformatted charref (&#bad;), patch written by + Fredrik H??rd + - Issue #8540: Decimal module: rename the Context._clamp attribute to Context.clamp and make it public. This is useful in creating contexts that correspond to the decimal interchange formats @@ -668,7 +763,8 @@ - Issue #2531: Comparison operations between floats and Decimal instances now return a result based on the numeric values of the operands; previously they returned an arbitrary result based on - the relative ordering of id(float) and id(Decimal). + the relative ordering of id(float) and id(Decimal). See also + issue #8188, which adds Decimal-to-Fraction comparisons. - Added a subtract() method to collections.Counter(). @@ -1229,6 +1325,28 @@ Extension Modules ----------------- +- Issue #5094: The ``datetime`` module now has a simple concrete class + implementing ``datetime.tzinfo`` interface. Instances of the new + class, ``datetime.timezone``, return fixed name and UTC offset from + their ``tzname(dt)`` and ``utcoffset(dt)`` methods. The ``dst(dt)`` + method always returns ``None``. A class attribute, ``utc`` contains + an instance representing the UTC timezone. Original patch by Rafe + Kaplan. + +- Issue #8973: Add __all__ to struct module; this ensures that + help(struct) includes documentation for the struct.Struct class. + +- Issue #3129: Trailing digits in struct format string are no longer ignored. + For example, "1" or "ilib123" are now invalid formats and cause + ``struct.error`` to be raised. Patch by Caleb Deveraux. + +- Issue #7384: If the system readline library is linked against ncurses, + the curses module must be linked against ncurses as well. Otherwise it + is not safe to load both the readline and curses modules in an application. + +- Issue #2810: Fix cases where the Windows registry API returns + ERROR_MORE_DATA, requiring a re-try in order to get the complete result. + - Issue #8692: Optimize math.factorial: replace the previous naive algorithm with an improved 'binary-split' algorithm that uses fewer multiplications and allows many of the multiplications to be @@ -1305,6 +1423,9 @@ Build ----- +- Issue #1759169, #8864: Drop _XOPEN_SOURCE on Solaris, define it for + multiprocessing only. + - Issue #8625: Turn off optimization in --with-pydebug builds with gcc. (Optimization was unintentionally turned on in gcc --with-pydebug builds as a result of the issue #1628484 fix, @@ -1391,9 +1512,14 @@ - Update python manual page (options -B, -O0, -s, environment variables PYTHONDONTWRITEBYTECODE, PYTHONNOUSERSITE). +- Issue #8909: Added the size of the bitmap used in the installer created by + distutils' bdist_wininst. Patch by Anatoly Techtonik. + Tests ----- +- Issue #7449: Skip test_socketserver if threading support is disabled + - Issue #8672: Add a zlib test ensuring that an incomplete stream can be handled by a decompressor object without errors (it returns incomplete uncompressed data). @@ -1520,6 +1646,8 @@ Tools/Demos ----------- +- Issue #5464: Implement plural forms in msgfmt.py. + - iobench (a file I/O benchmark) and ccbench (a concurrency benchmark) were added to the `Tools/` directory. They were previously living in the sandbox. Modified: python/branches/py3k-jit/Misc/developers.txt ============================================================================== --- python/branches/py3k-jit/Misc/developers.txt (original) +++ python/branches/py3k-jit/Misc/developers.txt Wed Jun 16 18:21:24 2010 @@ -20,6 +20,9 @@ Permissions History ------------------- +- Alexander Belopolsky was given commit access on May 25 2010 + by MvL at suggestion of Mark Dickinson. + - Tim Golden was given commit access on April 21 2010 by MvL, at suggestion of Michael Foord. Modified: python/branches/py3k-jit/Misc/maintainers.rst ============================================================================== --- python/branches/py3k-jit/Misc/maintainers.rst (original) +++ python/branches/py3k-jit/Misc/maintainers.rst Wed Jun 16 18:21:24 2010 @@ -80,7 +80,7 @@ csv ctypes theller curses andrew.kuchling -datetime +datetime alexander.belopolsky dbm decimal facundobatista, rhettinger, mark.dickinson difflib tim_one @@ -207,7 +207,7 @@ test textwrap threading -time +time alexander.belopolsky timeit tkinter gpolo token georg.brandl Modified: python/branches/py3k-jit/Modules/_codecsmodule.c ============================================================================== --- python/branches/py3k-jit/Modules/_codecsmodule.c (original) +++ python/branches/py3k-jit/Modules/_codecsmodule.c Wed Jun 16 18:21:24 2010 @@ -162,62 +162,62 @@ escape_encode(PyObject *self, PyObject *args) { - static const char *hexdigits = "0123456789abcdef"; - PyObject *str; - Py_ssize_t size; - Py_ssize_t newsize; - const char *errors = NULL; - PyObject *v; - - if (!PyArg_ParseTuple(args, "O!|z:escape_encode", - &PyBytes_Type, &str, &errors)) - return NULL; - - size = PyBytes_GET_SIZE(str); - newsize = 4*size; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { - PyErr_SetString(PyExc_OverflowError, - "string is too large to encode"); - return NULL; - } - v = PyBytes_FromStringAndSize(NULL, newsize); + static const char *hexdigits = "0123456789abcdef"; + PyObject *str; + Py_ssize_t size; + Py_ssize_t newsize; + const char *errors = NULL; + PyObject *v; + + if (!PyArg_ParseTuple(args, "O!|z:escape_encode", + &PyBytes_Type, &str, &errors)) + return NULL; + + size = PyBytes_GET_SIZE(str); + newsize = 4*size; + if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) { + PyErr_SetString(PyExc_OverflowError, + "string is too large to encode"); + return NULL; + } + v = PyBytes_FromStringAndSize(NULL, newsize); - if (v == NULL) { - return NULL; + if (v == NULL) { + return NULL; + } + else { + register Py_ssize_t i; + register char c; + register char *p = PyBytes_AS_STRING(v); + + for (i = 0; i < size; i++) { + /* There's at least enough room for a hex escape */ + assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); + c = PyBytes_AS_STRING(str)[i]; + if (c == '\'' || c == '\\') + *p++ = '\\', *p++ = c; + else if (c == '\t') + *p++ = '\\', *p++ = 't'; + else if (c == '\n') + *p++ = '\\', *p++ = 'n'; + else if (c == '\r') + *p++ = '\\', *p++ = 'r'; + else if (c < ' ' || c >= 0x7f) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = hexdigits[(c & 0xf0) >> 4]; + *p++ = hexdigits[c & 0xf]; + } + else + *p++ = c; } - else { - register Py_ssize_t i; - register char c; - register char *p = PyBytes_AS_STRING(v); - - for (i = 0; i < size; i++) { - /* There's at least enough room for a hex escape */ - assert(newsize - (p - PyBytes_AS_STRING(v)) >= 4); - c = PyBytes_AS_STRING(str)[i]; - if (c == '\'' || c == '\\') - *p++ = '\\', *p++ = c; - else if (c == '\t') - *p++ = '\\', *p++ = 't'; - else if (c == '\n') - *p++ = '\\', *p++ = 'n'; - else if (c == '\r') - *p++ = '\\', *p++ = 'r'; - else if (c < ' ' || c >= 0x7f) { - *p++ = '\\'; - *p++ = 'x'; - *p++ = hexdigits[(c & 0xf0) >> 4]; - *p++ = hexdigits[c & 0xf]; - } - else - *p++ = c; - } - *p = '\0'; - if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { - return NULL; - } + *p = '\0'; + if (_PyBytes_Resize(&v, (p - PyBytes_AS_STRING(v)))) { + return NULL; } + } - return codec_tuple(v, size); + return codec_tuple(v, size); } /* --- Decoder ------------------------------------------------------------ */ @@ -252,7 +252,7 @@ utf_7_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -265,7 +265,7 @@ decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -275,7 +275,7 @@ utf_8_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -288,7 +288,7 @@ decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -298,7 +298,7 @@ utf_16_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -311,7 +311,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -321,7 +321,7 @@ utf_16_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -335,7 +335,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -345,7 +345,7 @@ utf_16_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -359,7 +359,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -377,7 +377,7 @@ utf_16_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -390,7 +390,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -402,7 +402,7 @@ utf_32_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; int final = 0; @@ -415,7 +415,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -425,7 +425,7 @@ utf_32_le_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = -1; int final = 0; @@ -438,7 +438,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -448,7 +448,7 @@ utf_32_be_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 1; int final = 0; @@ -461,7 +461,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -479,7 +479,7 @@ utf_32_ex_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int byteorder = 0; PyObject *unicode, *tuple; @@ -492,7 +492,7 @@ consumed = pbuf.len; /* This is overwritten unless final is true. */ unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (unicode == NULL) return NULL; tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); @@ -504,7 +504,7 @@ unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; PyObject *unicode; @@ -512,68 +512,68 @@ &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * raw_unicode_escape_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; - PyObject *unicode; + PyObject *unicode; if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * latin_1_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:latin_1_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * ascii_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; if (!PyArg_ParseTuple(args, "y*|z:ascii_decode", &pbuf, &errors)) return NULL; - unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } static PyObject * charmap_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; - PyObject *unicode; + Py_buffer pbuf; + PyObject *unicode; const char *errors = NULL; PyObject *mapping = NULL; @@ -583,9 +583,9 @@ if (mapping == Py_None) mapping = NULL; - unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); + PyBuffer_Release(&pbuf); + return codec_tuple(unicode, pbuf.len); } #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) @@ -594,7 +594,7 @@ mbcs_decode(PyObject *self, PyObject *args) { - Py_buffer pbuf; + Py_buffer pbuf; const char *errors = NULL; int final = 0; Py_ssize_t consumed; @@ -607,7 +607,7 @@ decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); + PyBuffer_Release(&pbuf); if (decoded == NULL) return NULL; return codec_tuple(decoded, consumed); @@ -639,21 +639,6 @@ } static PyObject * -charbuffer_encode(PyObject *self, - PyObject *args) -{ - const char *data; - Py_ssize_t size; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "t#|z:charbuffer_encode", - &data, &size, &errors)) - return NULL; - - return codec_tuple(PyBytes_FromStringAndSize(data, size), size); -} - -static PyObject * unicode_internal_encode(PyObject *self, PyObject *args) { @@ -1116,7 +1101,6 @@ {"charmap_decode", charmap_decode, METH_VARARGS}, {"charmap_build", charmap_build, METH_VARARGS}, {"readbuffer_encode", readbuffer_encode, METH_VARARGS}, - {"charbuffer_encode", charbuffer_encode, METH_VARARGS}, #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) {"mbcs_encode", mbcs_encode, METH_VARARGS}, {"mbcs_decode", mbcs_decode, METH_VARARGS}, Modified: python/branches/py3k-jit/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k-jit/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k-jit/Modules/_ctypes/_ctypes.c Wed Jun 16 18:21:24 2010 @@ -4467,7 +4467,7 @@ #endif result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type, - "U(O){s:n,s:O}", + "s(O){s:n,s:O}", name, &PyCArray_Type, "_length_", Modified: python/branches/py3k-jit/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k-jit/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k-jit/Modules/_ctypes/cfield.c Wed Jun 16 18:21:24 2010 @@ -1333,7 +1333,7 @@ break; } - return PyUnicode_FromStringAndSize((char *)ptr, (Py_ssize_t)i); + return PyBytes_FromStringAndSize((char *)ptr, (Py_ssize_t)i); } static PyObject * Modified: python/branches/py3k-jit/Modules/_localemodule.c ============================================================================== --- python/branches/py3k-jit/Modules/_localemodule.c (original) +++ python/branches/py3k-jit/Modules/_localemodule.c Wed Jun 16 18:21:24 2010 @@ -572,19 +572,31 @@ static PyObject* PyIntl_bindtextdomain(PyObject* self,PyObject*args) { - char *domain, *dirname; - if (!PyArg_ParseTuple(args, "sz", &domain, &dirname)) + char *domain, *dirname, *current_dirname; + PyObject *dirname_obj, *dirname_bytes = NULL, *result; + if (!PyArg_ParseTuple(args, "sO", &domain, &dirname_obj)) return 0; if (!strlen(domain)) { PyErr_SetString(Error, "domain must be a non-empty string"); return 0; } - dirname = bindtextdomain(domain, dirname); - if (!dirname) { + if (dirname_obj != Py_None) { + if (!PyUnicode_FSConverter(dirname_obj, &dirname_bytes)) + return NULL; + dirname = PyBytes_AsString(dirname_bytes); + } else { + dirname_bytes = NULL; + dirname = NULL; + } + current_dirname = bindtextdomain(domain, dirname); + if (current_dirname == NULL) { + Py_XDECREF(dirname_bytes); PyErr_SetFromErrno(PyExc_OSError); return NULL; } - return str2uni(dirname); + result = str2uni(current_dirname); + Py_XDECREF(dirname_bytes); + return result; } #ifdef HAVE_BIND_TEXTDOMAIN_CODESET Modified: python/branches/py3k-jit/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/py3k-jit/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/py3k-jit/Modules/_multiprocessing/multiprocessing.h Wed Jun 16 18:21:24 2010 @@ -3,6 +3,12 @@ #define PY_SSIZE_T_CLEAN +#ifdef __sun +/* The control message API is only available on Solaris + if XPG 4.2 or later is requested. */ +#define _XOPEN_SOURCE 500 +#endif + #include "Python.h" #include "structmember.h" #include "pythread.h" Modified: python/branches/py3k-jit/Modules/_sqlite/connection.c ============================================================================== --- python/branches/py3k-jit/Modules/_sqlite/connection.c (original) +++ python/branches/py3k-jit/Modules/_sqlite/connection.c Wed Jun 16 18:21:24 2010 @@ -23,6 +23,7 @@ #include "cache.h" #include "module.h" +#include "structmember.h" #include "connection.h" #include "statement.h" #include "cursor.h" @@ -1551,6 +1552,7 @@ {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY}, {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, + {"in_transaction", T_BOOL, offsetof(pysqlite_Connection, inTransaction), READONLY}, {NULL} }; Modified: python/branches/py3k-jit/Modules/_struct.c ============================================================================== --- python/branches/py3k-jit/Modules/_struct.c (original) +++ python/branches/py3k-jit/Modules/_struct.c Wed Jun 16 18:21:24 2010 @@ -1143,16 +1143,19 @@ } -/* Align a size according to a format code */ +/* Align a size according to a format code. Return -1 on overflow. */ -static int +static Py_ssize_t align(Py_ssize_t size, char c, const formatdef *e) { + Py_ssize_t extra; + if (e->format == c) { - if (e->alignment) { - size = ((size + e->alignment - 1) - / e->alignment) - * e->alignment; + if (e->alignment && size > 0) { + extra = (e->alignment - 1) - (size - 1) % (e->alignment); + if (extra > PY_SSIZE_T_MAX - size) + return -1; + size += extra; } } return size; @@ -1171,7 +1174,7 @@ const char *s; const char *fmt; char c; - Py_ssize_t size, len, num, itemsize, x; + Py_ssize_t size, len, num, itemsize; fmt = PyBytes_AS_STRING(self->s_format); @@ -1186,17 +1189,19 @@ if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { - x = num*10 + (c - '0'); - if (x/10 != num) { - PyErr_SetString( - StructError, - "overflow in item count"); - return -1; - } - num = x; + /* overflow-safe version of + if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ + if (num >= PY_SSIZE_T_MAX / 10 && ( + num > PY_SSIZE_T_MAX / 10 || + (c - '0') > PY_SSIZE_T_MAX % 10)) + goto overflow; + num = num*10 + (c - '0'); + } + if (c == '\0') { + PyErr_SetString(StructError, + "repeat count given without format specifier"); + return -1; } - if (c == '\0') - break; } else num = 1; @@ -1214,13 +1219,13 @@ itemsize = e->size; size = align(size, c, e); - x = num * itemsize; - size += x; - if (x/itemsize != num || size < 0) { - PyErr_SetString(StructError, - "total struct size too long"); - return -1; - } + if (size == -1) + goto overflow; + + /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ + if (num > (PY_SSIZE_T_MAX - size) / itemsize) + goto overflow; + size += num * itemsize; } /* check for overflow */ @@ -1279,6 +1284,11 @@ codes->size = 0; return 0; + + overflow: + PyErr_SetString(StructError, + "total struct size too long"); + return -1; } static PyObject * @@ -1388,9 +1398,9 @@ PyDoc_STRVAR(s_unpack__doc__, "S.unpack(buffer) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\ -strings."); +Return a tuple containing values unpacked according to the format\n\ +string S.format. Requires len(buffer) == S.size. See help(struct)\n\ +for more on format strings."); static PyObject * s_unpack(PyObject *self, PyObject *input) @@ -1416,12 +1426,11 @@ } PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\ +"S.unpack_from(buffer, offset=0) -> (v1, v2, ...)\n\ \n\ -Return tuple containing values unpacked according to this Struct's format.\n\ -Unlike unpack, unpack_from can unpack values from any object supporting\n\ -the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\ -See struct.__doc__ for more on format strings."); +Return a tuple containing values unpacked according to the format\n\ +string S.format. Requires len(buffer[offset:]) >= S.size. See\n\ +help(struct) for more on format strings."); static PyObject * s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds) @@ -1556,8 +1565,9 @@ PyDoc_STRVAR(s_pack__doc__, "S.pack(v1, v2, ...) -> bytes\n\ \n\ -Return a bytes containing values v1, v2, ... packed according to this\n\ -Struct's format. See struct.__doc__ for more on format strings."); +Return a bytes object containing values v1, v2, ... packed according\n\ +to the format string S.format. See help(struct) for more on format\n\ +strings."); static PyObject * s_pack(PyObject *self, PyObject *args) @@ -1593,10 +1603,10 @@ PyDoc_STRVAR(s_pack_into__doc__, "S.pack_into(buffer, offset, v1, v2, ...)\n\ \n\ -Pack the values v1, v2, ... according to this Struct's format, write \n\ -the packed bytes into the writable buffer buf starting at offset. Note\n\ -that the offset is not an optional argument. See struct.__doc__ for \n\ -more on format strings."); +Pack the values v1, v2, ... according to the format string S.format\n\ +and write the packed bytes into the writable buffer buf starting at\n\ +offset. Note that the offset is a required argument. See\n\ +help(struct) for more on format strings."); static PyObject * s_pack_into(PyObject *self, PyObject *args) @@ -1673,7 +1683,11 @@ {NULL, NULL} /* sentinel */ }; -PyDoc_STRVAR(s__doc__, "Compiled struct object"); +PyDoc_STRVAR(s__doc__, +"Struct(fmt) --> compiled struct object\n" +"\n" +"Return a new Struct object which writes and reads binary data according to\n" +"the format string fmt. See help(struct) for more on format strings."); #define OFF(x) offsetof(PyStructObject, x) @@ -1771,7 +1785,9 @@ } PyDoc_STRVAR(calcsize_doc, -"Return size of C struct described by format string fmt."); +"calcsize(fmt) -> integer\n\ +\n\ +Return size in bytes of the struct described by the format string fmt."); static PyObject * calcsize(PyObject *self, PyObject *fmt) @@ -1786,7 +1802,10 @@ } PyDoc_STRVAR(pack_doc, -"Return bytes containing values v1, v2, ... packed according to fmt."); +"pack(fmt, v1, v2, ...) -> bytes\n\ +\n\ +Return a bytes object containing the values v1, v2, ... packed according\n\ +to the format string fmt. See help(struct) for more on format strings."); static PyObject * pack(PyObject *self, PyObject *args) @@ -1815,8 +1834,12 @@ } PyDoc_STRVAR(pack_into_doc, -"Pack the values v1, v2, ... according to fmt.\n\ -Write the packed bytes into the writable buffer buf starting at offset."); +"pack_into(fmt, buffer, offset, v1, v2, ...)\n\ +\n\ +Pack the values v1, v2, ... according to the format string fmt and write\n\ +the packed bytes into the writable buffer buf starting at offset. Note\n\ +that the offset is a required argument. See help(struct) for more\n\ +on format strings."); static PyObject * pack_into(PyObject *self, PyObject *args) @@ -1845,8 +1868,11 @@ } PyDoc_STRVAR(unpack_doc, -"Unpack the bytes containing packed C structure data, according to fmt.\n\ -Requires len(bytes) == calcsize(fmt)."); +"unpack(fmt, buffer) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to the format string\n\ +fmt. Requires len(buffer) == calcsize(fmt). See help(struct) for more\n\ +on format strings."); static PyObject * unpack(PyObject *self, PyObject *args) @@ -1865,8 +1891,11 @@ } PyDoc_STRVAR(unpack_from_doc, -"Unpack the buffer, containing packed C structure data, according to\n\ -fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt)."); +"unpack_from(fmt, buffer, offset=0) -> (v1, v2, ...)\n\ +\n\ +Return a tuple containing values unpacked according to the format string\n\ +fmt. Requires len(buffer[offset:]) >= calcsize(fmt). See help(struct)\n\ +for more on format strings."); static PyObject * unpack_from(PyObject *self, PyObject *args, PyObject *kwds) @@ -1953,11 +1982,7 @@ PyMODINIT_FUNC PyInit__struct(void) { - PyObject *ver, *m; - - ver = PyBytes_FromString("0.3"); - if (ver == NULL) - return NULL; + PyObject *m; m = PyModule_Create(&_structmodule); if (m == NULL) @@ -2019,7 +2044,5 @@ Py_INCREF((PyObject*)&PyStructType); PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType); - PyModule_AddObject(m, "__version__", ver); - return m; } Modified: python/branches/py3k-jit/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k-jit/Modules/_testcapimodule.c (original) +++ python/branches/py3k-jit/Modules/_testcapimodule.c Wed Jun 16 18:21:24 2010 @@ -807,8 +807,161 @@ } #endif +static PyObject * +getargs_s(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "s", &str)) + return NULL; + return PyBytes_FromString(str); +} + +static PyObject * +getargs_s_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "s*", &buffer)) + return NULL; + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_s_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &str, &size)) + return NULL; + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_z(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "z", &str)) + return NULL; + if (str != NULL) + return PyBytes_FromString(str); + else + Py_RETURN_NONE; +} + +static PyObject * +getargs_z_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "z*", &buffer)) + return NULL; + if (buffer.buf != NULL) + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + else { + Py_INCREF(Py_None); + bytes = Py_None; + } + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_z_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "z#", &str, &size)) + return NULL; + if (str != NULL) + return PyBytes_FromStringAndSize(str, size); + else + Py_RETURN_NONE; +} + +static PyObject * +getargs_y(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "y", &str)) + return NULL; + return PyBytes_FromString(str); +} + +static PyObject * +getargs_y_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "y*", &buffer)) + return NULL; + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_y_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "y#", &str, &size)) + return NULL; + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_u(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "u", &str)) + return NULL; + size = Py_UNICODE_strlen(str); + return PyUnicode_FromUnicode(str, size); +} static PyObject * +getargs_u_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "u#", &str, &size)) + return NULL; + return PyUnicode_FromUnicode(str, size); +} + +static PyObject * +getargs_Z(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Z", &str)) + return NULL; + if (str != NULL) { + size = Py_UNICODE_strlen(str); + return PyUnicode_FromUnicode(str, size); + } else + Py_RETURN_NONE; +} + +static PyObject * +getargs_Z_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Z#", &str, &size)) + return NULL; + if (str != NULL) + return PyUnicode_FromUnicode(str, size); + else + Py_RETURN_NONE; +} + +/* Test the s and z codes for PyArg_ParseTuple. +*/ +static PyObject * test_widechar(PyObject *self) { #if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) @@ -1593,11 +1746,24 @@ {"test_longlong_api", test_longlong_api, METH_NOARGS}, {"test_long_long_and_overflow", (PyCFunction)test_long_long_and_overflow, METH_NOARGS}, +#endif + {"getargs_s", getargs_s, METH_VARARGS}, + {"getargs_s_star", getargs_s_star, METH_VARARGS}, + {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, + {"getargs_z", getargs_z, METH_VARARGS}, + {"getargs_z_star", getargs_z_star, METH_VARARGS}, + {"getargs_z_hash", getargs_z_hash, METH_VARARGS}, + {"getargs_y", getargs_y, METH_VARARGS}, + {"getargs_y_star", getargs_y_star, METH_VARARGS}, + {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, + {"getargs_u", getargs_u, METH_VARARGS}, + {"getargs_u_hash", getargs_u_hash, METH_VARARGS}, + {"getargs_Z", getargs_Z, METH_VARARGS}, + {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, {"codec_incrementalencoder", (PyCFunction)codec_incrementalencoder, METH_VARARGS}, {"codec_incrementaldecoder", (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, -#endif {"test_widechar", (PyCFunction)test_widechar, METH_NOARGS}, #ifdef WITH_THREAD {"_test_thread_state", test_thread_state, METH_VARARGS}, Modified: python/branches/py3k-jit/Modules/config.c.in ============================================================================== --- python/branches/py3k-jit/Modules/config.c.in (original) +++ python/branches/py3k-jit/Modules/config.c.in Wed Jun 16 18:21:24 2010 @@ -34,28 +34,28 @@ /* -- ADDMODULE MARKER 2 -- */ - /* This module lives in marshal.c */ - {"marshal", PyMarshal_Init}, + /* This module lives in marshal.c */ + {"marshal", PyMarshal_Init}, - /* This lives in import.c */ - {"imp", PyInit_imp}, + /* This lives in import.c */ + {"imp", PyInit_imp}, - /* This lives in Python/Python-ast.c */ - {"_ast", PyInit__ast}, + /* This lives in Python/Python-ast.c */ + {"_ast", PyInit__ast}, - /* These entries are here for sys.builtin_module_names */ - {"__main__", NULL}, - {"builtins", NULL}, - {"sys", NULL}, + /* These entries are here for sys.builtin_module_names */ + {"__main__", NULL}, + {"builtins", NULL}, + {"sys", NULL}, - /* This lives in gcmodule.c */ - {"gc", PyInit_gc}, + /* This lives in gcmodule.c */ + {"gc", PyInit_gc}, - /* This lives in _warnings.c */ - {"_warnings", _PyWarnings_Init}, + /* This lives in _warnings.c */ + {"_warnings", _PyWarnings_Init}, - /* Sentinel */ - {0, 0} + /* Sentinel */ + {0, 0} }; Modified: python/branches/py3k-jit/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k-jit/Modules/datetimemodule.c (original) +++ python/branches/py3k-jit/Modules/datetimemodule.c Wed Jun 16 18:21:24 2010 @@ -30,6 +30,7 @@ #define MINYEAR 1 #define MAXYEAR 9999 +#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */ /* Nine decimal digits is easy to communicate, and leaves enough room * so that two delta days can be added w/o fear of overflowing a signed @@ -101,6 +102,7 @@ static PyTypeObject PyDateTime_DeltaType; static PyTypeObject PyDateTime_TimeType; static PyTypeObject PyDateTime_TZInfoType; +static PyTypeObject PyDateTime_TimeZoneType; /* --------------------------------------------------------------------------- * Math utilities. @@ -151,6 +153,25 @@ return (long)x; } +/* Nearest integer to m / n for integers m and n. Half-integer results + * are rounded to even. + */ +static PyObject * +divide_nearest(PyObject *m, PyObject *n) +{ + PyObject *result; + PyObject *temp; + + temp = _PyLong_DivmodNear(m, n); + if (temp == NULL) + return NULL; + result = PyTuple_GET_ITEM(temp, 0); + Py_INCREF(result); + Py_DECREF(temp); + + return result; +} + /* --------------------------------------------------------------------------- * General calendrical helper functions */ @@ -480,7 +501,7 @@ * The input values must be such that the internals don't overflow. * The way this routine is used, we don't get close. */ -static void +static int normalize_y_m_d(int *y, int *m, int *d) { int dim; /* # of days in month */ @@ -534,11 +555,23 @@ else { int ordinal = ymd_to_ord(*y, *m, 1) + *d - 1; - ord_to_ymd(ordinal, y, m, d); + if (ordinal < 1 || ordinal > MAXORDINAL) { + goto error; + } else { + ord_to_ymd(ordinal, y, m, d); + return 0; + } } } assert(*m > 0); assert(*d > 0); + if (MINYEAR <= *y && *y <= MAXYEAR) + return 0; + error: + PyErr_SetString(PyExc_OverflowError, + "date value out of range"); + return -1; + } /* Fiddle out-of-bounds months and days so that the result makes some kind @@ -548,17 +581,7 @@ static int normalize_date(int *year, int *month, int *day) { - int result; - - normalize_y_m_d(year, month, day); - if (MINYEAR <= *year && *year <= MAXYEAR) - result = 0; - else { - PyErr_SetString(PyExc_OverflowError, - "date value out of range"); - result = -1; - } - return result; + return normalize_y_m_d(year, month, day); } /* Force all the datetime fields into range. The parameters are both @@ -749,6 +772,52 @@ #define new_delta(d, s, us, normalize) \ new_delta_ex(d, s, us, normalize, &PyDateTime_DeltaType) + +typedef struct +{ + PyObject_HEAD + PyObject *offset; + PyObject *name; +} PyDateTime_TimeZone; + +/* Create new timezone instance checking offset range. This + function does not check the name argument. Caller must assure + that offset is a timedelta instance and name is either NULL + or a unicode object. */ +static PyObject * +new_timezone(PyObject *offset, PyObject *name) +{ + PyDateTime_TimeZone *self; + PyTypeObject *type = &PyDateTime_TimeZoneType; + + assert(offset != NULL); + assert(PyDelta_Check(offset)); + assert(name == NULL || PyUnicode_Check(name)); + + if (GET_TD_MICROSECONDS(offset) != 0 || GET_TD_SECONDS(offset) % 60 != 0) { + PyErr_Format(PyExc_ValueError, "offset must be a timedelta" + " representing a whole number of minutes"); + return NULL; + } + if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0) || + GET_TD_DAYS(offset) < -1 || GET_TD_DAYS(offset) >= 1) { + PyErr_Format(PyExc_ValueError, "offset must be a timedelta" + " strictly between -timedelta(hours=24) and" + " timedelta(hours=24)."); + return NULL; + } + + self = (PyDateTime_TimeZone *)(type->tp_alloc(type, 0)); + if (self == NULL) { + return NULL; + } + Py_INCREF(offset); + self->offset = offset; + Py_XINCREF(name); + self->name = name; + return (PyObject *)self; +} + /* --------------------------------------------------------------------------- * tzinfo helpers. */ @@ -1645,6 +1714,37 @@ } static PyObject * +multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta) +{ + PyObject *result = NULL; + PyObject *pyus_in = NULL, *temp, *pyus_out; + PyObject *ratio = NULL; + + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL); + if (ratio == NULL) + goto error; + temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0)); + Py_DECREF(pyus_in); + pyus_in = NULL; + if (temp == NULL) + goto error; + pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 1)); + Py_DECREF(temp); + if (pyus_out == NULL) + goto error; + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + error: + Py_XDECREF(pyus_in); + Py_XDECREF(ratio); + + return result; +} + +static PyObject * divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj) { PyObject *pyus_in; @@ -1712,6 +1812,55 @@ } static PyObject * +truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f) +{ + PyObject *result = NULL; + PyObject *pyus_in = NULL, *temp, *pyus_out; + PyObject *ratio = NULL; + + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL); + if (ratio == NULL) + goto error; + temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1)); + Py_DECREF(pyus_in); + pyus_in = NULL; + if (temp == NULL) + goto error; + pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, 0)); + Py_DECREF(temp); + if (pyus_out == NULL) + goto error; + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + error: + Py_XDECREF(pyus_in); + Py_XDECREF(ratio); + + return result; +} + +static PyObject * +truedivide_timedelta_int(PyDateTime_Delta *delta, PyObject *i) +{ + PyObject *result; + PyObject *pyus_in, *pyus_out; + pyus_in = delta_to_microseconds(delta); + if (pyus_in == NULL) + return NULL; + pyus_out = divide_nearest(pyus_in, i); + Py_DECREF(pyus_in); + if (pyus_out == NULL) + return NULL; + result = microseconds_to_delta(pyus_out); + Py_DECREF(pyus_out); + + return result; +} + +static PyObject * delta_add(PyObject *left, PyObject *right) { PyObject *result = Py_NotImplemented; @@ -1835,10 +1984,16 @@ if (PyLong_Check(right)) result = multiply_int_timedelta(right, (PyDateTime_Delta *) left); + else if (PyFloat_Check(right)) + result = multiply_float_timedelta(right, + (PyDateTime_Delta *) left); } else if (PyLong_Check(left)) result = multiply_int_timedelta(left, - (PyDateTime_Delta *) right); + (PyDateTime_Delta *) right); + else if (PyFloat_Check(left)) + result = multiply_float_timedelta(left, + (PyDateTime_Delta *) right); if (result == Py_NotImplemented) Py_INCREF(result); @@ -1877,6 +2032,12 @@ result = truedivide_timedelta_timedelta( (PyDateTime_Delta *)left, (PyDateTime_Delta *)right); + else if (PyFloat_Check(right)) + result = truedivide_timedelta_float( + (PyDateTime_Delta *)left, right); + else if (PyLong_Check(right)) + result = truedivide_timedelta_int( + (PyDateTime_Delta *)left, right); } if (result == Py_NotImplemented) @@ -3109,8 +3270,8 @@ PyDoc_STR("datetime -> string name of time zone.")}, {"utcoffset", (PyCFunction)tzinfo_utcoffset, METH_O, - PyDoc_STR("datetime -> minutes east of UTC (negative for " - "west of UTC).")}, + PyDoc_STR("datetime -> timedelta showing offset from UTC, negative " + "values indicating West of UTC")}, {"dst", (PyCFunction)tzinfo_dst, METH_O, PyDoc_STR("datetime -> DST offset in minutes east of UTC.")}, @@ -3147,7 +3308,7 @@ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ tzinfo_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -3169,6 +3330,206 @@ 0, /* tp_free */ }; +static char *timezone_kws[] = {"offset", "name", NULL}; + +static PyObject * +timezone_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ + PyObject *offset; + PyObject *name = NULL; + if (PyArg_ParseTupleAndKeywords(args, kw, "O!|O!:timezone", timezone_kws, + &PyDateTime_DeltaType, &offset, + &PyUnicode_Type, &name)) + return new_timezone(offset, name); + + return NULL; +} + +static void +timezone_dealloc(PyDateTime_TimeZone *self) +{ + Py_CLEAR(self->offset); + Py_CLEAR(self->name); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static PyObject * +timezone_richcompare(PyDateTime_TimeZone *self, + PyDateTime_TimeZone *other, int op) +{ + if (op != Py_EQ && op != Py_NE) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + return delta_richcompare(self->offset, other->offset, op); +} + +static long +timezone_hash(PyDateTime_TimeZone *self) +{ + return delta_hash((PyDateTime_Delta *)self->offset); +} + +/* Check argument type passed to tzname, utcoffset, or dst methods. + Returns 0 for good argument. Returns -1 and sets exception info + otherwise. + */ +static int +_timezone_check_argument(PyObject *dt, const char *meth) +{ + if (dt == Py_None || PyDateTime_Check(dt)) + return 0; + PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance" + " or None, not %.200s", meth, Py_TYPE(dt)->tp_name); + return -1; +} + +static PyObject * +timezone_str(PyDateTime_TimeZone *self) +{ + char buf[10]; + int hours, minutes, seconds; + PyObject *offset; + char sign; + + if (self->name != NULL) { + Py_INCREF(self->name); + return self->name; + } + /* Offset is normalized, so it is negative if days < 0 */ + if (GET_TD_DAYS(self->offset) < 0) { + sign = '-'; + offset = delta_negative((PyDateTime_Delta *)self->offset); + if (offset == NULL) + return NULL; + } + else { + sign = '+'; + offset = self->offset; + Py_INCREF(offset); + } + /* Offset is not negative here. */ + seconds = GET_TD_SECONDS(offset); + Py_DECREF(offset); + minutes = divmod(seconds, 60, &seconds); + hours = divmod(minutes, 60, &minutes); + assert(seconds == 0); + /* XXX ignore sub-minute data, curently not allowed. */ + PyOS_snprintf(buf, sizeof(buf), "UTC%c%02d:%02d", sign, hours, minutes); + + return PyUnicode_FromString(buf); +} + +static PyObject * +timezone_tzname(PyDateTime_TimeZone *self, PyObject *dt) +{ + if (_timezone_check_argument(dt, "tzname") == -1) + return NULL; + + return timezone_str(self); +} + +static PyObject * +timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt) +{ + if (_timezone_check_argument(dt, "utcoffset") == -1) + return NULL; + + Py_INCREF(self->offset); + return self->offset; +} + +static PyObject * +timezone_dst(PyObject *self, PyObject *dt) +{ + if (_timezone_check_argument(dt, "dst") == -1) + return NULL; + + Py_RETURN_NONE; +} + +static PyObject * +add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta, + int factor); + +static PyObject * +timezone_fromutc(PyDateTime_TimeZone *self, PyDateTime_DateTime *dt) +{ + if (! PyDateTime_Check(dt)) { + PyErr_SetString(PyExc_TypeError, + "fromutc: argument must be a datetime"); + return NULL; + } + if (! HASTZINFO(dt) || dt->tzinfo != (PyObject *)self) { + PyErr_SetString(PyExc_ValueError, "fromutc: dt.tzinfo " + "is not self"); + return NULL; + } + + return add_datetime_timedelta(dt, (PyDateTime_Delta *)self->offset, 1); +} + +static PyMethodDef timezone_methods[] = { + {"tzname", (PyCFunction)timezone_tzname, METH_O, + PyDoc_STR("If name is specified when timezone is created, returns the name." + " Otherwise returns offset as 'UTC(+|-)HHMM'.")}, + + {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O, + PyDoc_STR("Returns fixed offset. Ignores its argument.")}, + + {"dst", (PyCFunction)timezone_dst, METH_O, + PyDoc_STR("Returns None. Ignores its argument.")}, + + {"fromutc", (PyCFunction)timezone_fromutc, METH_O, + PyDoc_STR("datetime in UTC -> datetime in local time.")}, + + {NULL, NULL} +}; + +static char timezone_doc[] = +PyDoc_STR("Fixed offset from UTC implementation of tzinfo."); + +static PyTypeObject PyDateTime_TimeZoneType = { + PyVarObject_HEAD_INIT(NULL, 0) + "datetime.timezone", /* tp_name */ + sizeof(PyDateTime_TimeZone), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)timezone_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)timezone_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)timezone_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + timezone_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)timezone_richcompare,/* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + timezone_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyDateTime_TZInfoType, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + timezone_new, /* tp_new */ +}; + /* * PyDateTime_Time implementation. */ @@ -4857,6 +5218,7 @@ PyObject *m; /* a module object */ PyObject *d; /* its dict */ PyObject *x; + PyObject *delta; m = PyModule_Create(&datetimemodule); if (m == NULL) @@ -4872,6 +5234,8 @@ return NULL; if (PyType_Ready(&PyDateTime_TZInfoType) < 0) return NULL; + if (PyType_Ready(&PyDateTime_TimeZoneType) < 0) + return NULL; /* timedelta values */ d = PyDateTime_DeltaType.tp_dict; @@ -4945,6 +5309,36 @@ return NULL; Py_DECREF(x); + /* timezone values */ + d = PyDateTime_TimeZoneType.tp_dict; + + delta = new_delta(0, 0, 0, 0); + if (delta == NULL) + return NULL; + x = new_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL || PyDict_SetItemString(d, "utc", x) < 0) + return NULL; + Py_DECREF(x); + + delta = new_delta(-1, 60, 0, 1); /* -23:59 */ + if (delta == NULL) + return NULL; + x = new_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL || PyDict_SetItemString(d, "min", x) < 0) + return NULL; + Py_DECREF(x); + + delta = new_delta(0, (23 * 60 + 59) * 60, 0, 0); /* +23:59 */ + if (delta == NULL) + return NULL; + x = new_timezone(delta, NULL); + Py_DECREF(delta); + if (x == NULL || PyDict_SetItemString(d, "max", x) < 0) + return NULL; + Py_DECREF(x); + /* module initialization */ PyModule_AddIntConstant(m, "MINYEAR", MINYEAR); PyModule_AddIntConstant(m, "MAXYEAR", MAXYEAR); @@ -4965,6 +5359,9 @@ Py_INCREF(&PyDateTime_TZInfoType); PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType); + Py_INCREF(&PyDateTime_TimeZoneType); + PyModule_AddObject(m, "timezone", (PyObject *) &PyDateTime_TimeZoneType); + x = PyCapsule_New(&CAPI, PyDateTime_CAPSULE_NAME, NULL); if (x == NULL) return NULL; Modified: python/branches/py3k-jit/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k-jit/Modules/itertoolsmodule.c (original) +++ python/branches/py3k-jit/Modules/itertoolsmodule.c Wed Jun 16 18:21:24 2010 @@ -3066,7 +3066,7 @@ }; PyDoc_STRVAR(count_doc, - "count(start=0, step=1]) --> count object\n\ + "count(start=0, step=1) --> count object\n\ \n\ Return a count object whose .__next__() method returns consecutive values.\n\ Equivalent to:\n\n\ Modified: python/branches/py3k-jit/Modules/mathmodule.c ============================================================================== --- python/branches/py3k-jit/Modules/mathmodule.c (original) +++ python/branches/py3k-jit/Modules/mathmodule.c Wed Jun 16 18:21:24 2010 @@ -428,8 +428,8 @@ static double m_erf_series(double x) { - double x2, acc, fk; - int i; + double x2, acc, fk, result; + int i, saved_errno; x2 = x * x; acc = 0.0; @@ -438,7 +438,12 @@ acc = 2.0 + x2 * acc / fk; fk -= 1.0; } - return acc * x * exp(-x2) / sqrtpi; + /* Make sure the exp call doesn't affect errno; + see m_erfc_contfrac for more. */ + saved_errno = errno; + result = acc * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; } /* @@ -453,8 +458,8 @@ static double m_erfc_contfrac(double x) { - double x2, a, da, p, p_last, q, q_last, b; - int i; + double x2, a, da, p, p_last, q, q_last, b, result; + int i, saved_errno; if (x >= ERFC_CONTFRAC_CUTOFF) return 0.0; @@ -472,7 +477,12 @@ 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; + /* Issue #8986: On some platforms, exp sets errno on underflow to zero; + save the current errno value so that we can restore it later. */ + saved_errno = errno; + result = p / q * x * exp(-x2) / sqrtpi; + errno = saved_errno; + return result; } /* Error function erf(x), for general x */ Modified: python/branches/py3k-jit/Modules/readline.c ============================================================================== --- python/branches/py3k-jit/Modules/readline.c (original) +++ python/branches/py3k-jit/Modules/readline.c Wed Jun 16 18:21:24 2010 @@ -98,10 +98,16 @@ static PyObject * read_init_file(PyObject *self, PyObject *args) { - char *s = NULL; - if (!PyArg_ParseTuple(args, "|z:read_init_file", &s)) + PyObject *filename_obj = Py_None, *filename_bytes; + if (!PyArg_ParseTuple(args, "|O:read_init_file", &filename_obj)) return NULL; - errno = rl_read_init_file(s); + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + errno = rl_read_init_file(PyBytes_AsString(filename_bytes)); + Py_DECREF(filename_bytes); + } else + errno = rl_read_init_file(NULL); if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; @@ -118,10 +124,16 @@ static PyObject * read_history_file(PyObject *self, PyObject *args) { - char *s = NULL; - if (!PyArg_ParseTuple(args, "|z:read_history_file", &s)) + PyObject *filename_obj = Py_None, *filename_bytes; + if (!PyArg_ParseTuple(args, "|O:read_history_file", &filename_obj)) return NULL; - errno = read_history(s); + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + errno = read_history(PyBytes_AsString(filename_bytes)); + Py_DECREF(filename_bytes); + } else + errno = read_history(NULL); if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; @@ -139,12 +151,22 @@ static PyObject * write_history_file(PyObject *self, PyObject *args) { - char *s = NULL; - if (!PyArg_ParseTuple(args, "|z:write_history_file", &s)) + PyObject *filename_obj = Py_None, *filename_bytes; + char *filename; + if (!PyArg_ParseTuple(args, "|O:write_history_file", &filename_obj)) return NULL; - errno = write_history(s); + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + filename = PyBytes_AsString(filename_bytes); + } else { + filename_bytes = NULL; + filename = NULL; + } + errno = write_history(filename); if (!errno && _history_length >= 0) - history_truncate_file(s, _history_length); + history_truncate_file(filename, _history_length); + Py_XDECREF(filename_bytes); if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; Modified: python/branches/py3k-jit/Modules/timemodule.c ============================================================================== --- python/branches/py3k-jit/Modules/timemodule.c (original) +++ python/branches/py3k-jit/Modules/timemodule.c Wed Jun 16 18:21:24 2010 @@ -208,21 +208,27 @@ a floating point number for subsecond precision."); static PyStructSequence_Field struct_time_type_fields[] = { - {"tm_year", NULL}, - {"tm_mon", NULL}, - {"tm_mday", NULL}, - {"tm_hour", NULL}, - {"tm_min", NULL}, - {"tm_sec", NULL}, - {"tm_wday", NULL}, - {"tm_yday", NULL}, - {"tm_isdst", NULL}, + {"tm_year", "year, for example, 1993"}, + {"tm_mon", "month of year, range [1, 12]"}, + {"tm_mday", "day of month, range [1, 31]"}, + {"tm_hour", "hours, range [0, 23]"}, + {"tm_min", "minutes, range [0, 59]"}, + {"tm_sec", "seconds, range [0, 61])"}, + {"tm_wday", "day of week, range [0, 6], Monday is 0"}, + {"tm_yday", "day of year, range [1, 366]"}, + {"tm_isdst", "1 if summer time is in effect, 0 if not, and -1 if unknown"}, {0} }; static PyStructSequence_Desc struct_time_type_desc = { "time.struct_time", - NULL, + "The time value as returned by gmtime(), localtime(), and strptime(), and\n" + " accepted by asctime(), mktime() and strftime(). May be considered as a\n" + " sequence of 9 integers.\n\n" + " Note that several fields' values are not the same as those defined by\n" + " the C language standard for struct tm. For example, the value of the\n" + " field tm_year is the actual year, not year - 1900. See individual\n" + " fields' descriptions for details.", struct_time_type_fields, 9, }; Modified: python/branches/py3k-jit/Objects/abstract.c ============================================================================== --- python/branches/py3k-jit/Objects/abstract.c (original) +++ python/branches/py3k-jit/Objects/abstract.c Wed Jun 16 18:21:24 2010 @@ -693,48 +693,37 @@ PyObject * PyObject_Format(PyObject *obj, PyObject *format_spec) { - static PyObject * str__format__ = NULL; PyObject *meth; PyObject *empty = NULL; PyObject *result = NULL; - - /* Initialize cached value */ - if (str__format__ == NULL) { - /* Initialize static variable needed by _PyType_Lookup */ - str__format__ = PyUnicode_FromString("__format__"); - if (str__format__ == NULL) - goto done; - } + static PyObject *format_cache = NULL; /* If no format_spec is provided, use an empty string */ if (format_spec == NULL) { - empty = PyUnicode_FromUnicode(NULL, 0); - format_spec = empty; + empty = PyUnicode_FromUnicode(NULL, 0); + format_spec = empty; } - /* Make sure the type is initialized. float gets initialized late */ - if (Py_TYPE(obj)->tp_dict == NULL) - if (PyType_Ready(Py_TYPE(obj)) < 0) - goto done; - /* Find the (unbound!) __format__ method (a borrowed reference) */ - meth = _PyType_Lookup(Py_TYPE(obj), str__format__); + meth = _PyObject_LookupSpecial(obj, "__format__", &format_cache); if (meth == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __format__", - Py_TYPE(obj)->tp_name); + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __format__", + Py_TYPE(obj)->tp_name); goto done; } - /* And call it, binding it to the value */ - result = PyObject_CallFunctionObjArgs(meth, obj, format_spec, NULL); + /* And call it. */ + result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL); + Py_DECREF(meth); if (result && !PyUnicode_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "__format__ method did not return string"); - Py_DECREF(result); - result = NULL; - goto done; + PyErr_SetString(PyExc_TypeError, + "__format__ method did not return string"); + Py_DECREF(result); + result = NULL; + goto done; } done: Modified: python/branches/py3k-jit/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k-jit/Objects/bytearrayobject.c (original) +++ python/branches/py3k-jit/Objects/bytearrayobject.c Wed Jun 16 18:21:24 2010 @@ -1650,43 +1650,43 @@ char from_c, char to_c, Py_ssize_t maxcount) { - char *self_s, *result_s, *start, *end, *next; - Py_ssize_t self_len; - PyByteArrayObject *result; - - /* The result string will be the same size */ - self_s = PyByteArray_AS_STRING(self); - self_len = PyByteArray_GET_SIZE(self); - - next = findchar(self_s, self_len, from_c); - - if (next == NULL) { - /* No matches; return the original bytes */ - return return_self(self); - } + char *self_s, *result_s, *start, *end, *next; + Py_ssize_t self_len; + PyByteArrayObject *result; - /* Need to make a new bytes */ - result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyByteArray_AS_STRING(result); - Py_MEMCPY(result_s, self_s, self_len); + /* The result string will be the same size */ + self_s = PyByteArray_AS_STRING(self); + self_len = PyByteArray_GET_SIZE(self); - /* change everything in-place, starting with this one */ - start = result_s + (next-self_s); - *start = to_c; - start++; - end = result_s + self_len; - - while (--maxcount > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - *next = to_c; - start = next+1; - } + next = findchar(self_s, self_len, from_c); + + if (next == NULL) { + /* No matches; return the original bytes */ + return return_self(self); + } + + /* Need to make a new bytes */ + result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len); + if (result == NULL) + return NULL; + result_s = PyByteArray_AS_STRING(result); + Py_MEMCPY(result_s, self_s, self_len); + + /* change everything in-place, starting with this one */ + start = result_s + (next-self_s); + *start = to_c; + start++; + end = result_s + self_len; - return result; + while (--maxcount > 0) { + next = findchar(start, end-start, from_c); + if (next == NULL) + break; + *next = to_c; + start = next+1; + } + + return result; } /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ Modified: python/branches/py3k-jit/Objects/bytesobject.c ============================================================================== --- python/branches/py3k-jit/Objects/bytesobject.c (original) +++ python/branches/py3k-jit/Objects/bytesobject.c Wed Jun 16 18:21:24 2010 @@ -14,10 +14,10 @@ if (buffer == NULL || buffer->bf_getbuffer == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't support the buffer API", + Py_TYPE(obj)->tp_name); + return -1; } if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) @@ -776,19 +776,19 @@ { Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) { - Py_buffer varg; - int pos; - PyErr_Clear(); - if (_getbuffer(arg, &varg) < 0) - return -1; - pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), - varg.buf, varg.len, 0); - PyBuffer_Release(&varg); - return pos >= 0; + Py_buffer varg; + int pos; + PyErr_Clear(); + if (_getbuffer(arg, &varg) < 0) + return -1; + pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), + varg.buf, varg.len, 0); + PyBuffer_Release(&varg); + return pos >= 0; } if (ival < 0 || ival >= 256) { - PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); - return -1; + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return -1; } return memchr(PyBytes_AS_STRING(self), ival, Py_SIZE(self)) != NULL; @@ -2345,12 +2345,12 @@ int keepends = 0; if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) - return NULL; + return NULL; return stringlib_splitlines( - (PyObject*) self, PyBytes_AS_STRING(self), - PyBytes_GET_SIZE(self), keepends - ); + (PyObject*) self, PyBytes_AS_STRING(self), + PyBytes_GET_SIZE(self), keepends + ); } Modified: python/branches/py3k-jit/Objects/exceptions.c ============================================================================== --- python/branches/py3k-jit/Objects/exceptions.c (original) +++ python/branches/py3k-jit/Objects/exceptions.c Wed Jun 16 18:21:24 2010 @@ -1510,7 +1510,7 @@ const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason) { - return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU", + return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns", encoding, object, length, start, end, reason); } @@ -1625,7 +1625,7 @@ assert(length < INT_MAX); assert(start < INT_MAX); assert(end < INT_MAX); - return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU", + return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns", encoding, object, length, start, end, reason); } Modified: python/branches/py3k-jit/Objects/longobject.c ============================================================================== --- python/branches/py3k-jit/Objects/longobject.c (original) +++ python/branches/py3k-jit/Objects/longobject.c Wed Jun 16 18:21:24 2010 @@ -4098,23 +4098,34 @@ static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *x = NULL; - int base = -909; /* unlikely! */ + PyObject *obase = NULL, *x = NULL; + long base; + int overflow; static char *kwlist[] = {"x", "base", 0}; if (type != &PyLong_Type) return long_subtype_new(type, args, kwds); /* Wimp out */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, - &x, &base)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:int", kwlist, + &x, &obase)) return NULL; if (x == NULL) return PyLong_FromLong(0L); - if (base == -909) + if (obase == NULL) return PyNumber_Long(x); - else if (PyUnicode_Check(x)) + + base = PyLong_AsLongAndOverflow(obase, &overflow); + if (base == -1 && PyErr_Occurred()) + return NULL; + if (overflow || (base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() arg 2 must be >= 2 and <= 36"); + return NULL; + } + + if (PyUnicode_Check(x)) return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x), PyUnicode_GET_SIZE(x), - base); + (int)base); else if (PyByteArray_Check(x) || PyBytes_Check(x)) { /* Since PyLong_FromString doesn't have a length parameter, * check here for possible NULs in the string. */ @@ -4129,10 +4140,10 @@ x is a bytes or buffer, *and* a base is given. */ PyErr_Format(PyExc_ValueError, "invalid literal for int() with base %d: %R", - base, x); + (int)base, x); return NULL; } - return PyLong_FromString(string, NULL, base); + return PyLong_FromString(string, NULL, (int)base); } else { PyErr_SetString(PyExc_TypeError, @@ -4201,140 +4212,169 @@ PyUnicode_GET_SIZE(format_spec)); } +/* Return a pair (q, r) such that a = b * q + r, and + abs(r) <= abs(b)/2, with equality possible only if q is even. + In other words, q == a / b, rounded to the nearest integer using + round-half-to-even. */ + +PyObject * +_PyLong_DivmodNear(PyObject *a, PyObject *b) +{ + PyLongObject *quo = NULL, *rem = NULL; + PyObject *one = NULL, *twice_rem, *result, *temp; + int cmp, quo_is_odd, quo_is_neg; + + /* Equivalent Python code: + + def divmod_near(a, b): + q, r = divmod(a, b) + # round up if either r / b > 0.5, or r / b == 0.5 and q is odd. + # The expression r / b > 0.5 is equivalent to 2 * r > b if b is + # positive, 2 * r < b if b negative. + greater_than_half = 2*r > b if b > 0 else 2*r < b + exactly_half = 2*r == b + if greater_than_half or exactly_half and q % 2 == 1: + q += 1 + r -= b + return q, r + + */ + if (!PyLong_Check(a) || !PyLong_Check(b)) { + PyErr_SetString(PyExc_TypeError, + "non-integer arguments in division"); + return NULL; + } + + /* Do a and b have different signs? If so, quotient is negative. */ + quo_is_neg = (Py_SIZE(a) < 0) != (Py_SIZE(b) < 0); + + one = PyLong_FromLong(1L); + if (one == NULL) + return NULL; + + if (long_divrem((PyLongObject*)a, (PyLongObject*)b, &quo, &rem) < 0) + goto error; + + /* compare twice the remainder with the divisor, to see + if we need to adjust the quotient and remainder */ + twice_rem = long_lshift((PyObject *)rem, one); + if (twice_rem == NULL) + goto error; + if (quo_is_neg) { + temp = long_neg((PyLongObject*)twice_rem); + Py_DECREF(twice_rem); + twice_rem = temp; + if (twice_rem == NULL) + goto error; + } + cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b); + Py_DECREF(twice_rem); + + quo_is_odd = Py_SIZE(quo) != 0 && ((quo->ob_digit[0] & 1) != 0); + if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { + /* fix up quotient */ + if (quo_is_neg) + temp = long_sub(quo, (PyLongObject *)one); + else + temp = long_add(quo, (PyLongObject *)one); + Py_DECREF(quo); + quo = (PyLongObject *)temp; + if (quo == NULL) + goto error; + /* and remainder */ + if (quo_is_neg) + temp = long_add(rem, (PyLongObject *)b); + else + temp = long_sub(rem, (PyLongObject *)b); + Py_DECREF(rem); + rem = (PyLongObject *)temp; + if (rem == NULL) + goto error; + } + + result = PyTuple_New(2); + if (result == NULL) + goto error; + + /* PyTuple_SET_ITEM steals references */ + PyTuple_SET_ITEM(result, 0, (PyObject *)quo); + PyTuple_SET_ITEM(result, 1, (PyObject *)rem); + Py_DECREF(one); + return result; + + error: + Py_XDECREF(quo); + Py_XDECREF(rem); + Py_XDECREF(one); + return NULL; +} + static PyObject * long_round(PyObject *self, PyObject *args) { - PyObject *o_ndigits=NULL, *temp; - PyLongObject *pow=NULL, *q=NULL, *r=NULL, *ndigits=NULL, *one; - int errcode; - digit q_mod_4; - - /* Notes on the algorithm: to round to the nearest 10**n (n positive), - the straightforward method is: - - (1) divide by 10**n - (2) round to nearest integer (round to even in case of tie) - (3) multiply result by 10**n. - - But the rounding step involves examining the fractional part of the - quotient to see whether it's greater than 0.5 or not. Since we - want to do the whole calculation in integer arithmetic, it's - simpler to do: - - (1) divide by (10**n)/2 - (2) round to nearest multiple of 2 (multiple of 4 in case of tie) - (3) multiply result by (10**n)/2. - - Then all we need to know about the fractional part of the quotient - arising in step (2) is whether it's zero or not. - - Doing both a multiplication and division is wasteful, and is easily - avoided if we just figure out how much to adjust the original input - by to do the rounding. - - Here's the whole algorithm expressed in Python. - - def round(self, ndigits = None): - """round(int, int) -> int""" - if ndigits is None or ndigits >= 0: - return self - pow = 10**-ndigits >> 1 - q, r = divmod(self, pow) - self -= r - if (q & 1 != 0): - if (q & 2 == r == 0): - self -= pow - else: - self += pow - return self + PyObject *o_ndigits=NULL, *temp, *result, *ndigits; - */ + /* To round an integer m to the nearest 10**n (n positive), we make use of + * the divmod_near operation, defined by: + * + * divmod_near(a, b) = (q, r) + * + * where q is the nearest integer to the quotient a / b (the + * nearest even integer in the case of a tie) and r == a - q * b. + * Hence q * b = a - r is the nearest multiple of b to a, + * preferring even multiples in the case of a tie. + * + * So the nearest multiple of 10**n to m is: + * + * m - divmod_near(m, 10**n)[1]. + */ if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) return NULL; if (o_ndigits == NULL) return long_long(self); - ndigits = (PyLongObject *)PyNumber_Index(o_ndigits); + ndigits = PyNumber_Index(o_ndigits); if (ndigits == NULL) return NULL; + /* if ndigits >= 0 then no rounding is necessary; return self unchanged */ if (Py_SIZE(ndigits) >= 0) { Py_DECREF(ndigits); return long_long(self); } - Py_INCREF(self); /* to keep refcounting simple */ - /* we now own references to self, ndigits */ - - /* pow = 10 ** -ndigits >> 1 */ - pow = (PyLongObject *)PyLong_FromLong(10L); - if (pow == NULL) - goto error; - temp = long_neg(ndigits); + /* result = self - divmod_near(self, 10 ** -ndigits)[1] */ + temp = long_neg((PyLongObject*)ndigits); Py_DECREF(ndigits); - ndigits = (PyLongObject *)temp; + ndigits = temp; if (ndigits == NULL) - goto error; - temp = long_pow((PyObject *)pow, (PyObject *)ndigits, Py_None); - Py_DECREF(pow); - pow = (PyLongObject *)temp; - if (pow == NULL) - goto error; - assert(PyLong_Check(pow)); /* check long_pow returned a long */ - one = (PyLongObject *)PyLong_FromLong(1L); - if (one == NULL) - goto error; - temp = long_rshift(pow, one); - Py_DECREF(one); - Py_DECREF(pow); - pow = (PyLongObject *)temp; - if (pow == NULL) - goto error; - - /* q, r = divmod(self, pow) */ - errcode = l_divmod((PyLongObject *)self, pow, &q, &r); - if (errcode == -1) - goto error; - - /* self -= r */ - temp = long_sub((PyLongObject *)self, r); - Py_DECREF(self); - self = temp; - if (self == NULL) - goto error; + return NULL; - /* get value of quotient modulo 4 */ - if (Py_SIZE(q) == 0) - q_mod_4 = 0; - else if (Py_SIZE(q) > 0) - q_mod_4 = q->ob_digit[0] & 3; - else - q_mod_4 = (PyLong_BASE-q->ob_digit[0]) & 3; - - if ((q_mod_4 & 1) == 1) { - /* q is odd; round self up or down by adding or subtracting pow */ - if (q_mod_4 == 1 && Py_SIZE(r) == 0) - temp = (PyObject *)long_sub((PyLongObject *)self, pow); - else - temp = (PyObject *)long_add((PyLongObject *)self, pow); - Py_DECREF(self); - self = temp; - if (self == NULL) - goto error; + result = PyLong_FromLong(10L); + if (result == NULL) { + Py_DECREF(ndigits); + return NULL; } - Py_DECREF(q); - Py_DECREF(r); - Py_DECREF(pow); + + temp = long_pow(result, ndigits, Py_None); Py_DECREF(ndigits); - return self; + Py_DECREF(result); + result = temp; + if (result == NULL) + return NULL; - error: - Py_XDECREF(q); - Py_XDECREF(r); - Py_XDECREF(pow); - Py_XDECREF(self); - Py_XDECREF(ndigits); - return NULL; + temp = _PyLong_DivmodNear(self, result); + Py_DECREF(result); + result = temp; + if (result == NULL) + return NULL; + + temp = long_sub((PyLongObject *)self, + (PyLongObject *)PyTuple_GET_ITEM(result, 1)); + Py_DECREF(result); + result = temp; + + return result; } static PyObject * Modified: python/branches/py3k-jit/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-jit/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-jit/Objects/stringlib/formatter.h Wed Jun 16 18:21:24 2010 @@ -649,8 +649,8 @@ case LT_DEFAULT_LOCALE: locale_info->decimal_point = "."; locale_info->thousands_sep = ","; - locale_info->grouping = "\3"; /* Group every 3 characters, - trailing 0 means repeat + locale_info->grouping = "\3"; /* Group every 3 characters. The + (implicit) trailing 0 means repeat infinitely. */ break; case LT_NO_LOCALE: Modified: python/branches/py3k-jit/Objects/stringlib/string_format.h ============================================================================== --- python/branches/py3k-jit/Objects/stringlib/string_format.h (original) +++ python/branches/py3k-jit/Objects/stringlib/string_format.h Wed Jun 16 18:21:24 2010 @@ -373,6 +373,8 @@ if (_FieldNameIterator_item(self, name) == 0) return 0; *name_idx = get_integer(name); + if (*name_idx == -1 && PyErr_Occurred()) + return 0; break; default: /* Invalid character follows ']' */ @@ -429,6 +431,8 @@ /* see if "first" is an integer, in which case it's used as an index */ *first_idx = get_integer(first); + if (*first_idx == -1 && PyErr_Occurred()) + return 0; field_name_is_empty = first->ptr >= first->end; Modified: python/branches/py3k-jit/Objects/typeobject.c ============================================================================== --- python/branches/py3k-jit/Objects/typeobject.c (original) +++ python/branches/py3k-jit/Objects/typeobject.c Wed Jun 16 18:21:24 2010 @@ -3310,23 +3310,15 @@ PyObject *format_spec; PyObject *self_as_str = NULL; PyObject *result = NULL; - PyObject *format_meth = NULL; if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) return NULL; self_as_str = PyObject_Str(self); - if (self_as_str != NULL) { - /* find the format function */ - format_meth = PyObject_GetAttrString(self_as_str, "__format__"); - if (format_meth != NULL) { - /* and call it */ - result = PyObject_CallFunctionObjArgs(format_meth, format_spec, NULL); - } - } + if (self_as_str != NULL) + result = PyObject_Format(self_as_str, format_spec); Py_XDECREF(self_as_str); - Py_XDECREF(format_meth); return result; } Modified: python/branches/py3k-jit/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k-jit/Objects/unicodeobject.c (original) +++ python/branches/py3k-jit/Objects/unicodeobject.c Wed Jun 16 18:21:24 2010 @@ -1293,25 +1293,24 @@ return NULL; } -PyObject *PyUnicode_Decode(const char *s, - Py_ssize_t size, - const char *encoding, - const char *errors) +/* Convert encoding to lower case and replace '_' with '-' in order to + catch e.g. UTF_8. Return 0 on error (encoding is longer than lower_len-1), + 1 on success. */ +static int +normalize_encoding(const char *encoding, + char *lower, + size_t lower_len) { - PyObject *buffer = NULL, *unicode; - Py_buffer info; - char lower[20]; /* Enough for any encoding name we recognize */ - char *l; const char *e; + char *l; + char *l_end; - if (encoding == NULL) - encoding = PyUnicode_GetDefaultEncoding(); - - /* Convert encoding to lower case and replace '_' with '-' in order to - catch e.g. UTF_8 */ e = encoding; l = lower; - while (*e && l < &lower[(sizeof lower) - 2]) { + l_end = &lower[lower_len - 1]; + while (*e) { + if (l == l_end) + return 0; if (ISUPPER(*e)) { *l++ = TOLOWER(*e++); } @@ -1324,23 +1323,39 @@ } } *l = '\0'; + return 1; +} + +PyObject *PyUnicode_Decode(const char *s, + Py_ssize_t size, + const char *encoding, + const char *errors) +{ + PyObject *buffer = NULL, *unicode; + Py_buffer info; + char lower[11]; /* Enough for any encoding shortcut */ + + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - if (strcmp(lower, "utf-8") == 0) - return PyUnicode_DecodeUTF8(s, size, errors); - else if ((strcmp(lower, "latin-1") == 0) || - (strcmp(lower, "iso-8859-1") == 0)) - return PyUnicode_DecodeLatin1(s, size, errors); + if (normalize_encoding(encoding, lower, sizeof(lower))) { + if (strcmp(lower, "utf-8") == 0) + return PyUnicode_DecodeUTF8(s, size, errors); + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) + return PyUnicode_DecodeLatin1(s, size, errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(lower, "mbcs") == 0) - return PyUnicode_DecodeMBCS(s, size, errors); + else if (strcmp(lower, "mbcs") == 0) + return PyUnicode_DecodeMBCS(s, size, errors); #endif - else if (strcmp(lower, "ascii") == 0) - return PyUnicode_DecodeASCII(s, size, errors); - else if (strcmp(lower, "utf-16") == 0) - return PyUnicode_DecodeUTF16(s, size, errors, 0); - else if (strcmp(lower, "utf-32") == 0) - return PyUnicode_DecodeUTF32(s, size, errors, 0); + else if (strcmp(lower, "ascii") == 0) + return PyUnicode_DecodeASCII(s, size, errors); + else if (strcmp(lower, "utf-16") == 0) + return PyUnicode_DecodeUTF16(s, size, errors, 0); + else if (strcmp(lower, "utf-32") == 0) + return PyUnicode_DecodeUTF32(s, size, errors, 0); + } /* Decode via the codec registry */ buffer = NULL; @@ -1463,11 +1478,17 @@ PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) { - if (Py_FileSystemDefaultEncoding) + if (Py_FileSystemDefaultEncoding) { +#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) + if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + NULL); +#endif return PyUnicode_AsEncodedString(unicode, Py_FileSystemDefaultEncoding, "surrogateescape"); - else + } else return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), "surrogateescape"); @@ -1478,6 +1499,7 @@ const char *errors) { PyObject *v; + char lower[11]; /* Enough for any encoding shortcut */ if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); @@ -1488,24 +1510,27 @@ encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - if (strcmp(encoding, "utf-8") == 0) - return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); - else if (strcmp(encoding, "latin-1") == 0) - return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + if (normalize_encoding(encoding, lower, sizeof(lower))) { + if (strcmp(lower, "utf-8") == 0) + return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) + return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(encoding, "mbcs") == 0) - return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + else if (strcmp(lower, "mbcs") == 0) + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #endif - else if (strcmp(encoding, "ascii") == 0) - return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + else if (strcmp(lower, "ascii") == 0) + return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + } /* During bootstrap, we may need to find the encodings package, to load the file system encoding, and require the file system encoding in order to load the encodings @@ -1515,7 +1540,7 @@ the encodings module is ASCII-only. XXX could try wcstombs instead, if the file system encoding is the locale's encoding. */ - else if (Py_FileSystemDefaultEncoding && + if (Py_FileSystemDefaultEncoding && strcmp(encoding, Py_FileSystemDefaultEncoding) == 0 && !PyThreadState_GET()->interp->codecs_initialized) return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), @@ -1620,7 +1645,7 @@ if (Py_FileSystemDefaultEncoding) { #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) { - return PyUnicode_DecodeMBCS(s, size, "surrogateescape"); + return PyUnicode_DecodeMBCS(s, size, NULL); } #elif defined(__APPLE__) if (strcmp(Py_FileSystemDefaultEncoding, "utf-8") == 0) { @@ -2711,7 +2736,8 @@ PyUnicodeObject *unicode; Py_UNICODE *p; #ifndef Py_UNICODE_WIDE - int i, pairs; + int pairs = 0; + const unsigned char *qq; #else const int pairs = 0; #endif @@ -2726,23 +2752,7 @@ #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* On narrow builds we split characters outside the BMP into two - codepoints => count how much extra space we need. */ -#ifndef Py_UNICODE_WIDE - for (i = pairs = 0; i < size/4; i++) - if (((Py_UCS4 *)s)[i] >= 0x10000) - pairs++; -#endif - /* This might be one to much, because of a BOM */ - unicode = _PyUnicode_New((size+3)/4+pairs); - if (!unicode) - return NULL; - if (size == 0) - return (PyObject *)unicode; - - /* Unpack UTF-32 encoded data */ - p = unicode->str; q = (unsigned char *)s; e = q + size; @@ -2794,6 +2804,24 @@ iorder[3] = 0; } + /* On narrow builds we split characters outside the BMP into two + codepoints => count how much extra space we need. */ +#ifndef Py_UNICODE_WIDE + for (qq = q; qq < e; qq += 4) + if (qq[iorder[2]] != 0 || qq[iorder[3]] != 0) + pairs++; +#endif + + /* This might be one to much, because of a BOM */ + unicode = _PyUnicode_New((size+3)/4+pairs); + if (!unicode) + return NULL; + if (size == 0) + return (PyObject *)unicode; + + /* Unpack UTF-32 encoded data */ + p = unicode->str; + while (q < e) { Py_UCS4 ch; /* remaining bytes at the end? (size should be divisible by 4) */ Modified: python/branches/py3k-jit/PC/winreg.c ============================================================================== --- python/branches/py3k-jit/PC/winreg.c (original) +++ python/branches/py3k-jit/PC/winreg.c Wed Jun 16 18:21:24 2010 @@ -1096,7 +1096,14 @@ int index; long rc; PyObject *retStr; - wchar_t tmpbuf[256]; /* max key name length is 255 */ + + /* The Windows docs claim that the max key name length is 255 + * characters, plus a terminating nul character. However, + * empirical testing demonstrates that it is possible to + * create a 256 character key that is missing the terminating + * nul. RegEnumKeyEx requires a 257 character buffer to + * retrieve such a key name. */ + wchar_t tmpbuf[257]; DWORD len = sizeof(tmpbuf); /* includes NULL terminator */ if (!PyArg_ParseTuple(args, "Oi:EnumKey", &obKey, &index)) @@ -1122,9 +1129,10 @@ int index; long rc; wchar_t *retValueBuf; + wchar_t *tmpBuf; BYTE *retDataBuf; - DWORD retValueSize; - DWORD retDataSize; + DWORD retValueSize, bufValueSize; + DWORD retDataSize, bufDataSize; DWORD typ; PyObject *obData; PyObject *retVal; @@ -1142,6 +1150,8 @@ "RegQueryInfoKey"); ++retValueSize; /* include null terminators */ ++retDataSize; + bufDataSize = retDataSize; + bufValueSize = retValueSize; retValueBuf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t) * retValueSize); if (retValueBuf == NULL) return PyErr_NoMemory(); @@ -1151,16 +1161,32 @@ return PyErr_NoMemory(); } - Py_BEGIN_ALLOW_THREADS - rc = RegEnumValueW(hKey, - index, - retValueBuf, - &retValueSize, - NULL, - &typ, - retDataBuf, - &retDataSize); - Py_END_ALLOW_THREADS + while (1) { + Py_BEGIN_ALLOW_THREADS + rc = RegEnumValueW(hKey, + index, + retValueBuf, + &retValueSize, + NULL, + &typ, + (BYTE *)retDataBuf, + &retDataSize); + Py_END_ALLOW_THREADS + + if (rc != ERROR_MORE_DATA) + break; + + bufDataSize *= 2; + tmpBuf = (wchar_t *)PyMem_Realloc(retDataBuf, bufDataSize); + if (tmpBuf == NULL) { + PyErr_NoMemory(); + retVal = NULL; + goto fail; + } + retDataBuf = tmpBuf; + retDataSize = bufDataSize; + retValueSize = bufValueSize; + } if (rc != ERROR_SUCCESS) { retVal = PyErr_SetFromWindowsErrWithFunction(rc, @@ -1317,23 +1343,44 @@ long rc; PyObject *retStr; wchar_t *retBuf; - long bufSize = 0; + DWORD bufSize = 0; + DWORD retSize = 0; + wchar_t *tmp; if (!PyArg_ParseTuple(args, "OZ:QueryValue", &obKey, &subKey)) return NULL; if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) return NULL; - if ((rc = RegQueryValueW(hKey, subKey, NULL, &bufSize)) - != ERROR_SUCCESS) + + rc = RegQueryValueW(hKey, subKey, NULL, &retSize); + if (rc == ERROR_MORE_DATA) + retSize = 256; + else if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValue"); - retBuf = (wchar_t *)PyMem_Malloc(bufSize); + + bufSize = retSize; + retBuf = (wchar_t *) PyMem_Malloc(bufSize); if (retBuf == NULL) return PyErr_NoMemory(); - if ((rc = RegQueryValueW(hKey, subKey, retBuf, &bufSize)) - != ERROR_SUCCESS) { + while (1) { + retSize = bufSize; + rc = RegQueryValueW(hKey, subKey, retBuf, &retSize); + if (rc != ERROR_MORE_DATA) + break; + + bufSize *= 2; + tmp = (wchar_t *) PyMem_Realloc(retBuf, bufSize); + if (tmp == NULL) { + PyMem_Free(retBuf); + return PyErr_NoMemory(); + } + retBuf = tmp; + } + + if (rc != ERROR_SUCCESS) { PyMem_Free(retBuf); return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValue"); @@ -1352,8 +1399,8 @@ wchar_t *valueName; long rc; - BYTE *retBuf; - DWORD bufSize = 0; + BYTE *retBuf, *tmp; + DWORD bufSize = 0, retSize; DWORD typ; PyObject *obData; PyObject *result; @@ -1363,18 +1410,34 @@ if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) return NULL; - if ((rc = RegQueryValueExW(hKey, valueName, - NULL, NULL, NULL, - &bufSize)) - != ERROR_SUCCESS) + + rc = RegQueryValueExW(hKey, valueName, NULL, NULL, NULL, &bufSize); + if (rc == ERROR_MORE_DATA) + bufSize = 256; + else if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValueEx"); retBuf = (BYTE *)PyMem_Malloc(bufSize); if (retBuf == NULL) return PyErr_NoMemory(); - if ((rc = RegQueryValueExW(hKey, valueName, NULL, - &typ, retBuf, &bufSize)) - != ERROR_SUCCESS) { + + while (1) { + retSize = bufSize; + rc = RegQueryValueExW(hKey, valueName, NULL, &typ, + (BYTE *)retBuf, &retSize); + if (rc != ERROR_MORE_DATA) + break; + + bufSize *= 2; + tmp = (char *) PyMem_Realloc(retBuf, bufSize); + if (tmp == NULL) { + PyMem_Free(retBuf); + return PyErr_NoMemory(); + } + retBuf = tmp; + } + + if (rc != ERROR_SUCCESS) { PyMem_Free(retBuf); return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValueEx"); Modified: python/branches/py3k-jit/Parser/asdl_c.py ============================================================================== --- python/branches/py3k-jit/Parser/asdl_c.py (original) +++ python/branches/py3k-jit/Parser/asdl_c.py Wed Jun 16 18:21:24 2010 @@ -722,7 +722,7 @@ } PyTuple_SET_ITEM(fnames, i, field); } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "U(O){sOss}", + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sOss}", type, base, "_fields", fnames, "__module__", "_ast"); Py_DECREF(fnames); return (PyTypeObject*)result; Modified: python/branches/py3k-jit/Python/Python-ast.c ============================================================================== --- python/branches/py3k-jit/Python/Python-ast.c (original) +++ python/branches/py3k-jit/Python/Python-ast.c Wed Jun 16 18:21:24 2010 @@ -527,7 +527,7 @@ } PyTuple_SET_ITEM(fnames, i, field); } - result = PyObject_CallFunction((PyObject*)&PyType_Type, "U(O){sOss}", + result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sOss}", type, base, "_fields", fnames, "__module__", "_ast"); Py_DECREF(fnames); return (PyTypeObject*)result; Modified: python/branches/py3k-jit/Python/ceval.c ============================================================================== --- python/branches/py3k-jit/Python/ceval.c (original) +++ python/branches/py3k-jit/Python/ceval.c Wed Jun 16 18:21:24 2010 @@ -655,7 +655,7 @@ } pendingcalls[NPENDINGCALLS]; static volatile int pendingfirst = 0; static volatile int pendinglast = 0; -static volatile int pendingcalls_to_do = 0; +static _Py_atomic_int pendingcalls_to_do = {0}; int Py_AddPendingCall(int (*func)(void *), void *arg) Modified: python/branches/py3k-jit/Python/errors.c ============================================================================== --- python/branches/py3k-jit/Python/errors.c (original) +++ python/branches/py3k-jit/Python/errors.c Wed Jun 16 18:21:24 2010 @@ -679,7 +679,7 @@ goto failure; } /* Create a real new-style class. */ - result = PyObject_CallFunction((PyObject *)&PyType_Type, "UOO", + result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO", dot+1, bases, dict); failure: Py_XDECREF(bases); Modified: python/branches/py3k-jit/Python/getargs.c ============================================================================== --- python/branches/py3k-jit/Python/getargs.c (original) +++ python/branches/py3k-jit/Python/getargs.c Wed Jun 16 18:21:24 2010 @@ -582,19 +582,6 @@ #define CONV_UNICODE "(unicode conversion error)" -/* explicitly check for float arguments when integers are expected. For now - * signal a warning. Returns true if an exception was raised. */ -static int -float_argument_warning(PyObject *arg) -{ - if (PyFloat_Check(arg) && - PyErr_Warn(PyExc_DeprecationWarning, - "integer argument expected, got float" )) - return 1; - else - return 0; -} - /* Explicitly check for float arguments when integers are expected. Return 1 for error, 0 if ok. */ static int @@ -791,14 +778,13 @@ case 'L': {/* PY_LONG_LONG */ PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * ); PY_LONG_LONG ival; - if (float_argument_warning(arg)) + if (float_argument_error(arg)) return converterr("long", arg, msgbuf, bufsize); ival = PyLong_AsLongLong(arg); - if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) { + if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred()) return converterr("long", arg, msgbuf, bufsize); - } else { + else *p = ival; - } break; } @@ -864,7 +850,7 @@ break; } - /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w', 't' codes all + /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all need to be cleaned up! */ case 's': {/* text string */ @@ -949,10 +935,15 @@ count = convertbuffer(arg, p, &buf); if (count < 0) return converterr(buf, arg, msgbuf, bufsize); - else if (*format == '#') { + if (*format == '#') { FETCH_SIZE; STORE_SIZE(count); format++; + } else { + if (strlen(*p) != count) + return converterr( + "bytes without null bytes", + arg, msgbuf, bufsize); } break; } @@ -1029,18 +1020,7 @@ else return converterr("string or None", arg, msgbuf, bufsize); - if (*format == '#') { - FETCH_SIZE; - assert(0); /* XXX redundant with if-case */ - if (arg == Py_None) { - STORE_SIZE(0); - } - else { - STORE_SIZE(PyBytes_Size(arg)); - } - format++; - } - else if (*p != NULL && uarg != NULL && + if (*p != NULL && uarg != NULL && (Py_ssize_t) strlen(*p) != PyBytes_GET_SIZE(uarg)) return converterr( "string without null bytes or None", @@ -1062,17 +1042,22 @@ *p = PyUnicode_AS_UNICODE(arg); STORE_SIZE(PyUnicode_GET_SIZE(arg)); } + else + return converterr("str or None", arg, msgbuf, bufsize); format++; } else { Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); if (arg == Py_None) *p = 0; - else if (PyUnicode_Check(arg)) + else if (PyUnicode_Check(arg)) { *p = PyUnicode_AS_UNICODE(arg); - else - return converterr("string or None", - arg, msgbuf, bufsize); + if (Py_UNICODE_strlen(*p) != PyUnicode_GET_SIZE(arg)) + return converterr( + "str without null character or None", + arg, msgbuf, bufsize); + } else + return converterr("str or None", arg, msgbuf, bufsize); } break; } @@ -1183,6 +1168,7 @@ *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); + PyErr_NoMemory(); return converterr( "(memory error)", arg, msgbuf, bufsize); @@ -1226,6 +1212,7 @@ *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); + PyErr_NoMemory(); return converterr("(memory error)", arg, msgbuf, bufsize); } @@ -1249,6 +1236,11 @@ FETCH_SIZE; STORE_SIZE(PyUnicode_GET_SIZE(arg)); format++; + } else { + if (Py_UNICODE_strlen(*p) != PyUnicode_GET_SIZE(arg)) + return converterr( + "str without null character", + arg, msgbuf, bufsize); } break; } @@ -1267,7 +1259,7 @@ if (PyByteArray_Check(arg)) *p = arg; else - return converterr("buffer", arg, msgbuf, bufsize); + return converterr("bytearray", arg, msgbuf, bufsize); break; } @@ -1293,17 +1285,6 @@ return converterr(type->tp_name, arg, msgbuf, bufsize); } - else if (*format == '?') { - inquiry pred = va_arg(*p_va, inquiry); - p = va_arg(*p_va, PyObject **); - format++; - if ((*pred)(arg)) - *p = arg; - else - return converterr("(unspecified)", - arg, msgbuf, bufsize); - - } else if (*format == '&') { typedef int (*converter)(PyObject *, void *); converter convert = va_arg(*p_va, converter); @@ -1381,45 +1362,6 @@ break; } - /*TEO: This can be eliminated --- here only for backward - compatibility */ - case 't': { /* 8-bit character buffer, read-only access */ - char **p = va_arg(*p_va, char **); - PyBufferProcs *pb = arg->ob_type->tp_as_buffer; - Py_ssize_t count; - Py_buffer view; - - if (*format++ != '#') - return converterr( - "invalid use of 't' format character", - arg, msgbuf, bufsize); - if (pb == NULL || pb->bf_getbuffer == NULL) - return converterr( - "bytes or read-only character buffer", - arg, msgbuf, bufsize); - - if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0) - return converterr("string or single-segment read-only buffer", - arg, msgbuf, bufsize); - - count = view.len; - *p = view.buf; - if (pb->bf_releasebuffer) - return converterr( - "string or pinned buffer", - arg, msgbuf, bufsize); - - PyBuffer_Release(&view); - - if (count < 0) - return converterr("(unspecified)", arg, msgbuf, bufsize); - { - FETCH_SIZE; - STORE_SIZE(count); - } - break; - } - default: return converterr("impossible", arg, msgbuf, bufsize); @@ -1432,7 +1374,7 @@ static Py_ssize_t convertbuffer(PyObject *arg, void **p, char **errmsg) { - PyBufferProcs *pb = arg->ob_type->tp_as_buffer; + PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; Py_ssize_t count; Py_buffer view; @@ -1460,31 +1402,23 @@ static int getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) { - void *buf; - Py_ssize_t count; - PyBufferProcs *pb = arg->ob_type->tp_as_buffer; + PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; if (pb == NULL) { *errmsg = "bytes or buffer"; return -1; } - if (pb->bf_getbuffer) { - if (PyObject_GetBuffer(arg, view, 0) < 0) { - *errmsg = "convertible to a buffer"; - return -1; - } - if (!PyBuffer_IsContiguous(view, 'C')) { - *errmsg = "contiguous buffer"; - return -1; - } - return 0; + if (pb->bf_getbuffer == NULL) { + *errmsg = "convertible to a buffer"; + return -1; } - - count = convertbuffer(arg, &buf, errmsg); - if (count < 0) { + if (PyObject_GetBuffer(arg, view, 0) < 0) { *errmsg = "convertible to a buffer"; - return count; + return -1; + } + if (!PyBuffer_IsContiguous(view, 'C')) { + *errmsg = "contiguous buffer"; + return -1; } - PyBuffer_FillInfo(view, NULL, buf, count, 1, 0); return 0; } @@ -1834,7 +1768,6 @@ case 'z': /* string or None */ case 'y': /* bytes */ case 'u': /* unicode string */ - case 't': /* buffer, read-only */ case 'w': /* buffer, read-write */ { (void) va_arg(*p_va, char **); Modified: python/branches/py3k-jit/Python/modsupport.c ============================================================================== --- python/branches/py3k-jit/Python/modsupport.c (original) +++ python/branches/py3k-jit/Python/modsupport.c Wed Jun 16 18:21:24 2010 @@ -302,39 +302,7 @@ case 's': case 'z': - { - PyObject *v; - char *str = va_arg(*p_va, char *); - Py_ssize_t n; - if (**p_format == '#') { - ++*p_format; - if (flags & FLAG_SIZE_T) - n = va_arg(*p_va, Py_ssize_t); - else - n = va_arg(*p_va, int); - } - else - n = -1; - if (str == NULL) { - v = Py_None; - Py_INCREF(v); - } - else { - if (n < 0) { - size_t m = strlen(str); - if (m > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "string too long for Python string"); - return NULL; - } - n = (Py_ssize_t)m; - } - v = PyUnicode_FromStringAndSize(str, n); - } - return v; - } - - case 'U': + case 'U': /* XXX deprecated alias */ { PyObject *v; char *str = va_arg(*p_va, char *); Modified: python/branches/py3k-jit/Python/pythonrun.c ============================================================================== --- python/branches/py3k-jit/Python/pythonrun.c (original) +++ python/branches/py3k-jit/Python/pythonrun.c Wed Jun 16 18:21:24 2010 @@ -704,24 +704,26 @@ #if defined(HAVE_LANGINFO_H) && defined(CODESET) char *codeset; - /* On Unix, set the file system encoding according to the - user's preference, if the CODESET names a well-known - Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - codeset = get_codeset(); - if (codeset != NULL) { - Py_FileSystemDefaultEncoding = codeset; - Py_HasFileSystemDefaultEncoding = 0; - return; - } + if (Py_FileSystemDefaultEncoding == NULL) { + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. Also set the encoding of + stdin and stdout if these are terminals. */ + codeset = get_codeset(); + if (codeset != NULL) { + Py_FileSystemDefaultEncoding = codeset; + Py_HasFileSystemDefaultEncoding = 0; + return; + } - PyErr_Clear(); - fprintf(stderr, - "Unable to get the locale encoding: " - "fallback to utf-8\n"); - Py_FileSystemDefaultEncoding = "utf-8"; - Py_HasFileSystemDefaultEncoding = 1; + PyErr_Clear(); + fprintf(stderr, + "Unable to get the locale encoding: " + "fallback to utf-8\n"); + Py_FileSystemDefaultEncoding = "utf-8"; + Py_HasFileSystemDefaultEncoding = 1; + } #endif /* the encoding is mbcs, utf-8 or ascii */ @@ -2056,7 +2058,7 @@ fprintf(stderr, "Fatal Python error: %s\n", msg); fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { - PyErr_Print(); + PyErr_PrintEx(0); } #ifdef MS_WINDOWS { Modified: python/branches/py3k-jit/Python/symtable.c ============================================================================== --- python/branches/py3k-jit/Python/symtable.c (original) +++ python/branches/py3k-jit/Python/symtable.c Wed Jun 16 18:21:24 2010 @@ -1533,7 +1533,7 @@ symtable_visit_alias(struct symtable *st, alias_ty a) { /* Compute store_name, the name actually bound by the import - operation. It is diferent than a->name when a->name is a + operation. It is different than a->name when a->name is a dotted package name (e.g. spam.eggs) */ PyObject *store_name; Modified: python/branches/py3k-jit/Python/sysmodule.c ============================================================================== --- python/branches/py3k-jit/Python/sysmodule.c (original) +++ python/branches/py3k-jit/Python/sysmodule.c Wed Jun 16 18:21:24 2010 @@ -1510,7 +1510,7 @@ PyLong_FromLong(PY_VERSION_HEX)); svnversion_init(); SET_SYS_FROM_STRING("subversion", - Py_BuildValue("(UUU)", "CPython", branch, + Py_BuildValue("(sss)", "CPython", branch, svn_revision)); SET_SYS_FROM_STRING("dont_write_bytecode", PyBool_FromLong(Py_DontWriteBytecodeFlag)); @@ -1839,6 +1839,9 @@ PyObject *unicode = NULL, *writer = NULL, *args = NULL, *result = NULL; int err; + if (file == NULL) + return -1; + unicode = PyUnicode_FromString(text); if (unicode == NULL) goto error; Modified: python/branches/py3k-jit/Tools/i18n/msgfmt.py ============================================================================== --- python/branches/py3k-jit/Tools/i18n/msgfmt.py (original) +++ python/branches/py3k-jit/Tools/i18n/msgfmt.py Wed Jun 16 18:21:24 2010 @@ -30,6 +30,7 @@ import getopt import struct import array +from email.parser import HeaderParser __version__ = "1.1" @@ -59,13 +60,13 @@ # the keys are sorted in the .mo file keys = sorted(MESSAGES.keys()) offsets = [] - ids = strs = '' + ids = strs = b'' for id in keys: # For each string, we need size and file offset. Each string is NUL # terminated; the NUL does not count into the size. offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) - ids += id + '\0' - strs += MESSAGES[id] + '\0' + ids += id + b'\0' + strs += MESSAGES[id] + b'\0' output = '' # The header is 7 32-bit unsigned integers. We don't use hash tables, so # the keys start right after the index tables. @@ -108,7 +109,7 @@ outfile = os.path.splitext(infile)[0] + '.mo' try: - lines = open(infile).readlines() + lines = open(infile, 'rb').readlines() except IOError as msg: print(msg, file=sys.stderr) sys.exit(1) @@ -116,9 +117,14 @@ section = None fuzzy = 0 + # Start off assuming Latin-1, so everything decodes without failure, + # until we know the exact encoding + encoding = 'latin-1' + # Parse the catalog lno = 0 for l in lines: + l = l.decode(encoding) lno += 1 # If we get a comment line after a msgstr, this is a new entry if l[0] == '#' and section == STR: @@ -132,16 +138,45 @@ if l[0] == '#': continue # Now we are in a msgid section, output previous section - if l.startswith('msgid'): + if l.startswith('msgid') and not l.startswith('msgid_plural'): if section == STR: add(msgid, msgstr, fuzzy) + if not msgid: + # See whether there is an encoding declaration + p = HeaderParser() + charset = p.parsestr(msgstr.decode(encoding)).get_content_charset() + if charset: + encoding = charset section = ID l = l[5:] - msgid = msgstr = '' + msgid = msgstr = b'' + is_plural = False + # This is a message with plural forms + elif l.startswith('msgid_plural'): + if section != ID: + print('msgid_plural not preceeded by msgid on %s:%d' % (infile, lno), + file=sys.stderr) + sys.exit(1) + l = l[12:] + msgid += b'\0' # separator of singular and plural + is_plural = True # Now we are in a msgstr section elif l.startswith('msgstr'): section = STR - l = l[6:] + if l.startswith('msgstr['): + if not is_plural: + print(sys.stderr, 'plural without msgid_plural on %s:%d' % (infile, lno), + file=sys.stderr) + sys.exit(1) + l = l.split(']', 1)[1] + if msgstr: + msgstr += b'\0' # Separator of the various plural forms + else: + if is_plural: + print(sys.stderr, 'indexed msgstr required for plural on %s:%d' % (infile, lno), + file=sys.stderr) + sys.exit(1) + l = l[6:] # Skip empty lines l = l.strip() if not l: @@ -149,9 +184,9 @@ # XXX: Does this always follow Python escape semantics? l = eval(l) if section == ID: - msgid += l + msgid += l.encode(encoding) elif section == STR: - msgstr += l + msgstr += l.encode(encoding) else: print('Syntax error on %s:%d' % (infile, lno), \ 'before:', file=sys.stderr) Modified: python/branches/py3k-jit/Tools/scripts/serve.py ============================================================================== --- python/branches/py3k-jit/Tools/scripts/serve.py (original) +++ python/branches/py3k-jit/Tools/scripts/serve.py Wed Jun 16 18:21:24 2010 @@ -28,5 +28,8 @@ path = sys.argv[1] port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000 httpd = simple_server.make_server('', port, app) - print("Serving {} on port {}".format(path, port)) - httpd.serve_forever() + print("Serving {} on port {}, control-C to stop".format(path, port)) + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("\b\bShutting down.") Modified: python/branches/py3k-jit/configure ============================================================================== --- python/branches/py3k-jit/configure (original) +++ python/branches/py3k-jit/configure Wed Jun 16 18:21:24 2010 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 81086 . +# From configure.in Revision: 81078 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65 for python 3.2. # @@ -1950,11 +1950,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default - enum { N = $2 / 2 - 1 }; int main () { -static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +static int test_array [1 - 2 * !(enum { N = $2 / 2 - 1 }; + 0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; test_array [0] = 0 ; @@ -1965,11 +1965,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default - enum { N = $2 / 2 - 1 }; int main () { -static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) +static int test_array [1 - 2 * !(enum { N = $2 / 2 - 1 }; + ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; test_array [0] = 0 @@ -3034,9 +3034,12 @@ # Marc Recht NetBSD/1.5 | NetBSD/1.5.* | NetBSD/1.6 | NetBSD/1.6.* | NetBSD/1.6[A-S]) define_xopen_source=no;; - # On Solaris 2.6, sys/wait.h is inconsistent in the usage - # of union __?sigval. Reported by Stuart Bishop. - SunOS/5.6) + # From the perspective of Solaris, _XOPEN_SOURCE is not so much a + # request to enable features supported by the standard as a request + # to disable features not supported by the standard. The best way + # for Python to use Solaris is simply to leave _XOPEN_SOURCE out + # entirely and define __EXTENSIONS__ instead. + SunOS/*) define_xopen_source=no;; # On UnixWare 7, u_long is never defined with _XOPEN_SOURCE, # but used in /usr/include/netinet/tcp.h. Reported by Tim Rice. @@ -3082,38 +3085,17 @@ if test $define_xopen_source = yes then - # On Solaris w/ g++ it appears that _XOPEN_SOURCE has to be - # defined precisely as g++ defines it - # Furthermore, on Solaris 10, XPG6 requires the use of a C99 - # compiler - case $ac_sys_system/$ac_sys_release in - SunOS/5.8|SunOS/5.9|SunOS/5.10) - -$as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h - - ;; - *) $as_echo "#define _XOPEN_SOURCE 600" >>confdefs.h - ;; - esac # On Tru64 Unix 4.0F, defining _XOPEN_SOURCE also requires # definition of _XOPEN_SOURCE_EXTENDED and _POSIX_C_SOURCE, or else # several APIs are not declared. Since this is also needed in some # cases for HP-UX, we define it globally. - # except for Solaris 10, where it must not be defined, - # as it implies XPG4.2 - case $ac_sys_system/$ac_sys_release in - SunOS/5.10) - ;; - *) $as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h - ;; - esac $as_echo "#define _POSIX_C_SOURCE 200112L" >>confdefs.h Modified: python/branches/py3k-jit/configure.in ============================================================================== --- python/branches/py3k-jit/configure.in (original) +++ python/branches/py3k-jit/configure.in Wed Jun 16 18:21:24 2010 @@ -330,9 +330,12 @@ # Marc Recht NetBSD/1.5 | NetBSD/1.5.* | NetBSD/1.6 | NetBSD/1.6.* | NetBSD/1.6@<:@A-S@:>@) define_xopen_source=no;; - # On Solaris 2.6, sys/wait.h is inconsistent in the usage - # of union __?sigval. Reported by Stuart Bishop. - SunOS/5.6) + # From the perspective of Solaris, _XOPEN_SOURCE is not so much a + # request to enable features supported by the standard as a request + # to disable features not supported by the standard. The best way + # for Python to use Solaris is simply to leave _XOPEN_SOURCE out + # entirely and define __EXTENSIONS__ instead. + SunOS/*) define_xopen_source=no;; # On UnixWare 7, u_long is never defined with _XOPEN_SOURCE, # but used in /usr/include/netinet/tcp.h. Reported by Tim Rice. @@ -378,35 +381,15 @@ if test $define_xopen_source = yes then - # On Solaris w/ g++ it appears that _XOPEN_SOURCE has to be - # defined precisely as g++ defines it - # Furthermore, on Solaris 10, XPG6 requires the use of a C99 - # compiler - case $ac_sys_system/$ac_sys_release in - SunOS/5.8|SunOS/5.9|SunOS/5.10) - AC_DEFINE(_XOPEN_SOURCE, 500, - Define to the level of X/Open that your system supports) - ;; - *) - AC_DEFINE(_XOPEN_SOURCE, 600, - Define to the level of X/Open that your system supports) - ;; - esac + AC_DEFINE(_XOPEN_SOURCE, 600, + Define to the level of X/Open that your system supports) # On Tru64 Unix 4.0F, defining _XOPEN_SOURCE also requires # definition of _XOPEN_SOURCE_EXTENDED and _POSIX_C_SOURCE, or else # several APIs are not declared. Since this is also needed in some # cases for HP-UX, we define it globally. - # except for Solaris 10, where it must not be defined, - # as it implies XPG4.2 - case $ac_sys_system/$ac_sys_release in - SunOS/5.10) - ;; - *) - AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, - Define to activate Unix95-and-earlier features) - ;; - esac + AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, + Define to activate Unix95-and-earlier features) AC_DEFINE(_POSIX_C_SOURCE, 200112L, Define to activate features from IEEE Stds 1003.1-2001) Modified: python/branches/py3k-jit/setup.py ============================================================================== --- python/branches/py3k-jit/setup.py (original) +++ python/branches/py3k-jit/setup.py Wed Jun 16 18:21:24 2010 @@ -14,6 +14,7 @@ from distutils.command.build_ext import build_ext from distutils.command.install import install from distutils.command.install_lib import install_lib +from distutils.spawn import find_executable # Were we compiled --with-pydebug or with #define Py_DEBUG? COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') @@ -28,6 +29,25 @@ if dir is not None and os.path.isdir(dir) and dir not in dirlist: dirlist.insert(0, dir) +def macosx_sdk_root(): + """ + Return the directory of the current OSX SDK, + or '/' if no SDK was specified. + """ + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + return sysroot + +def is_macosx_sdk_path(path): + """ + Returns True if 'path' can be located in an OSX SDK + """ + return path.startswith('/usr/') or path.startswith('/System/') + def find_file(filename, std_dirs, paths): """Searches for the directory where a given file is located, and returns a possibly-empty list of additional directories, or None @@ -39,15 +59,28 @@ 'paths' is a list of additional locations to check; if the file is found in one of them, the resulting list will contain the directory. """ + if sys.platform == 'darwin': + # Honor the MacOSX SDK setting when one was specified. + # An SDK is a directory with the same structure as a real + # system, but with only header files and libraries. + sysroot = macosx_sdk_root() # Check the standard locations for dir in std_dirs: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [] # Check the additional directories for dir in paths: f = os.path.join(dir, filename) + + if sys.platform == 'darwin' and is_macosx_sdk_path(dir): + f = os.path.join(sysroot, dir[1:], filename) + if os.path.exists(f): return [dir] @@ -59,11 +92,19 @@ if result is None: return None + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + # Check whether the found file is in one of the standard directories dirname = os.path.dirname(result) for p in std_dirs: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ ] + if p == dirname: return [ ] @@ -72,6 +113,11 @@ for p in paths: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) + + if sys.platform == 'darwin' and is_macosx_sdk_path(p): + if os.path.join(sysroot, p[1:]) == dirname: + return [ p ] + if p == dirname: return [p] else: @@ -480,6 +526,38 @@ # readline do_readline = self.compiler_obj.find_library_file(lib_dirs, 'readline') + readline_termcap_library = "" + curses_library = "" + # Determine if readline is already linked against curses or tinfo. + if do_readline and find_executable('ldd'): + # Cannot use os.popen here in py3k. + tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) + os.system("ldd %s > %s" % (do_readline, tmpfile)) + fp = open(tmpfile) + for ln in fp: + if 'curses' in ln: + readline_termcap_library = re.sub( + r'.*lib(n?cursesw?)\.so.*', r'\1', ln + ).rstrip() + break + if 'tinfo' in ln: # termcap interface split out from ncurses + readline_termcap_library = 'tinfo' + break + fp.close() + os.unlink(tmpfile) + # Issue 7384: If readline is already linked against curses, + # use the same library for the readline and curses modules. + if 'curses' in readline_termcap_library: + curses_library = readline_termcap_library + elif self.compiler_obj.find_library_file(lib_dirs, 'ncursesw'): + curses_library = 'ncursesw' + elif self.compiler_obj.find_library_file(lib_dirs, 'ncurses'): + curses_library = 'ncurses' + elif self.compiler_obj.find_library_file(lib_dirs, 'curses'): + curses_library = 'curses' + if platform == 'darwin': os_release = int(os.uname()[2].split('.')[0]) dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') @@ -497,20 +575,16 @@ # library and then a static library, instead of first looking # for dynamic libraries on the entire path. # This way a staticly linked custom readline gets picked up - # before the (broken) dynamic library in /usr/lib. + # before the (possibly broken) dynamic library in /usr/lib. readline_extra_link_args = ('-Wl,-search_paths_first',) else: readline_extra_link_args = () readline_libs = ['readline'] - if self.compiler_obj.find_library_file(lib_dirs, - 'ncursesw'): - readline_libs.append('ncursesw') - elif self.compiler_obj.find_library_file(lib_dirs, - 'ncurses'): - readline_libs.append('ncurses') - elif self.compiler_obj.find_library_file(lib_dirs, 'curses'): - readline_libs.append('curses') + if readline_termcap_library: + pass # Issue 7384: Already linked against curses or tinfo. + elif curses_library: + readline_libs.append(curses_library) elif self.compiler_obj.find_library_file(lib_dirs + ['/usr/lib/termcap'], 'termcap'): @@ -571,22 +645,23 @@ openssl_ver = 0 openssl_ver_re = re.compile( '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' ) - for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in: - name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h') - if os.path.isfile(name): - try: - incfile = open(name, 'r') - for line in incfile: - m = openssl_ver_re.match(line) - if m: - openssl_ver = eval(m.group(1)) - break - except IOError: - pass - # first version found is what we'll use (as the compiler should) - if openssl_ver: - break + # look for the openssl version header on the compiler search path. + opensslv_h = find_file('openssl/opensslv.h', [], + inc_dirs + search_for_ssl_incs_in) + if opensslv_h: + name = os.path.join(opensslv_h[0], 'openssl/opensslv.h') + if sys.platform == 'darwin' and is_macosx_sdk_path(name): + name = os.path.join(macosx_sdk_root(), name[1:]) + try: + incfile = open(name, 'r') + for line in incfile: + m = openssl_ver_re.match(line) + if m: + openssl_ver = eval(m.group(1)) + except IOError as msg: + print("IOError while reading opensshv.h:", msg) + pass #print('openssl_ver = 0x%08x' % openssl_ver) min_openssl_ver = 0x00907000 @@ -715,12 +790,18 @@ db_ver_inc_map = {} + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + class db_found(Exception): pass try: # See whether there is a Sleepycat header in the standard # search path. for d in inc_dirs + db_inc_paths: f = os.path.join(d, "db.h") + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "db.h") + if db_setup_debug: print("db: looking for db.h in", f) if os.path.exists(f): f = open(f, "rb").read() @@ -767,7 +848,22 @@ db_incdir.replace("include", 'lib64'), db_incdir.replace("include", 'lib'), ] - db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + if sys.platform != 'darwin': + db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + else: + # Same as other branch, but takes OSX SDK into account + tmp = [] + for dn in db_dirs_to_check: + if is_macosx_sdk_path(dn): + if os.path.isdir(os.path.join(sysroot, dn[1:])): + tmp.append(dn) + else: + if os.path.isdir(dn): + tmp.append(dn) + + db_dirs_to_check = tmp # Look for a version specific db-X.Y before an ambiguoius dbX # XXX should we -ever- look for a dbX name? Do any @@ -816,8 +912,15 @@ # Scan the default include directories before the SQLite specific # ones. This allows one to override the copy of sqlite on OSX, # where /usr/include contains an old version of sqlite. + if sys.platform == 'darwin': + sysroot = macosx_sdk_root() + for d in inc_dirs + sqlite_inc_paths: f = os.path.join(d, "sqlite3.h") + + if sys.platform == 'darwin' and is_macosx_sdk_path(d): + f = os.path.join(sysroot, d[1:], "sqlite3.h") + if os.path.exists(f): if sqlite_setup_debug: print("sqlite: found %s"%f) incf = open(f).read() @@ -996,19 +1099,15 @@ # Curses support, requiring the System V version of curses, often # provided by the ncurses library. panel_library = 'panel' - if (self.compiler_obj.find_library_file(lib_dirs, 'ncursesw')): - curses_libs = ['ncursesw'] - # Bug 1464056: If _curses.so links with ncursesw, - # _curses_panel.so must link with panelw. - panel_library = 'panelw' + if curses_library.startswith('ncurses'): + if curses_library == 'ncursesw': + # Bug 1464056: If _curses.so links with ncursesw, + # _curses_panel.so must link with panelw. + panel_library = 'panelw' + curses_libs = [curses_library] exts.append( Extension('_curses', ['_cursesmodule.c'], libraries = curses_libs) ) - elif (self.compiler_obj.find_library_file(lib_dirs, 'ncurses')): - curses_libs = ['ncurses'] - exts.append( Extension('_curses', ['_cursesmodule.c'], - libraries = curses_libs) ) - elif (self.compiler_obj.find_library_file(lib_dirs, 'curses') - and platform != 'darwin'): + elif curses_library == 'curses' and platform != 'darwin': # OSX has an old Berkeley curses, not good enough for # the _curses module. if (self.compiler_obj.find_library_file(lib_dirs, 'terminfo')): @@ -1253,14 +1352,22 @@ join(os.getenv('HOME'), '/Library/Frameworks') ] + sysroot = macosx_sdk_root() + # Find the directory that contains the Tcl.framework and Tk.framework # bundles. # XXX distutils should support -F! for F in framework_dirs: # both Tcl.framework and Tk.framework should be present + + for fw in 'Tcl', 'Tk': - if not exists(join(F, fw + '.framework')): - break + if is_macosx_sdk_path(F): + if not exists(join(sysroot, F[1:], fw + '.framework')): + break + else: + if not exists(join(F, fw + '.framework')): + break else: # ok, F is now directory with both frameworks. Continure # building @@ -1297,8 +1404,12 @@ # Note: cannot use os.popen or subprocess here, that # requires extensions that are not available here. - os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) + if is_macosx_sdk_path(F): + os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(os.path.join(sysroot, F[1:]), tmpfile)) + else: + os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) fp = open(tmpfile) + detected_archs = [] for ln in fp: a = ln.split()[-1] From python-checkins at python.org Wed Jun 16 18:41:11 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 16 Jun 2010 18:41:11 +0200 (CEST) Subject: [Python-checkins] r82022 - in python/branches/py3k: Doc/library/http.server.rst Message-ID: <20100616164111.66541EEC76@mail.python.org> Author: senthil.kumaran Date: Wed Jun 16 18:41:11 2010 New Revision: 82022 Log: Merged revisions 82018 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82018 | senthil.kumaran | 2010-06-16 20:25:31 +0530 (Wed, 16 Jun 2010) | 3 lines Fix Issue8937 - SimpleHTTPServer should contain usage example ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/http.server.rst Modified: python/branches/py3k/Doc/library/http.server.rst ============================================================================== --- python/branches/py3k/Doc/library/http.server.rst (original) +++ python/branches/py3k/Doc/library/http.server.rst Wed Jun 16 18:41:11 2010 @@ -281,8 +281,30 @@ contents of the file are output. If the file's MIME type starts with ``text/`` the file is opened in text mode; otherwise binary mode is used. - For example usage, see the implementation of the :func:`test` function. + For example usage, see the implementation of the :func:`test` function + invocation in the :mod:`http.server` module. +The :class:`SimpleHTTPRequestHandler` class can be invoked the following manner +with the :mod:`http.server` to create a very basic webserver serving files +relative to the current directory.:: + + import http.server + import socketserver + + PORT = 8000 + + Handler = http.server.SimpleHTTPRequestHandler + + httpd = socketserver.TCPServer(("", PORT), Handler) + + print("serving at port", PORT) + httpd.serve_forever() + +:mod:`http.server` can also be invoked directly using the ``-m`` switch of +interpreter a with ``port number`` argument which interfaces +:class:`SimpleHTTPRequestHandler` by default.:: + + python -m http.server 8000 .. class:: CGIHTTPRequestHandler(request, client_address, server) From python-checkins at python.org Wed Jun 16 18:44:15 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 16 Jun 2010 18:44:15 +0200 (CEST) Subject: [Python-checkins] r82023 - in python/branches/release31-maint: Doc/library/http.server.rst Message-ID: <20100616164415.8A53EEEC6D@mail.python.org> Author: senthil.kumaran Date: Wed Jun 16 18:44:15 2010 New Revision: 82023 Log: Merged revisions 82022 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r82022 | senthil.kumaran | 2010-06-16 22:11:11 +0530 (Wed, 16 Jun 2010) | 9 lines Merged revisions 82018 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82018 | senthil.kumaran | 2010-06-16 20:25:31 +0530 (Wed, 16 Jun 2010) | 3 lines Fix Issue8937 - SimpleHTTPServer should contain usage example ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/http.server.rst Modified: python/branches/release31-maint/Doc/library/http.server.rst ============================================================================== --- python/branches/release31-maint/Doc/library/http.server.rst (original) +++ python/branches/release31-maint/Doc/library/http.server.rst Wed Jun 16 18:44:15 2010 @@ -281,8 +281,30 @@ contents of the file are output. If the file's MIME type starts with ``text/`` the file is opened in text mode; otherwise binary mode is used. - For example usage, see the implementation of the :func:`test` function. + For example usage, see the implementation of the :func:`test` function + invocation in the :mod:`http.server` module. +The :class:`SimpleHTTPRequestHandler` class can be invoked the following manner +with the :mod:`http.server` to create a very basic webserver serving files +relative to the current directory.:: + + import http.server + import socketserver + + PORT = 8000 + + Handler = http.server.SimpleHTTPRequestHandler + + httpd = socketserver.TCPServer(("", PORT), Handler) + + print("serving at port", PORT) + httpd.serve_forever() + +:mod:`http.server` can also be invoked directly using the ``-m`` switch of +interpreter a with ``port number`` argument which interfaces +:class:`SimpleHTTPRequestHandler` by default.:: + + python -m http.server 8000 .. class:: CGIHTTPRequestHandler(request, client_address, server) From python-checkins at python.org Wed Jun 16 19:03:29 2010 From: python-checkins at python.org (mark.dickinson) Date: Wed, 16 Jun 2010 19:03:29 +0200 (CEST) Subject: [Python-checkins] r82024 - python/branches/py3k-dtoa Message-ID: <20100616170329.2C5D7EEC76@mail.python.org> Author: mark.dickinson Date: Wed Jun 16 19:03:29 2010 New Revision: 82024 Log: Create new branch to work on improving Python/dtoa.c. (Issue #9009.) Added: python/branches/py3k-dtoa/ - copied from r82023, /python/branches/py3k/ From rdmurray at bitdance.com Wed Jun 16 19:15:51 2010 From: rdmurray at bitdance.com (R. David Murray) Date: Wed, 16 Jun 2010 13:15:51 -0400 Subject: [Python-checkins] r82018 - python/trunk/Doc/library/simplehttpserver.rst In-Reply-To: <20100616145531.CDB47EE9BB@mail.python.org> References: <20100616145531.CDB47EE9BB@mail.python.org> Message-ID: <20100616171551.8D0191F9DE3@kimball.webabinitio.net> On Wed, 16 Jun 2010 16:55:31 +0200, senthil.kumaran wrote: > Author: senthil.kumaran > Date: Wed Jun 16 16:55:31 2010 > New Revision: 82018 > > Log: > Fix Issue8937 - SimpleHTTPServer should contain usage example > > > Modified: > python/trunk/Doc/library/simplehttpserver.rst > > Modified: python/trunk/Doc/library/simplehttpserver.rst > ============================================================================== > --- python/trunk/Doc/library/simplehttpserver.rst (original) > +++ python/trunk/Doc/library/simplehttpserver.rst Wed Jun 16 16:55:31 2010 > @@ -81,12 +81,34 @@ > contents of the file are output. If the file's MIME type starts with > ``text/`` the file is opened in text mode; otherwise binary mode is used. > > - For example usage, see the implementation of the :func:`test` function. > + The :func:`test` function in the :mod:`SimpleHTTPServer` module is an > + example which interfaces the :class:`SimpleHTTPRequestHandler` as a > + Handler to the :mod:`BaseHTTPServer` module. I don't think this is correct English ("which interfaces the SimpleHTTPRequestHandler as a Handler..."), because I'm not sure what the meaning is. Do you mean something like "which creates a server using the BaseHTTPServer module, using SimpleHTTPRequestHandler as a Handler"? > .. versionadded:: 2.5 > The ``'Last-Modified'`` header. > > > +The :mod:`SimpleHTTPServer` module can be used the following manner in order to > +setup a very basic web server serving files relative to the current directory.:: setup should be two words in this context ("set up"). > + > + import SimpleHTTPServer > + import SocketServer > + > + PORT = 8000 > + > + Handler = SimpleHTTPServer.SimpleHTTPRequestHandler > + > + httpd = SocketServer.TCPServer(("", PORT), Handler) > + > + print "serving at port", PORT > + httpd.serve_forever() > + > +It can also be invoked directly using the ``-m`` switch of interpreter a with It is not clear what "It" is here. I think you mean "the SimpleHTTPServer module", but as written it could equally well be the example code above it. It also isn't clear (from these docs) what *happens* when you execute the example line below. Does it serve files relative to the current directly, like the preceding example? > +``port number`` argument.:: > + > + python -m SimpleHTTPServer 8000 > + > .. seealso:: > > Module :mod:`BaseHTTPServer` > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins From orsenthil at gmail.com Wed Jun 16 19:23:34 2010 From: orsenthil at gmail.com (Senthil Kumaran) Date: Wed, 16 Jun 2010 22:53:34 +0530 Subject: [Python-checkins] r82018 - python/trunk/Doc/library/simplehttpserver.rst In-Reply-To: <20100616171551.8D0191F9DE3@kimball.webabinitio.net> References: <20100616145531.CDB47EE9BB@mail.python.org> <20100616171551.8D0191F9DE3@kimball.webabinitio.net> Message-ID: <20100616172333.GA7278@remy> On Wed, Jun 16, 2010 at 01:15:51PM -0400, R. David Murray wrote: > I don't think this is correct English ("which interfaces the > SimpleHTTPRequestHandler as a Handler..."), because I'm not sure what the > meaning is. Do you mean something like "which creates a server using > the BaseHTTPServer module, using SimpleHTTPRequestHandler as a Handler"? I shall correct it along the lines you mentioned. I had a doubt when I wrote that sentence. I meant, SimpleHTTPRequestHandler is assigned to the Handler argument of the BaseHTTPServer. > setup should be two words in this context ("set up"). > Okay. > > + > > +It can also be invoked directly using the ``-m`` switch of interpreter a with > > It is not clear what "It" is here. I think you mean "the SimpleHTTPServer > module", but as written it could equally well be the example code > above it. It also isn't clear (from these docs) what *happens* when > you execute the example line below. Does it serve files relative to > the current directly, like the preceding example? > Yes, I wrote as a continuation to the previous example. But It can be improved as you pointed out. I have it slightly changed in the py3k version where I explicitly mentioned the module name. Thanks for the comments. -- Senthil Pascal Users: To show respect for the 313th anniversary (tomorrow) of the death of Blaise Pascal, your programs will be run at half speed. From python-checkins at python.org Wed Jun 16 19:29:03 2010 From: python-checkins at python.org (mark.dickinson) Date: Wed, 16 Jun 2010 19:29:03 +0200 (CEST) Subject: [Python-checkins] r82025 - python/branches/py3k-dtoa/Python/dtoa.c Message-ID: <20100616172903.42694EEC71@mail.python.org> Author: mark.dickinson Date: Wed Jun 16 19:29:03 2010 New Revision: 82025 Log: Issue #9009: In _Py_dg_strtod, have 'e' refer to the adjusted exponent of the input, not the base exponent. This is a preliminary refactoring which makes it easier to break out the parsing code. Modified: python/branches/py3k-dtoa/Python/dtoa.c Modified: python/branches/py3k-dtoa/Python/dtoa.c ============================================================================== --- python/branches/py3k-dtoa/Python/dtoa.c (original) +++ python/branches/py3k-dtoa/Python/dtoa.c Wed Jun 16 19:29:03 2010 @@ -1384,7 +1384,7 @@ nd = bc->nd; nd0 = bc->nd0; - p5 = nd + bc->e0; + p5 = bc->e0; b = sd2b(rv, bc->scale, &p2); if (b == NULL) return -1; @@ -1600,7 +1600,7 @@ } /* Adjust exponent to take into account position of the point. */ - e -= nd - nd0; + e += nd0; if (nd0 <= 0) nd0 = nd; @@ -1619,7 +1619,6 @@ break; } } - e += nd - i; nd = i; if (nd0 > nd) nd0 = nd; @@ -1641,7 +1640,7 @@ * nd0 == nd, then s0[nd0] could be any non-digit character.) * * - e is the adjusted exponent: the absolute value of the number - * represented by the original input string is n * 10**e, where + * represented by the original input string is n * 10**(e - nd), where * n is the integer represented by the concatenation of * s0[0:nd0] and s0[nd0+1:nd+1] * @@ -1660,7 +1659,7 @@ * gives the value represented by the first min(16, nd) sig. digits. */ - bc.e0 = e1 = e; + bc.e0 = e; y = z = 0; for (i = 0; i < nd; i++) { if (i < 9) @@ -1677,33 +1676,32 @@ dval(&rv) = tens[k - 9] * dval(&rv) + z; } bd0 = 0; + e1 = e - k; if (nd <= DBL_DIG && Flt_Rounds == 1 ) { - if (!e) + if (!e1) goto ret; - if (e > 0) { - if (e <= Ten_pmax) { - dval(&rv) *= tens[e]; + if (e1 > 0) { + if (e1 <= Ten_pmax) { + dval(&rv) *= tens[e1]; goto ret; } i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { + if (e1 - i <= Ten_pmax) { /* A fancier test would sometimes let us do * this for larger i values. */ - e -= i; dval(&rv) *= tens[i]; - dval(&rv) *= tens[e]; + dval(&rv) *= tens[e1 - i]; goto ret; } } - else if (e >= -Ten_pmax) { - dval(&rv) /= tens[-e]; + else if (-e1 <= -Ten_pmax) { + dval(&rv) /= tens[-e1]; goto ret; } } - e1 += nd - k; bc.scale = 0; @@ -1800,7 +1798,6 @@ break; } } - e += nd - i; nd = i; if (nd0 > nd) nd0 = nd; @@ -1869,12 +1866,12 @@ goto failed_malloc; } - if (e >= 0) { + if (e >= nd) { bb2 = bb5 = 0; - bd2 = bd5 = e; + bd2 = bd5 = e - nd; } else { - bb2 = bb5 = -e; + bb2 = bb5 = nd - e; bd2 = bd5 = 0; } if (bbe >= 0) From python-checkins at python.org Wed Jun 16 19:37:32 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 16 Jun 2010 19:37:32 +0200 (CEST) Subject: [Python-checkins] r82026 - python/trunk/Doc/library/simplehttpserver.rst Message-ID: <20100616173732.A7D05EEC57@mail.python.org> Author: senthil.kumaran Date: Wed Jun 16 19:37:32 2010 New Revision: 82026 Log: Addressing RDM's review comments on the doc change. Modified: python/trunk/Doc/library/simplehttpserver.rst Modified: python/trunk/Doc/library/simplehttpserver.rst ============================================================================== --- python/trunk/Doc/library/simplehttpserver.rst (original) +++ python/trunk/Doc/library/simplehttpserver.rst Wed Jun 16 19:37:32 2010 @@ -82,15 +82,16 @@ ``text/`` the file is opened in text mode; otherwise binary mode is used. The :func:`test` function in the :mod:`SimpleHTTPServer` module is an - example which interfaces the :class:`SimpleHTTPRequestHandler` as a - Handler to the :mod:`BaseHTTPServer` module. + example which creates a server using the + :class:`SimpleHTTPRequestHandler` as the Handler. .. versionadded:: 2.5 The ``'Last-Modified'`` header. The :mod:`SimpleHTTPServer` module can be used the following manner in order to -setup a very basic web server serving files relative to the current directory.:: +set up a very basic web server serving files relative to the current +directory.:: import SimpleHTTPServer import SocketServer @@ -104,8 +105,9 @@ print "serving at port", PORT httpd.serve_forever() -It can also be invoked directly using the ``-m`` switch of interpreter a with -``port number`` argument.:: +:mod:`SimpleHTTPServer` module can also be invoked directly using the ``-m`` +switch of interpreter with a ``port number`` argument. Similar to previous +example, this serves the files relative to the current directory.:: python -m SimpleHTTPServer 8000 From python-checkins at python.org Wed Jun 16 19:39:51 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 16 Jun 2010 19:39:51 +0200 (CEST) Subject: [Python-checkins] r82027 - in python/branches/release26-maint: Doc/library/simplehttpserver.rst Message-ID: <20100616173951.D87E1EEC97@mail.python.org> Author: senthil.kumaran Date: Wed Jun 16 19:39:51 2010 New Revision: 82027 Log: Merged revisions 82026 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82026 | senthil.kumaran | 2010-06-16 23:07:32 +0530 (Wed, 16 Jun 2010) | 3 lines Addressing RDM's review comments on the doc change. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/simplehttpserver.rst Modified: python/branches/release26-maint/Doc/library/simplehttpserver.rst ============================================================================== --- python/branches/release26-maint/Doc/library/simplehttpserver.rst (original) +++ python/branches/release26-maint/Doc/library/simplehttpserver.rst Wed Jun 16 19:39:51 2010 @@ -82,15 +82,16 @@ ``text/`` the file is opened in text mode; otherwise binary mode is used. The :func:`test` function in the :mod:`SimpleHTTPServer` module is an - example which interfaces the :class:`SimpleHTTPRequestHandler` as a - Handler to the :mod:`BaseHTTPServer` module. + example which creates a server using the + :class:`SimpleHTTPRequestHandler` as the Handler. .. versionadded:: 2.5 The ``'Last-Modified'`` header. The :mod:`SimpleHTTPServer` module can be used the following manner in order to -setup a very basic web server serving files relative to the current directory.:: +set up a very basic web server serving files relative to the current +directory.:: import SimpleHTTPServer import SocketServer @@ -104,8 +105,9 @@ print "serving at port", PORT httpd.serve_forever() -It can also be invoked directly using the ``-m`` switch of interpreter a with -``port number`` argument.:: +:mod:`SimpleHTTPServer` module can also be invoked directly using the ``-m`` +switch of interpreter with a ``port number`` argument. Similar to previous +example, this serves the files relative to the current directory.:: python -m SimpleHTTPServer 8000 From python-checkins at python.org Wed Jun 16 19:44:58 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 16 Jun 2010 19:44:58 +0200 (CEST) Subject: [Python-checkins] r82028 - in python/branches/py3k: Doc/library/http.server.rst Message-ID: <20100616174458.0F07DEECBA@mail.python.org> Author: senthil.kumaran Date: Wed Jun 16 19:44:57 2010 New Revision: 82028 Log: Merged revisions 82026 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82026 | senthil.kumaran | 2010-06-16 23:07:32 +0530 (Wed, 16 Jun 2010) | 3 lines Addressing RDM's review comments on the doc change. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/http.server.rst Modified: python/branches/py3k/Doc/library/http.server.rst ============================================================================== --- python/branches/py3k/Doc/library/http.server.rst (original) +++ python/branches/py3k/Doc/library/http.server.rst Wed Jun 16 19:44:57 2010 @@ -301,8 +301,10 @@ httpd.serve_forever() :mod:`http.server` can also be invoked directly using the ``-m`` switch of -interpreter a with ``port number`` argument which interfaces -:class:`SimpleHTTPRequestHandler` by default.:: +interpreter a with ``port number`` argument which uses +:class:`SimpleHTTPRequestHandler` as the default request Handler. Similar to +the previous example, even this serves files relative to the current +directory.:: python -m http.server 8000 From python-checkins at python.org Wed Jun 16 19:47:48 2010 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 16 Jun 2010 19:47:48 +0200 (CEST) Subject: [Python-checkins] r82029 - in python/branches/release31-maint: Doc/library/http.server.rst Message-ID: <20100616174748.83E9CEEC71@mail.python.org> Author: senthil.kumaran Date: Wed Jun 16 19:47:48 2010 New Revision: 82029 Log: Merged revisions 82028 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r82028 | senthil.kumaran | 2010-06-16 23:14:57 +0530 (Wed, 16 Jun 2010) | 9 lines Merged revisions 82026 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82026 | senthil.kumaran | 2010-06-16 23:07:32 +0530 (Wed, 16 Jun 2010) | 3 lines Addressing RDM's review comments on the doc change. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/http.server.rst Modified: python/branches/release31-maint/Doc/library/http.server.rst ============================================================================== --- python/branches/release31-maint/Doc/library/http.server.rst (original) +++ python/branches/release31-maint/Doc/library/http.server.rst Wed Jun 16 19:47:48 2010 @@ -301,8 +301,10 @@ httpd.serve_forever() :mod:`http.server` can also be invoked directly using the ``-m`` switch of -interpreter a with ``port number`` argument which interfaces -:class:`SimpleHTTPRequestHandler` by default.:: +interpreter a with ``port number`` argument which uses +:class:`SimpleHTTPRequestHandler` as the default request Handler. Similar to +the previous example, even this serves files relative to the current +directory.:: python -m http.server 8000 From python-checkins at python.org Wed Jun 16 19:58:15 2010 From: python-checkins at python.org (collin.winter) Date: Wed, 16 Jun 2010 19:58:15 +0200 (CEST) Subject: [Python-checkins] r82030 - in python/branches/py3k-jit: Doc/c-api/file.rst Doc/library/datetime.rst Doc/library/doctest.rst Doc/library/struct.rst Lib/distutils/command/install.py Lib/email/feedparser.py Lib/email/test/test_email.py Lib/sysconfig.py Lib/test/regrtest.py Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c Message-ID: <20100616175815.9BF38EEC97@mail.python.org> Author: collin.winter Date: Wed Jun 16 19:58:15 2010 New Revision: 82030 Log: Merged revisions 81990,81994,81999-82001,82003-82005,82008,82011,82014-82015 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r81990 | brett.cannon | 2010-06-14 15:22:54 -0700 (Mon, 14 Jun 2010) | 5 lines Switch the __import__ state check from using __builtins__ to builtins to be nicer to other VMs. Thanks to Philip Jenvey for the pointer. ................ r81994 | mark.dickinson | 2010-06-15 01:42:37 -0700 (Tue, 15 Jun 2010) | 10 lines Merged revisions 81992 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81992 | mark.dickinson | 2010-06-15 09:33:03 +0100 (Tue, 15 Jun 2010) | 3 lines Issue #8469: Further clarifications and improvements to struct module documentation. Thanks Mads Kiilerich. ........ ................ r81999 | ronald.oussoren | 2010-06-15 09:05:20 -0700 (Tue, 15 Jun 2010) | 5 lines Fix for issue #8577: without this patch test_distutils will fail when builddir != srcdir (that is, when you run configure in a directory that is not the top of the source tree). ................ r82000 | antoine.pitrou | 2010-06-15 10:00:21 -0700 (Tue, 15 Jun 2010) | 3 lines Fixes to the PyFile_FromFd() doc, by Renato Cunha. ................ r82001 | antoine.pitrou | 2010-06-15 10:30:16 -0700 (Tue, 15 Jun 2010) | 3 lines Further refinements to the C file API. ................ r82003 | alexander.belopolsky | 2010-06-15 11:40:23 -0700 (Tue, 15 Jun 2010) | 1 line Minor changes to the choice of assert methods ................ r82004 | alexander.belopolsky | 2010-06-15 12:24:52 -0700 (Tue, 15 Jun 2010) | 1 line Issue 5094: minor documentation fixes ................ r82005 | ronald.oussoren | 2010-06-15 14:19:50 -0700 (Tue, 15 Jun 2010) | 3 lines Fix for buildbot failure in r81999. ................ r82008 | r.david.murray | 2010-06-15 16:46:40 -0700 (Tue, 15 Jun 2010) | 9 lines Merged revisions 81634 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81634 | r.david.murray | 2010-05-31 21:42:41 -0400 (Mon, 31 May 2010) | 2 lines #7583: clarify discussion of hard tab expansion in doctests. ........ ................ r82011 | r.david.murray | 2010-06-15 19:19:40 -0700 (Tue, 15 Jun 2010) | 17 lines Merged revisions 81675 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r81675 | r.david.murray | 2010-06-03 11:43:20 -0400 (Thu, 03 Jun 2010) | 10 lines #5610: use \Z not $ so we don't eat extra chars when body part ends with \r\n. If a body part ended with \r\n, feedparser, using '$' to terminate its search for the newline, would match on the \r\n, and think that it needed to strip two characters in order to account for the line end before the boundary. That made it chop one too many characters off the end of the body part. Using \Z makes the match correct. Patch and test by Tony Nelson. ........ ................ r82014 | r.david.murray | 2010-06-16 05:53:07 -0700 (Wed, 16 Jun 2010) | 20 lines Blocked revisions 81571,81678 via svnmerge I'm going to merge 81678 by hand. ........ r81571 | victor.stinner | 2010-05-27 18:29:48 -0400 (Thu, 27 May 2010) | 3 lines Issue #8835: test_support.transient_internet() catchs gaierror(EAI_NONAME) and gaierror(EAI_NODATA) ........ r81678 | r.david.murray | 2010-06-03 16:19:25 -0400 (Thu, 03 Jun 2010) | 7 lines #8889: rewrite transient_internet so we don't use EAI_NODATA on FreeBSD. FreeBSD doesn't have socket.EAI_NODATA. I rewrote the routine because there's no easy way to conditionally include a context manager in a with statement. As a side benefit, instead of a stack of context managers there's now only one. ........ ................ r82015 | r.david.murray | 2010-06-16 05:56:31 -0700 (Wed, 16 Jun 2010) | 2 lines Remove versionadded accidentally introduced by r82008. ................ Modified: python/branches/py3k-jit/ (props changed) python/branches/py3k-jit/Doc/c-api/file.rst python/branches/py3k-jit/Doc/library/datetime.rst python/branches/py3k-jit/Doc/library/doctest.rst python/branches/py3k-jit/Doc/library/struct.rst python/branches/py3k-jit/Lib/distutils/command/install.py python/branches/py3k-jit/Lib/email/feedparser.py python/branches/py3k-jit/Lib/email/test/test_email.py python/branches/py3k-jit/Lib/sysconfig.py python/branches/py3k-jit/Lib/test/regrtest.py python/branches/py3k-jit/Lib/test/test_datetime.py python/branches/py3k-jit/Misc/NEWS python/branches/py3k-jit/Modules/datetimemodule.c Modified: python/branches/py3k-jit/Doc/c-api/file.rst ============================================================================== --- python/branches/py3k-jit/Doc/c-api/file.rst (original) +++ python/branches/py3k-jit/Doc/c-api/file.rst Wed Jun 16 19:58:15 2010 @@ -7,24 +7,29 @@ .. index:: object: file -Python's built-in file objects are implemented entirely on the :ctype:`FILE\*` -support from the C standard library. This is an implementation detail and may -change in future releases of Python. The ``PyFile_`` APIs are a wrapper over -the :mod:`io` module. - - -.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *newline, int closefd) - - Create a new :ctype:`PyFileObject` from the file descriptor of an already - opened file *fd*. The arguments *name*, *encoding* and *newline* can be - *NULL* to use the defaults; *buffering* can be *-1* to use the default. - Return *NULL* on failure. +These APIs are a minimal emulation of the Python 2 C API for built-in file +objects, which used to rely on the buffered I/O (:ctype:`FILE\*`) support +from the C standard library. In Python 3, files and streams use the new +:mod:`io` module, which defines several layers over the low-level unbuffered +I/O of the operating system. The functions described below are +convenience C wrappers over these new APIs, and meant mostly for internal +error reporting in the interpreter; third-party code is advised to access +the :mod:`io` APIs instead. + + +.. cfunction:: PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd) + + Create a Python file object from the file descriptor of an already + opened file *fd*. The arguments *name*, *encoding*, *errors* and *newline* + can be *NULL* to use the defaults; *buffering* can be *-1* to use the + default. Return *NULL* on failure. For a more comprehensive description of + the arguments, please refer to the :func:`io.open` function documentation. .. warning:: - Take care when you are mixing streams and descriptors! For more - information, see `the GNU C Library docs - `_. + Since Python streams have their own buffering layer, mixing them with + OS-level file descriptors can produce various issues (such as unexpected + ordering of data). .. cfunction:: int PyObject_AsFileDescriptor(PyObject *p) Modified: python/branches/py3k-jit/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/datetime.rst (original) +++ python/branches/py3k-jit/Doc/library/datetime.rst Wed Jun 16 19:58:15 2010 @@ -1351,7 +1351,7 @@ :mod:`datetime` objects. If in doubt, simply implement all of them. -.. method:: tzinfo.utcoffset(self, dt) +.. method:: tzinfo.utcoffset(dt) Return offset of local time from UTC, in minutes east of UTC. If local time is west of UTC, this should be negative. Note that this is intended to be the @@ -1373,7 +1373,7 @@ :exc:`NotImplementedError`. -.. method:: tzinfo.dst(self, dt) +.. method:: tzinfo.dst(dt) Return the daylight saving time (DST) adjustment, in minutes east of UTC, or ``None`` if DST information isn't known. Return ``timedelta(0)`` if DST is not @@ -1421,7 +1421,7 @@ The default implementation of :meth:`dst` raises :exc:`NotImplementedError`. -.. method:: tzinfo.tzname(self, dt) +.. method:: tzinfo.tzname(dt) Return the time zone name corresponding to the :class:`datetime` object *dt*, as a string. Nothing about string names is defined by the :mod:`datetime` module, @@ -1457,7 +1457,7 @@ There is one more :class:`tzinfo` method that a subclass may wish to override: -.. method:: tzinfo.fromutc(self, dt) +.. method:: tzinfo.fromutc(dt) This is called from the default :class:`datetime.astimezone()` implementation. When called from that, ``dt.tzinfo`` is *self*, and *dt*'s date and time members @@ -1553,46 +1553,46 @@ .. class:: timezone(offset[, name]) - The ``offset`` argument must be specified as a :class:`timedelta` + The *offset* argument must be specified as a :class:`timedelta` object representing the difference between the local time and UTC. It must - be within the range [``-timedelta(hours=23, minutes=59), - ``timedelta(hours=23, minutes=59)``] and represent whole number of minutes, + be strictly between ``-timedelta(hours=24)`` and + ``timedelta(hours=24)`` and represent a whole number of minutes, otherwise :exc:`ValueError` is raised. - The ``name`` argument is optional. If specified it must be a string that - used as the value returned by the ``tzname(dt)`` method. Otherwise, + The *name* argument is optional. If specified it must be a string that + is used as the value returned by the ``tzname(dt)`` method. Otherwise, ``tzname(dt)`` returns a string 'UTCsHH:MM', where s is the sign of - ``offset``, HH and MM are two digits of ``offset.hours`` and + *offset*, HH and MM are two digits of ``offset.hours`` and ``offset.minutes`` respectively. -.. method:: timezone.utcoffset(self, dt) +.. method:: timezone.utcoffset(dt) - Returns the fixed value specified when the :class:`timezone` instance is - constructed. The ``dt`` argument is ignored. The return value is a + Return the fixed value specified when the :class:`timezone` instance is + constructed. The *dt* argument is ignored. The return value is a :class:`timedelta` instance equal to the difference between the local time and UTC. -.. method:: timezone.tzname(self, dt) +.. method:: timezone.tzname(dt) - Returns the fixed value specified when the :class:`timezone` instance is + Return the fixed value specified when the :class:`timezone` instance is constructed or a string 'UTCsHH:MM', where s is the sign of - ``offset``, HH and MM are two digits of ``offset.hours`` and - ``offset.minutes`` respectively. The ``dt`` argument is ignored. + *offset*, HH and MM are two digits of ``offset.hours`` and + ``offset.minutes`` respectively. -.. method:: timezone.dst(self, dt) +.. method:: timezone.dst(dt) Always returns ``None``. -.. method:: timezone.fromutc(self, dt) +.. method:: timezone.fromutc(dt) - Returns ``dt + offset``. The ``dt`` argument must be aware with ``tzinfo`` - set to ``self``. + Return ``dt + offset``. The *dt* argument must be an aware + :class:`datetime` instance, with ``tzinfo`` set to ``self``. Class attributes: .. attribute:: timezone.utc - The UTC timezone, ``timezone(0, 'UTC')``. + The UTC timezone, ``timezone(timedelta(0))``. .. _strftime-strptime-behavior: Modified: python/branches/py3k-jit/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/doctest.rst (original) +++ python/branches/py3k-jit/Doc/library/doctest.rst Wed Jun 16 19:58:15 2010 @@ -282,11 +282,8 @@ How are Docstring Examples Recognized? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In most cases a copy-and-paste of an interactive console session works fine, but -doctest isn't trying to do an exact emulation of any specific Python shell. All -hard tab characters are expanded to spaces, using 8-column tab stops. If you -don't believe tabs should mean that, too bad: don't use hard tabs, or write -your own :class:`DocTestParser` class. +In most cases a copy-and-paste of an interactive console session works fine, +but doctest isn't trying to do an exact emulation of any specific Python shell. :: @@ -317,6 +314,17 @@ blank line, put ```` in your doctest example each place a blank line is expected. +* All hard tab characters are expanded to spaces, using 8-column tab stops. + Tabs in output generated by the tested code are not modified. Because any + hard tabs in the sample output *are* expanded, this means that if the code + output includes hard tabs, the only way the doctest can pass is if the + :const:`NORMALIZE_WHITESPACE` option or directive is in effect. + Alternatively, the test can be rewritten to capture the output and compare it + to an expected value as part of the test. This handling of tabs in the + source was arrived at through trial and error, and has proven to be the least + error prone way of handling them. It is possible to use a different + algorithm for handling tabs by writing a custom :class:`DocTestParser` class. + * Output to stdout is captured, but not output to stderr (exception tracebacks are captured via a different means). @@ -1778,4 +1786,3 @@ .. [#] Examples containing both expected output and an exception are not supported. Trying to guess where one ends and the other begins is too error-prone, and that also makes for a confusing test. - Modified: python/branches/py3k-jit/Doc/library/struct.rst ============================================================================== --- python/branches/py3k-jit/Doc/library/struct.rst (original) +++ python/branches/py3k-jit/Doc/library/struct.rst Wed Jun 16 19:58:15 2010 @@ -20,9 +20,9 @@ order to maintain proper alignment for the C types involved; similarly, alignment is taken into account when unpacking. This behavior is chosen so that the bytes of a packed struct correspond exactly to the layout in memory - of the corresponding C struct. To omit pad bytes, use `standard` size and - alignment instead of `native` size and alignment: see :ref:`struct-alignment` - for details. + of the corresponding C struct. To handle platform-independent data formats + or omit implicit pad bytes, use `standard` size and alignment instead of + `native` size and alignment: see :ref:`struct-alignment` for details. Functions and Exceptions ------------------------ @@ -95,19 +95,19 @@ the byte order, size and alignment of the packed data, according to the following table: -+-----------+------------------------+--------------------+ -| Character | Byte order | Size and alignment | -+===========+========================+====================+ -| ``@`` | native | native | -+-----------+------------------------+--------------------+ -| ``=`` | native | standard | -+-----------+------------------------+--------------------+ -| ``<`` | little-endian | standard | -+-----------+------------------------+--------------------+ -| ``>`` | big-endian | standard | -+-----------+------------------------+--------------------+ -| ``!`` | network (= big-endian) | standard | -+-----------+------------------------+--------------------+ ++-----------+------------------------+----------+-----------+ +| Character | Byte order | Size | Alignment | ++===========+========================+==========+===========+ +| ``@`` | native | native | native | ++-----------+------------------------+----------+-----------+ +| ``=`` | native | standard | none | ++-----------+------------------------+----------+-----------+ +| ``<`` | little-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``>`` | big-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ``!`` | network (= big-endian) | standard | none | ++-----------+------------------------+----------+-----------+ If the first character is not one of these, ``'@'`` is assumed. @@ -120,11 +120,8 @@ Native size and alignment are determined using the C compiler's ``sizeof`` expression. This is always combined with native byte order. -Standard size and alignment are as follows: no alignment is required for any -type (so you have to use pad bytes); :ctype:`short` is 2 bytes; :ctype:`int` and -:ctype:`long` are 4 bytes; :ctype:`long long` (:ctype:`__int64` on Windows) is 8 -bytes; :ctype:`float` and :ctype:`double` are 32-bit and 64-bit IEEE floating -point numbers, respectively. :ctype:`_Bool` is 1 byte. +Standard size depends only on the format character; see the table in +the :ref:`format-characters` section. Note the difference between ``'@'`` and ``'='``: both use native byte order, but the size and alignment of the latter is standardized. @@ -135,12 +132,6 @@ There is no way to indicate non-native byte order (force byte-swapping); use the appropriate choice of ``'<'`` or ``'>'``. -The ``'P'`` format character is only available for the native byte ordering -(selected as the default or with the ``'@'`` byte order character). The byte -order character ``'='`` chooses to use little- or big-endian ordering based on -the host system. The struct module does not interpret this as native ordering, -so the ``'P'`` format is not available. - Notes: (1) Padding is only automatically added between successive structure members. @@ -192,15 +183,15 @@ | ``Q`` | :ctype:`unsigned long | integer | 8 | \(3), \(4) | | | long` | | | | +--------+-------------------------+--------------------+----------------+------------+ -| ``f`` | :ctype:`float` | float | 4 | | +| ``f`` | :ctype:`float` | float | 4 | \(5) | +--------+-------------------------+--------------------+----------------+------------+ -| ``d`` | :ctype:`double` | float | 8 | | +| ``d`` | :ctype:`double` | float | 8 | \(5) | +--------+-------------------------+--------------------+----------------+------------+ | ``s`` | :ctype:`char[]` | bytes | | \(1) | +--------+-------------------------+--------------------+----------------+------------+ | ``p`` | :ctype:`char[]` | bytes | | \(1) | +--------+-------------------------+--------------------+----------------+------------+ -| ``P`` | :ctype:`void \*` | integer | | | +| ``P`` | :ctype:`void \*` | integer | | \(6) | +--------+-------------------------+--------------------+----------------+------------+ Notes: @@ -228,6 +219,18 @@ .. versionchanged:: 3.2 Use of the :meth:`__index__` method for non-integers is new in 3.2. +(5) + For the ``'f'`` and ``'d'`` conversion codes, the packed representation uses + the IEEE 754 binary32 (for ``'f'``) or binary64 (for ``'d'``) format, + regardless of the floating-point format used by the platform. + +(6) + The ``'P'`` format character is only available for the native byte ordering + (selected as the default or with the ``'@'`` byte order character). The byte + order character ``'='`` chooses to use little- or big-endian ordering based + on the host system. The struct module does not interpret this as native + ordering, so the ``'P'`` format is not available. + A format character may be preceded by an integral repeat count. For example, the format string ``'4h'`` means exactly the same as ``'hhhh'``. Modified: python/branches/py3k-jit/Lib/distutils/command/install.py ============================================================================== --- python/branches/py3k-jit/Lib/distutils/command/install.py (original) +++ python/branches/py3k-jit/Lib/distutils/command/install.py Wed Jun 16 19:58:15 2010 @@ -302,8 +302,8 @@ # about needing recursive variable expansion (shudder). py_version = sys.version.split()[0] - prefix, exec_prefix, srcdir = get_config_vars('prefix', 'exec_prefix', - 'srcdir') + prefix, exec_prefix, srcdir, projectbase = get_config_vars('prefix', 'exec_prefix', + 'srcdir', 'projectbase') self.config_vars = {'dist_name': self.distribution.get_name(), 'dist_version': self.distribution.get_version(), @@ -316,6 +316,7 @@ 'sys_exec_prefix': exec_prefix, 'exec_prefix': exec_prefix, 'srcdir': srcdir, + 'projectbase': projectbase, } self.config_vars['userbase'] = self.install_userbase Modified: python/branches/py3k-jit/Lib/email/feedparser.py ============================================================================== --- python/branches/py3k-jit/Lib/email/feedparser.py (original) +++ python/branches/py3k-jit/Lib/email/feedparser.py Wed Jun 16 19:58:15 2010 @@ -28,7 +28,7 @@ NLCRE = re.compile('\r\n|\r|\n') NLCRE_bol = re.compile('(\r\n|\r|\n)') -NLCRE_eol = re.compile('(\r\n|\r|\n)$') +NLCRE_eol = re.compile('(\r\n|\r|\n)\Z') NLCRE_crack = re.compile('(\r\n|\r|\n)') # RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character # except controls, SP, and ":". Modified: python/branches/py3k-jit/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k-jit/Lib/email/test/test_email.py (original) +++ python/branches/py3k-jit/Lib/email/test/test_email.py Wed Jun 16 19:58:15 2010 @@ -2588,6 +2588,24 @@ eq(headers, ['A', 'B', 'CC']) eq(msg.get_payload(), 'body') + def test_CRLFLF_at_end_of_part(self): + # issue 5610: feedparser should not eat two chars from body part ending + # with "\r\n\n". + m = ( + "From: foo at bar.com\n" + "To: baz\n" + "Mime-Version: 1.0\n" + "Content-Type: multipart/mixed; boundary=BOUNDARY\n" + "\n" + "--BOUNDARY\n" + "Content-Type: text/plain\n" + "\n" + "body ending with CRLF newline\r\n" + "\n" + "--BOUNDARY--\n" + ) + msg = email.message_from_string(m) + self.assertTrue(msg.get_payload(0).get_payload().endswith('\r\n')) class TestBase64(unittest.TestCase): Modified: python/branches/py3k-jit/Lib/sysconfig.py ============================================================================== --- python/branches/py3k-jit/Lib/sysconfig.py (original) +++ python/branches/py3k-jit/Lib/sysconfig.py Wed Jun 16 19:58:15 2010 @@ -123,8 +123,8 @@ if _PYTHON_BUILD: for scheme in ('posix_prefix', 'posix_home'): - _INSTALL_SCHEMES[scheme]['include'] = '{projectbase}/Include' - _INSTALL_SCHEMES[scheme]['platinclude'] = '{srcdir}' + _INSTALL_SCHEMES[scheme]['include'] = '{srcdir}/Include' + _INSTALL_SCHEMES[scheme]['platinclude'] = '{projectbase}/.' def _subst_vars(s, local_vars): try: @@ -458,6 +458,8 @@ if 'srcdir' not in _CONFIG_VARS: _CONFIG_VARS['srcdir'] = _PROJECT_BASE + else: + _CONFIG_VARS['srcdir'] = realpath(_CONFIG_VARS['srcdir']) # Convert srcdir into an absolute path if it appears necessary. Modified: python/branches/py3k-jit/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k-jit/Lib/test/regrtest.py (original) +++ python/branches/py3k-jit/Lib/test/regrtest.py Wed Jun 16 19:58:15 2010 @@ -152,6 +152,7 @@ option '-uall,-gui'. """ +import builtins import getopt import json import os @@ -859,15 +860,9 @@ sys.path_hooks[:] = saved_hooks[2] def get___import__(self): - if isinstance(__builtins__, dict): - return __builtins__['__import__'] - else: - return __builtins__.__import__ + return builtins.__import__ def restore___import__(self, import_): - if isinstance(__builtins__, dict): - __builtins__['__import__'] = import_ - else: - __builtins__.__import__ = import_ + builtins.__import__ = import_ def get_warnings_filters(self): return id(warnings.filters), warnings.filters, warnings.filters[:] Modified: python/branches/py3k-jit/Lib/test/test_datetime.py ============================================================================== --- python/branches/py3k-jit/Lib/test/test_datetime.py (original) +++ python/branches/py3k-jit/Lib/test/test_datetime.py Wed Jun 16 19:58:15 2010 @@ -148,13 +148,13 @@ def test_class_members(self): limit = timedelta(hours=23, minutes=59) - self.assertEquals(timezone.utc.utcoffset(None), ZERO) - self.assertEquals(timezone.min.utcoffset(None), -limit) - self.assertEquals(timezone.max.utcoffset(None), limit) + self.assertEqual(timezone.utc.utcoffset(None), ZERO) + self.assertEqual(timezone.min.utcoffset(None), -limit) + self.assertEqual(timezone.max.utcoffset(None), limit) def test_constructor(self): - self.assertEquals(timezone.utc, timezone(timedelta(0))) + self.assertEqual(timezone.utc, timezone(timedelta(0))) # invalid offsets for invalid in [timedelta(microseconds=1), timedelta(1, 1), timedelta(seconds=1), timedelta(1), -timedelta(1)]: @@ -167,32 +167,32 @@ with self.assertRaises(TypeError): timezone(ZERO, 42) def test_inheritance(self): - self.assertTrue(isinstance(timezone.utc, tzinfo)) - self.assertTrue(isinstance(self.EST, tzinfo)) + self.assertIsInstance(timezone.utc, tzinfo) + self.assertIsInstance(self.EST, tzinfo) def test_utcoffset(self): dummy = self.DT for h in [0, 1.5, 12]: offset = h * HOUR - self.assertEquals(offset, timezone(offset).utcoffset(dummy)) - self.assertEquals(-offset, timezone(-offset).utcoffset(dummy)) + self.assertEqual(offset, timezone(offset).utcoffset(dummy)) + self.assertEqual(-offset, timezone(-offset).utcoffset(dummy)) with self.assertRaises(TypeError): self.EST.utcoffset('') with self.assertRaises(TypeError): self.EST.utcoffset(5) def test_dst(self): - self.assertEquals(None, timezone.utc.dst(self.DT)) + self.assertEqual(None, timezone.utc.dst(self.DT)) with self.assertRaises(TypeError): self.EST.dst('') with self.assertRaises(TypeError): self.EST.dst(5) def test_tzname(self): - self.assertEquals('UTC+00:00', timezone(ZERO).tzname(None)) - self.assertEquals('UTC-05:00', timezone(-5 * HOUR).tzname(None)) - self.assertEquals('UTC+09:30', timezone(9.5 * HOUR).tzname(None)) - self.assertEquals('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None)) - self.assertEquals('XYZ', timezone(-5 * HOUR, 'XYZ').tzname(None)) + self.assertEqual('UTC+00:00', timezone(ZERO).tzname(None)) + self.assertEqual('UTC-05:00', timezone(-5 * HOUR).tzname(None)) + self.assertEqual('UTC+09:30', timezone(9.5 * HOUR).tzname(None)) + self.assertEqual('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None)) + self.assertEqual('XYZ', timezone(-5 * HOUR, 'XYZ').tzname(None)) with self.assertRaises(TypeError): self.EST.tzname('') with self.assertRaises(TypeError): self.EST.tzname(5) @@ -203,9 +203,9 @@ for tz in [self.EST, self.ACDT, Eastern]: utctime = self.DT.replace(tzinfo=tz) local = tz.fromutc(utctime) - self.assertEquals(local - utctime, tz.utcoffset(local)) - self.assertEquals(local, - self.DT.replace(tzinfo=timezone.utc)) + self.assertEqual(local - utctime, tz.utcoffset(local)) + self.assertEqual(local, + self.DT.replace(tzinfo=timezone.utc)) def test_comparison(self): self.assertNotEqual(timezone(ZERO), timezone(HOUR)) @@ -218,12 +218,12 @@ # test that timezone instances can be used by datetime t = datetime(1, 1, 1) for tz in [timezone.min, timezone.max, timezone.utc]: - self.assertEquals(tz.tzname(t), - t.replace(tzinfo=tz).tzname()) - self.assertEquals(tz.utcoffset(t), - t.replace(tzinfo=tz).utcoffset()) - self.assertEquals(tz.dst(t), - t.replace(tzinfo=tz).dst()) + self.assertEqual(tz.tzname(t), + t.replace(tzinfo=tz).tzname()) + self.assertEqual(tz.utcoffset(t), + t.replace(tzinfo=tz).utcoffset()) + self.assertEqual(tz.dst(t), + t.replace(tzinfo=tz).dst()) ############################################################################# # Base clase for testing a particular aspect of timedelta, time, date and @@ -1681,8 +1681,8 @@ def test_microsecond_rounding(self): # Test whether fromtimestamp "rounds up" floats that are less # than one microsecond smaller than an integer. - self.assertEquals(self.theclass.fromtimestamp(0.9999999), - self.theclass.fromtimestamp(1)) + self.assertEqual(self.theclass.fromtimestamp(0.9999999), + self.theclass.fromtimestamp(1)) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, @@ -1710,7 +1710,7 @@ @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_utcfromtimestamp(self): d = self.theclass.utcfromtimestamp(-1.05) - self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) + self.assertEqual(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) def test_utcnow(self): import time Modified: python/branches/py3k-jit/Misc/NEWS ============================================================================== --- python/branches/py3k-jit/Misc/NEWS (original) +++ python/branches/py3k-jit/Misc/NEWS Wed Jun 16 19:58:15 2010 @@ -451,6 +451,9 @@ Library ------- +- Issue #5610: feedparser no longer eats extra characters at the end of + a body part if the body part ends with a \r\n. + - Issue #8986: math.erfc was incorrectly raising OverflowError for values between -27.3 and -30.0 on some platforms. Modified: python/branches/py3k-jit/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k-jit/Modules/datetimemodule.c (original) +++ python/branches/py3k-jit/Modules/datetimemodule.c Wed Jun 16 19:58:15 2010 @@ -3472,13 +3472,13 @@ static PyMethodDef timezone_methods[] = { {"tzname", (PyCFunction)timezone_tzname, METH_O, PyDoc_STR("If name is specified when timezone is created, returns the name." - " Otherwise returns offset as 'UTC(+|-)HHMM'.")}, + " Otherwise returns offset as 'UTC(+|-)HH:MM'.")}, {"utcoffset", (PyCFunction)timezone_utcoffset, METH_O, - PyDoc_STR("Returns fixed offset. Ignores its argument.")}, + PyDoc_STR("Return fixed offset.")}, {"dst", (PyCFunction)timezone_dst, METH_O, - PyDoc_STR("Returns None. Ignores its argument.")}, + PyDoc_STR("Return None.")}, {"fromutc", (PyCFunction)timezone_fromutc, METH_O, PyDoc_STR("datetime in UTC -> datetime in local time.")}, From python-checkins at python.org Wed Jun 16 20:07:56 2010 From: python-checkins at python.org (mark.dickinson) Date: Wed, 16 Jun 2010 20:07:56 +0200 (CEST) Subject: [Python-checkins] r82031 - python/branches/py3k-dtoa/Python/dtoa.c Message-ID: <20100616180756.A91B4EEC6C@mail.python.org> Author: mark.dickinson Date: Wed Jun 16 20:07:56 2010 New Revision: 82031 Log: Issue #9009: In the s2b function: - Remove an instance of premature optimization (passing y to s2b) that makes s2b less general than in might be, and also makes it harder to verify correctness. - Use the same method for accessing elements of the string s0 as elsewhere in the code; this is more robust in cases where nd0 is out of range. Modified: python/branches/py3k-dtoa/Python/dtoa.c Modified: python/branches/py3k-dtoa/Python/dtoa.c ============================================================================== --- python/branches/py3k-dtoa/Python/dtoa.c (original) +++ python/branches/py3k-dtoa/Python/dtoa.c Wed Jun 16 20:07:56 2010 @@ -474,39 +474,27 @@ return b; } -/* convert a string s containing nd decimal digits (possibly containing a - decimal separator at position nd0, which is ignored) to a Bigint. This - function carries on where the parsing code in _Py_dg_strtod leaves off: on - entry, y9 contains the result of converting the first 9 digits. Returns - NULL on failure. */ +/* Convert a string s0 containing nd decimal digits (and possibly a decimal + separator at position nd0, which is ignored) to a Bigint. Returns NULL on + failure. Assumes that nd >= 1 and that the first digit is nonzero. */ static Bigint * -s2b(const char *s, int nd0, int nd, ULong y9) +s2b(const char *s0, int nd0, int nd) { Bigint *b; int i, k; Long x, y; x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; + for (k = 0, y = 1; x > y; y <<= 1, k++) ; b = Balloc(k); if (b == NULL) return NULL; - b->x[0] = y9; + b->x[0] = 0; b->wds = 1; - if (nd <= 9) - return b; - - s += 9; - for (i = 9; i < nd0; i++) { - b = multadd(b, 10, *s++ - '0'); - if (b == NULL) - return NULL; - } - s++; - for(; i < nd; i++) { - b = multadd(b, 10, *s++ - '0'); + for (i = 0; i < nd; i++) { + b = multadd(b, 10, s0[i < nd0 ? i : i + 1] - '0'); if (b == NULL) return NULL; } @@ -1809,7 +1797,7 @@ y = 10*y + s0[i+1] - '0'; } } - bd0 = s2b(s0, nd0, nd, y); + bd0 = s2b(s0, nd0, nd); if (bd0 == NULL) goto failed_malloc; From python-checkins at python.org Wed Jun 16 20:38:33 2010 From: python-checkins at python.org (mark.dickinson) Date: Wed, 16 Jun 2010 20:38:33 +0200 (CEST) Subject: [Python-checkins] r82032 - python/branches/py3k-dtoa/Lib/test/test_strtod.py Message-ID: <20100616183833.D396BEECFF@mail.python.org> Author: mark.dickinson Date: Wed Jun 16 20:38:33 2010 New Revision: 82032 Log: Issue #9009: Additional tests. (test_extra_long_significand will fail). Modified: python/branches/py3k-dtoa/Lib/test/test_strtod.py Modified: python/branches/py3k-dtoa/Lib/test/test_strtod.py ============================================================================== --- python/branches/py3k-dtoa/Lib/test/test_strtod.py (original) +++ python/branches/py3k-dtoa/Lib/test/test_strtod.py Wed Jun 16 20:38:33 2010 @@ -145,6 +145,63 @@ digits *= 5 exponent -= 1 + def test_twopower_boundaries(self): + # bit pattern for the value just under a normal power of 2 + for k in range(1, 2048): + bits = k * 2**52 - 1 + + # convert bit pattern to a number of the form m * 2**e + e, m = divmod(bits, 2**52) + if e: + m, e = m + 2**52, e - 1 + e -= 1074 + + # add 0.5 ulps + m, e = 2*m + 1, e - 1 + + # convert to a decimal string + if e >= 0: + digits = m << e + exponent = 0 + else: + # m * 2**e = (m * 5**-e) * 10**e + digits = m * 5**-e + exponent = e + s = '{}e{}'.format(digits, exponent) + self.check_strtod(s) + s = '{}e{}'.format(digits * 10**20 - 1, exponent - 20) + self.check_strtod(s) + s = '{}e{}'.format(digits * 10**20 + 1, exponent - 20) + self.check_strtod(s) + s = '{}e{}'.format(digits * 10**40 - 1, exponent - 40) + self.check_strtod(s) + s = '{}e{}'.format(digits * 10**40 + 1, exponent - 40) + self.check_strtod(s) + + # same again, but for exact value, not halfway case + e, m = divmod(bits, 2**52) + if e: + m, e = m + 2**52, e - 1 + e -= 1074 + + if e >= 0: + digits = m << e + exponent = 0 + else: + # m * 2**e = (m * 5**-e) * 10**e + digits = m * 5**-e + exponent = e + s = '{}e{}'.format(digits, exponent) + self.check_strtod(s) + s = '{}e{}'.format(digits * 10**20 - 1, exponent - 20) + self.check_strtod(s) + s = '{}e{}'.format(digits * 10**20 + 1, exponent - 20) + self.check_strtod(s) + s = '{}e{}'.format(digits * 10**40 - 1, exponent - 40) + self.check_strtod(s) + s = '{}e{}'.format(digits * 10**40 + 1, exponent - 40) + self.check_strtod(s) + def test_halfway_cases(self): # test halfway cases for the round-half-to-even rule for i in range(100 * TEST_SIZE): @@ -247,6 +304,20 @@ else: assert False, "expected ValueError" + def test_extra_long_significand(self): + for n in 1000, 10000, 100000, 1000000: + s = '1{}e{}'.format('0'*n, -n) + self.assertEqual(float(s), 1.0) + + s = '0.{}1e{}'.format('0'*(n-1), n) + self.assertEqual(float(s), 1.0) + + s = '1.00000000000000000000000{}e{}'.format('0'*n, 23) + self.assertEqual(float(s), 1e23) + + s = '1.00000000000000000000000{}1e{}'.format('0'*n, 23) + self.assertEqual(float(s), float(10**23 + 1)) + def test_particular(self): # inputs that produced crashes or incorrectly rounded results with # previous versions of dtoa.c, for various reasons From python-checkins at python.org Wed Jun 16 21:27:57 2010 From: python-checkins at python.org (r.david.murray) Date: Wed, 16 Jun 2010 21:27:57 +0200 (CEST) Subject: [Python-checkins] r82033 - python/branches/release31-maint Message-ID: <20100616192757.9B607EED95@mail.python.org> Author: r.david.murray Date: Wed Jun 16 21:27:57 2010 New Revision: 82033 Log: Blocked revisions 75914,75932,75976,75981,75992,76002,76013,76072,76097,76124,76200,76237,76251,76268,76280,76297,76332,76335,76351,76375,76385,76413,76418,76421,76467,76474,76497,76501,76513,76516,76532,76570,76585,76607,76631,76650,76667,76677,76680,76688,76773,76793,76795,76797,76800,76832,76850,76921,76928,76947,76965,76970,76986,76999,77039,77049,77113,77168,77183-77184,77201,77224,77253,77255,77285,77312,77363,77373,77387-77388,77407,77429,77441,77444,77674,77720,77792,77808,77813,77935,77939-77940,77984,77991,77994,78023,78120,78286,78395,78414,78451,78473,78478,78487,78670,78691,78695,78715,78745,78747,78750,78763,78765,78803,78848,78927,78938,78956,79025,79080,79087,79253,79257,79400,79407,79411,79414,79454,79462-79463,79467,79505,79591,79593,79628,79641,79656,79694,79696,79705,79708,79715,79720-79721,79770,79933,79948,79953,79955,79966-79967,79972,80019,80083,80122,80206,80217,80272,80493,80497,80550,80697,80740,80750,80760,80778,80806,80842,80973,81003,81009,81021,81028,81136,81138,81211,81378,81424,81455,81511,81519,81538,81581,81607,81609,81737,81743,81746,81751,81762,81778,81816,81818,81827,81829,81877,81901,81905,81946,81958,82014 via svnmerge ................ r75914 | eric.smith | 2009-10-28 04:46:43 -0400 (Wed, 28 Oct 2009) | 8 lines Blocked revisions 75913 via svnmerge ........ r75913 | eric.smith | 2009-10-28 04:44:37 -0400 (Wed, 28 Oct 2009) | 1 line Issue 7117: Replace PyOS_ascii_strtod with PyOS_string_to_double in _json.c as part of short float repr. Change made after consulting with Bob Ippolito. This completes the removal of calls to PyOS_ascii_strtod. ........ ................ r75932 | benjamin.peterson | 2009-10-28 21:50:06 -0400 (Wed, 28 Oct 2009) | 11 lines Blocked revisions 75931 via svnmerge ........ r75931 | benjamin.peterson | 2009-10-28 20:49:07 -0500 (Wed, 28 Oct 2009) | 5 lines do a backport of r75928 The added test does not fail without the patch, but we still fix the issue of surrogates being used in wide builds where they should not be. ........ ................ r75976 | mark.dickinson | 2009-10-31 05:29:47 -0400 (Sat, 31 Oct 2009) | 8 lines Blocked revisions 75974 via svnmerge ........ r75974 | mark.dickinson | 2009-10-31 09:28:12 +0000 (Sat, 31 Oct 2009) | 1 line Move a Misc/NEWS entry to right section. ........ ................ r75981 | mark.dickinson | 2009-10-31 05:43:46 -0400 (Sat, 31 Oct 2009) | 8 lines Blocked revisions 75979 via svnmerge ........ r75979 | mark.dickinson | 2009-10-31 09:42:39 +0000 (Sat, 31 Oct 2009) | 1 line Deprecate PyOS_ascii_strtod and PyOS_ascii_atof, and document the replacement function PyOS_string_to_double. ........ ................ r75992 | mark.dickinson | 2009-10-31 08:48:28 -0400 (Sat, 31 Oct 2009) | 8 lines Blocked revisions 75991 via svnmerge ........ r75991 | mark.dickinson | 2009-10-31 12:47:47 +0000 (Sat, 31 Oct 2009) | 1 line Set retval on PyOS_string_to_double failure. ........ ................ r76002 | antoine.pitrou | 2009-10-31 19:26:47 -0400 (Sat, 31 Oct 2009) | 9 lines Blocked revisions 76001 via svnmerge Apparently someone already did the job in py3k. ........ r76001 | antoine.pitrou | 2009-11-01 00:19:52 +0100 (dim., 01 nov. 2009) | 3 lines Use richer assertions in test_mailbox (for better failure messages). ........ ................ r76013 | antoine.pitrou | 2009-11-01 11:13:08 -0500 (Sun, 01 Nov 2009) | 8 lines Blocked revisions 76012 via svnmerge ........ r76012 | antoine.pitrou | 2009-11-01 17:10:47 +0100 (dim., 01 nov. 2009) | 3 lines Hum, test skipping when the URL isn't reachable hadn't been applied to trunk. ........ ................ r76072 | antoine.pitrou | 2009-11-02 15:57:43 -0500 (Mon, 02 Nov 2009) | 9 lines Blocked revisions 76071 via svnmerge ........ r76071 | antoine.pitrou | 2009-11-02 21:47:33 +0100 (lun., 02 nov. 2009) | 4 lines Add acceptance of long ints to test_memoryio.py (in preparation for fix of #7249 in 2.6) ........ ................ r76097 | georg.brandl | 2009-11-03 13:35:33 -0500 (Tue, 03 Nov 2009) | 8 lines Blocked revisions 76095 via svnmerge ........ r76095 | georg.brandl | 2009-11-03 18:34:27 +0000 (Di, 03 Nov 2009) | 1 line #7256: add versionadded tags for functions copied from cgi. ........ ................ r76124 | r.david.murray | 2009-11-05 12:49:10 -0500 (Thu, 05 Nov 2009) | 9 lines Blocked revisions 76116 via svnmerge ........ r76116 | r.david.murray | 2009-11-04 20:50:56 -0500 (Wed, 04 Nov 2009) | 3 lines Increase the timeout in the bsddb3 replication test to allow the test time to complete on slow buildbots. See issue 6462. ........ ................ r76200 | antoine.pitrou | 2009-11-10 16:39:56 -0500 (Tue, 10 Nov 2009) | 8 lines Blocked revisions 76199 via svnmerge ........ r76199 | antoine.pitrou | 2009-11-10 22:39:25 +0100 (mar., 10 nov. 2009) | 3 lines Backport micro-fix from the py3k svnmerge ........ ................ r76237 | benjamin.peterson | 2009-11-12 21:43:40 -0500 (Thu, 12 Nov 2009) | 52 lines Blocked revisions 75407-75413,75415,75417,75419-75421 via svnmerge ........ r75407 | antoine.pitrou | 2009-10-14 12:30:52 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in the aifc module ........ r75408 | antoine.pitrou | 2009-10-14 12:34:31 -0500 (Wed, 14 Oct 2009) | 3 lines Fix a test_atexit failure when run with -3 ........ r75409 | antoine.pitrou | 2009-10-14 13:01:33 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in bsddb ........ r75410 | antoine.pitrou | 2009-10-14 13:09:45 -0500 (Wed, 14 Oct 2009) | 3 lines Silence a py3k warning claiming to affect Lib/calendar.py ........ r75411 | antoine.pitrou | 2009-10-14 13:12:54 -0500 (Wed, 14 Oct 2009) | 3 lines Fix a py3k warning in the StringIO module (exhibited in test_codecencodings_cn) ........ r75412 | antoine.pitrou | 2009-10-14 13:27:32 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in the socket module ........ r75413 | antoine.pitrou | 2009-10-14 13:31:05 -0500 (Wed, 14 Oct 2009) | 3 lines Fix a py3k warning in the sndhdr module (found with test_email) ........ r75415 | antoine.pitrou | 2009-10-14 13:39:46 -0500 (Wed, 14 Oct 2009) | 3 lines Silence some py3k warnings claiming to affect _pyio ........ r75417 | antoine.pitrou | 2009-10-14 13:47:13 -0500 (Wed, 14 Oct 2009) | 3 lines Fix failures in test_profilehooks when run with -3 ........ r75419 | antoine.pitrou | 2009-10-14 13:56:11 -0500 (Wed, 14 Oct 2009) | 3 lines Silence py3k warning claiming to affect the random module ........ r75420 | antoine.pitrou | 2009-10-14 14:04:48 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in httplib ........ r75421 | antoine.pitrou | 2009-10-14 14:09:48 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in the uuid module ........ ................ r76251 | benjamin.peterson | 2009-11-13 17:57:33 -0500 (Fri, 13 Nov 2009) | 12 lines Blocked revisions 76243,76249 via svnmerge ........ r76243 | benjamin.peterson | 2009-11-13 16:17:17 -0600 (Fri, 13 Nov 2009) | 1 line never mind about eval mode in this case ........ r76249 | benjamin.peterson | 2009-11-13 16:56:00 -0600 (Fri, 13 Nov 2009) | 1 line revert r76243; I was right, actually :) ........ ................ r76268 | r.david.murray | 2009-11-14 13:26:33 -0500 (Sat, 14 Nov 2009) | 16 lines Blocked revisions 76214,76265 via svnmerge ........ r76214 | r.david.murray | 2009-11-11 13:07:27 -0500 (Wed, 11 Nov 2009) | 5 lines I got the relative magnitudes of the timeout increases reversed, so I'm bumping up the longer test to the 60 seconds I intended to make it. If this doesn't cure the intermittent buildbot timeouts, I'm going to turn that test into a warning rather than a failure. ........ r76265 | r.david.murray | 2009-11-14 12:43:16 -0500 (Sat, 14 Nov 2009) | 3 lines Turn the bsddb replication startup timeout test into a warning, to improve buildbot stability. ........ ................ r76280 | r.david.murray | 2009-11-14 19:25:11 -0500 (Sat, 14 Nov 2009) | 9 lines Blocked revisions 76277 via svnmerge ........ r76277 | r.david.murray | 2009-11-14 19:07:00 -0500 (Sat, 14 Nov 2009) | 3 lines Remove 'g' from regrtest getopt argument string, since there's no handler for it. ........ ................ r76297 | mark.dickinson | 2009-11-15 07:34:44 -0500 (Sun, 15 Nov 2009) | 11 lines Blocked revisions 76295 via svnmerge ........ r76295 | mark.dickinson | 2009-11-15 12:31:13 +0000 (Sun, 15 Nov 2009) | 5 lines Avoid signed overflow in some xrange calculations, and extend xrange tests to cover some special cases that caused problems in py3k. This is a partial backport of r76292-76293 (see issue #7298.) ........ ................ r76332 | mark.dickinson | 2009-11-16 12:36:10 -0500 (Mon, 16 Nov 2009) | 8 lines Blocked revisions 76330 via svnmerge ........ r76330 | mark.dickinson | 2009-11-16 17:33:25 +0000 (Mon, 16 Nov 2009) | 1 line Silence MSVC warning about unary minus applied to unsigned type. ........ ................ r76335 | mark.dickinson | 2009-11-16 14:18:32 -0500 (Mon, 16 Nov 2009) | 8 lines Blocked revisions 76333 via svnmerge ........ r76333 | mark.dickinson | 2009-11-16 19:17:16 +0000 (Mon, 16 Nov 2009) | 1 line Silence another MSVC warning about unary minus. ........ ................ r76351 | benjamin.peterson | 2009-11-17 16:27:44 -0500 (Tue, 17 Nov 2009) | 8 lines Blocked revisions 76350 via svnmerge ........ r76350 | benjamin.peterson | 2009-11-17 15:24:54 -0600 (Tue, 17 Nov 2009) | 1 line a better callable replacement ........ ................ r76375 | mark.dickinson | 2009-11-18 14:35:30 -0500 (Wed, 18 Nov 2009) | 11 lines Blocked revisions 76373 via svnmerge ........ r76373 | mark.dickinson | 2009-11-18 19:33:35 +0000 (Wed, 18 Nov 2009) | 5 lines Issue #7117, continued: Change round implementation to use the correctly-rounded string <-> float conversions; this makes sure that the result of the round operation is correctly rounded, and hence displays nicely using the new float repr. ........ ................ r76385 | mark.dickinson | 2009-11-18 15:32:09 -0500 (Wed, 18 Nov 2009) | 8 lines Blocked revisions 76379 via svnmerge ........ r76379 | mark.dickinson | 2009-11-18 20:14:57 +0000 (Wed, 18 Nov 2009) | 1 line Enable short float repr! ........ ................ r76413 | mark.dickinson | 2009-11-19 13:43:03 -0500 (Thu, 19 Nov 2009) | 8 lines Blocked revisions 76411 via svnmerge ........ r76411 | mark.dickinson | 2009-11-19 18:41:49 +0000 (Thu, 19 Nov 2009) | 1 line Misc/NEWS entries for issue 7117. ........ ................ r76418 | benjamin.peterson | 2009-11-19 18:00:13 -0500 (Thu, 19 Nov 2009) | 19 lines Blocked revisions 76416-76417 via svnmerge ........ r76416 | benjamin.peterson | 2009-11-19 16:54:57 -0600 (Thu, 19 Nov 2009) | 10 lines improve several corner cases related with argument names in parenthesis - Fix #7362: give a good error message for parenthesized arguments with defaults. - Add a py3k warning for any parenthesized arguments since those are not allowed in Py3. This warning is not given in tuple unpacking, since that incurs the tuple unpacking warning. ........ r76417 | benjamin.peterson | 2009-11-19 16:58:01 -0600 (Thu, 19 Nov 2009) | 1 line add news notes for r76416 ........ ................ r76421 | benjamin.peterson | 2009-11-19 18:23:56 -0500 (Thu, 19 Nov 2009) | 8 lines Blocked revisions 76420 via svnmerge ........ r76420 | benjamin.peterson | 2009-11-19 17:19:29 -0600 (Thu, 19 Nov 2009) | 1 line spelling ........ ................ r76467 | mark.dickinson | 2009-11-23 13:52:36 -0500 (Mon, 23 Nov 2009) | 10 lines Blocked revisions 76465 via svnmerge ........ r76465 | mark.dickinson | 2009-11-23 18:46:41 +0000 (Mon, 23 Nov 2009) | 4 lines Remove restriction on precision when formatting floats. This is the first step towards removing the %f -> %g switch (see issues 7117, 5859). ........ ................ r76474 | mark.dickinson | 2009-11-23 15:55:58 -0500 (Mon, 23 Nov 2009) | 10 lines Blocked revisions 76472 via svnmerge ........ r76472 | mark.dickinson | 2009-11-23 20:54:09 +0000 (Mon, 23 Nov 2009) | 4 lines Issue #7117, continued: Remove substitution of %g-style formatting for %f-style formatting, which used to occur at high precision. Float formatting should now be consistent between 2.7 and 3.1. ........ ................ r76497 | mark.dickinson | 2009-11-24 10:13:27 -0500 (Tue, 24 Nov 2009) | 8 lines Blocked revisions 76495 via svnmerge ........ r76495 | mark.dickinson | 2009-11-24 15:12:20 +0000 (Tue, 24 Nov 2009) | 2 lines Issue #7117: Update float formatting testcases to match those in py3k. ........ ................ r76501 | alexandre.vassalotti | 2009-11-24 13:10:33 -0500 (Tue, 24 Nov 2009) | 15 lines Blocked revisions 76499 via svnmerge ........ r76499 | alexandre.vassalotti | 2009-11-24 12:53:23 -0500 (Tue, 24 Nov 2009) | 9 lines Issue 7128: Removed reference to the non-existent copyreg module. The reference to copyreg was a unnoticed leftover from the compatibility support for the grand renaming of the standard library in Python 3. The compatibility support was reverted in r63493, but not completely as this patch shows. Based on a patch by Amaury Forgeot d'Arc. ........ ................ r76513 | benjamin.peterson | 2009-11-25 12:12:57 -0500 (Wed, 25 Nov 2009) | 141 lines Blocked revisions 74962,75017,75131,75143,75147,75281,75423-75424,75482,75586,75929,76025,76050-76051,76126,76129,76132,76194,76212,76382,76392,76431,76434 via svnmerge ................ r74962 | ronald.oussoren | 2009-09-20 05:31:22 -0500 (Sun, 20 Sep 2009) | 2 lines Fix for issue 6851: urllib.urlopen crashes in a thread on OSX 10.6 ................ r75017 | ronald.oussoren | 2009-09-22 09:24:57 -0500 (Tue, 22 Sep 2009) | 4 lines The 'Navigation Toolbox' is not available at all for 64-bit code, make this explicit in the C code to avoid confusing error messages during the build. ................ r75131 | ronald.oussoren | 2009-09-29 08:00:44 -0500 (Tue, 29 Sep 2009) | 8 lines * Update the Mac/README file. Add the list of OSX-specific configure options to that README file with some explanation. * Be more strict in the configure script: complain loudly when the user has specified invalid combinations of OSX-specific configure arguments. The error message refers to the Mac/README file for more information. ................ r75143 | philip.jenvey | 2009-09-29 14:10:15 -0500 (Tue, 29 Sep 2009) | 5 lines #5329: fix os.popen* regression from 2.5: don't execute commands as a sequence through the shell. also document the correct subprocess replacement for this case patch from Jean-Paul Calderone and Jani Hakala ................ r75147 | ronald.oussoren | 2009-09-29 14:34:13 -0500 (Tue, 29 Sep 2009) | 4 lines Fix for issue6957: ensure that the OSX installer installs a version of Python that can build extensions on OSX 10.6. ................ r75281 | ronald.oussoren | 2009-10-08 03:04:15 -0500 (Thu, 08 Oct 2009) | 3 lines Ensure that _scproxy gets build even when --disable-toolbox-glue is specified on OSX. Fixes a regression in 2.6.3. ................ r75423 | neil.schemenauer | 2009-10-14 14:23:53 -0500 (Wed, 14 Oct 2009) | 2 lines Add support to the ihooks module for relative imports. ................ r75424 | neil.schemenauer | 2009-10-14 14:33:31 -0500 (Wed, 14 Oct 2009) | 4 lines Make cPickle.Unpickler.noload() handle dict subclasses. noload() is an obscure, undocumentated feature so no test was added. Closes issue #1101399. ................ r75482 | ronald.oussoren | 2009-10-18 02:07:00 -0500 (Sun, 18 Oct 2009) | 3 lines Fix for issue 7149: a regression in 2.6.3 that causes an exception when trying to detect proxy settings on OSX. ................ r75586 | vinay.sajip | 2009-10-21 15:22:14 -0500 (Wed, 21 Oct 2009) | 1 line Issue #7077: logging: SysLogHandler now treats Unicode as per RFC 5424. ................ r75929 | vinay.sajip | 2009-10-28 18:28:16 -0500 (Wed, 28 Oct 2009) | 1 line Issue 7199: Documentation made slightly more consistent w.r.t. logging level enumeration. ................ r76025 | raymond.hettinger | 2009-11-01 14:45:16 -0600 (Sun, 01 Nov 2009) | 1 line Fix exception handling in itertools.izip_longest(). ................ r76050 | gregory.p.smith | 2009-11-01 19:37:37 -0600 (Sun, 01 Nov 2009) | 5 lines see http://bugs.python.org/issue1006238 this merges in the following patch to make cross compilation of the chflags check easier: http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-lang/python/files/python-2.6-chflags-cross.patch?rev=1.1 ................ r76051 | gregory.p.smith | 2009-11-01 19:38:35 -0600 (Sun, 01 Nov 2009) | 2 lines build using r76050 ................ r76126 | benjamin.peterson | 2009-11-05 15:29:56 -0600 (Thu, 05 Nov 2009) | 9 lines Merged revisions 76125 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76125 | benjamin.peterson | 2009-11-05 15:26:55 -0600 (Thu, 05 Nov 2009) | 1 line handle newline issues better for comparing files ........ ................ r76129 | benjamin.peterson | 2009-11-05 17:20:06 -0600 (Thu, 05 Nov 2009) | 13 lines Merged revisions 76127-76128 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76127 | benjamin.peterson | 2009-11-05 17:04:58 -0600 (Thu, 05 Nov 2009) | 1 line set svn:eol-style ........ r76128 | benjamin.peterson | 2009-11-05 17:07:46 -0600 (Thu, 05 Nov 2009) | 1 line skip this test on windows to avoid newline horrors ........ ................ r76132 | benjamin.peterson | 2009-11-05 17:54:42 -0600 (Thu, 05 Nov 2009) | 9 lines Merged revisions 76131 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76131 | benjamin.peterson | 2009-11-05 17:53:21 -0600 (Thu, 05 Nov 2009) | 1 line import sys ........ ................ r76194 | raymond.hettinger | 2009-11-10 13:35:55 -0600 (Tue, 10 Nov 2009) | 3 lines Show example of how to make a sorted dictionary ................ r76212 | senthil.kumaran | 2009-11-11 11:22:35 -0600 (Wed, 11 Nov 2009) | 3 lines Fixing the NameError on Windows - issue1235 ................ r76382 | raymond.hettinger | 2009-11-18 14:28:22 -0600 (Wed, 18 Nov 2009) | 1 line Issue 7263: Fix set.intersection() docstring. ................ r76392 | raymond.hettinger | 2009-11-18 19:22:04 -0600 (Wed, 18 Nov 2009) | 1 line Fix docstrings for itertools combinatoric functions. ................ r76431 | mark.dickinson | 2009-11-20 13:27:43 -0600 (Fri, 20 Nov 2009) | 1 line Regenerate configure with GNU autoconf 2.61. ................ r76434 | jesse.noller | 2009-11-21 08:06:24 -0600 (Sat, 21 Nov 2009) | 1 line revert unintended change to multiprocessing/queues.py ................ ................ r76516 | benjamin.peterson | 2009-11-25 12:54:15 -0500 (Wed, 25 Nov 2009) | 101 lines Blocked revisions 74523,74715,74721,74733-74734,74798,74825,74832,74845,74849,74873,74936-74937,74962,74964,74981,75017,75022,76053 via svnmerge ........ r74523 | gregory.p.smith | 2009-08-20 04:38:43 -0500 (Thu, 20 Aug 2009) | 2 lines comment typo fix ........ r74715 | ronald.oussoren | 2009-09-08 02:17:10 -0500 (Tue, 08 Sep 2009) | 5 lines This is an update to r74701. How hard can it be to get a configure test right. This patch has already been backported as part of the backport of r74701, which is how I found this problem. ........ r74721 | thomas.heller | 2009-09-08 14:24:36 -0500 (Tue, 08 Sep 2009) | 1 line Make ctypes compile again with older Python versions. ........ r74733 | benjamin.peterson | 2009-09-09 06:40:54 -0500 (Wed, 09 Sep 2009) | 1 line tabbify ........ r74734 | benjamin.peterson | 2009-09-09 06:42:57 -0500 (Wed, 09 Sep 2009) | 1 line revert unintended changes ........ r74798 | ronald.oussoren | 2009-09-15 13:33:33 -0500 (Tue, 15 Sep 2009) | 8 lines MacOSX: detect the architectures supported by Tk.framework and build _tkinter only for those architectures. This replaces the hardcoded solution that is no longer valid now that 64-bit capable versions of Tk are available on OSX. ........ r74825 | ezio.melotti | 2009-09-16 08:14:05 -0500 (Wed, 16 Sep 2009) | 1 line #6879 - fix misstatement about exceptions ........ r74832 | georg.brandl | 2009-09-16 10:57:46 -0500 (Wed, 16 Sep 2009) | 1 line Rewrap long lines. ........ r74845 | georg.brandl | 2009-09-16 15:30:09 -0500 (Wed, 16 Sep 2009) | 5 lines #6844: do not emit DeprecationWarnings on access if Exception.message has been set by the user. This works by always setting it in __dict__, except when it's implicitly set in __init__. ........ r74849 | thomas.wouters | 2009-09-16 15:36:34 -0500 (Wed, 16 Sep 2009) | 4 lines Add news entry for r74841. ........ r74873 | georg.brandl | 2009-09-17 06:48:31 -0500 (Thu, 17 Sep 2009) | 1 line #6844 followup: the warning when setting Exception.message was removed, do not test for it. ........ r74936 | benjamin.peterson | 2009-09-18 16:46:21 -0500 (Fri, 18 Sep 2009) | 1 line backport keyword argument support for bytearray.decode ........ r74937 | benjamin.peterson | 2009-09-18 16:47:27 -0500 (Fri, 18 Sep 2009) | 1 line typo ........ r74962 | ronald.oussoren | 2009-09-20 05:31:22 -0500 (Sun, 20 Sep 2009) | 2 lines Fix for issue 6851: urllib.urlopen crashes in a thread on OSX 10.6 ........ r74964 | ronald.oussoren | 2009-09-20 05:54:07 -0500 (Sun, 20 Sep 2009) | 2 lines Followup for r74962 ........ r74981 | ronald.oussoren | 2009-09-20 15:16:11 -0500 (Sun, 20 Sep 2009) | 3 lines * Make it easier to build custom installers (such as a 3-way universal build) * Upgrade bzip dependency to 1.0.5 ........ r75017 | ronald.oussoren | 2009-09-22 09:24:57 -0500 (Tue, 22 Sep 2009) | 4 lines The 'Navigation Toolbox' is not available at all for 64-bit code, make this explicit in the C code to avoid confusing error messages during the build. ........ r75022 | ronald.oussoren | 2009-09-22 14:27:44 -0500 (Tue, 22 Sep 2009) | 8 lines Half of the fix for issue 6957: ensure that distutils ignores the '-isysroot' option on OSX when the corresponding SDK is not installed. This ensures that the user can compile extensions on OSX 10.6 using the Python.org installer and a default installation of Xcode. ........ r76053 | gregory.p.smith | 2009-11-01 20:03:16 -0600 (Sun, 01 Nov 2009) | 2 lines regenerated from r76052 ........ ................ r76532 | antoine.pitrou | 2009-11-25 18:03:48 -0500 (Wed, 25 Nov 2009) | 8 lines Blocked revisions 76531 via svnmerge ........ r76531 | antoine.pitrou | 2009-11-26 00:03:22 +0100 (jeu., 26 nov. 2009) | 3 lines Forgot to add a `versionadded` tag ........ ................ r76570 | mark.dickinson | 2009-11-28 08:14:02 -0500 (Sat, 28 Nov 2009) | 8 lines Blocked revisions 76568 via svnmerge ........ r76568 | mark.dickinson | 2009-11-28 13:13:13 +0000 (Sat, 28 Nov 2009) | 1 line Multiprocessing configure checks don't need LIBM ........ ................ r76585 | eric.smith | 2009-11-29 12:44:41 -0500 (Sun, 29 Nov 2009) | 8 lines Blocked revisions 76583 via svnmerge ........ r76583 | eric.smith | 2009-11-29 12:40:57 -0500 (Sun, 29 Nov 2009) | 1 line Issue #3382: Make '%F' and float.__format__('F') convert results to upper case. Much of the patch came from Mark Dickinson. ........ ................ r76607 | mark.dickinson | 2009-11-30 16:53:52 -0500 (Mon, 30 Nov 2009) | 12 lines Blocked revisions 76603,76605 via svnmerge ........ r76603 | raymond.hettinger | 2009-11-30 21:14:25 +0000 (Mon, 30 Nov 2009) | 1 line Update project file for new file: dtoa.c ........ r76605 | mark.dickinson | 2009-11-30 21:51:30 +0000 (Mon, 30 Nov 2009) | 2 lines Add dtoa.c and dtoa.h to the relevant project files. ........ ................ r76631 | mark.dickinson | 2009-12-02 12:37:21 -0500 (Wed, 02 Dec 2009) | 9 lines 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. ........ ................ r76650 | mark.dickinson | 2009-12-03 07:10:00 -0500 (Thu, 03 Dec 2009) | 9 lines 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. ........ ................ r76667 | mark.dickinson | 2009-12-04 06:26:06 -0500 (Fri, 04 Dec 2009) | 8 lines 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). ........ ................ r76677 | benjamin.peterson | 2009-12-05 13:42:10 -0500 (Sat, 05 Dec 2009) | 20 lines 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 ........ ................ r76680 | benjamin.peterson | 2009-12-05 13:51:13 -0500 (Sat, 05 Dec 2009) | 8 lines Blocked revisions 76679 via svnmerge ........ r76679 | benjamin.peterson | 2009-12-05 12:48:13 -0600 (Sat, 05 Dec 2009) | 1 line fix date ........ ................ r76688 | benjamin.peterson | 2009-12-06 12:36:44 -0500 (Sun, 06 Dec 2009) | 12 lines 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 ........ ................ r76773 | benjamin.peterson | 2009-12-12 19:38:59 -0500 (Sat, 12 Dec 2009) | 28 lines 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. ........ ................ r76793 | antoine.pitrou | 2009-12-13 11:19:46 -0500 (Sun, 13 Dec 2009) | 9 lines 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) ........ ................ r76795 | benjamin.peterson | 2009-12-13 11:39:38 -0500 (Sun, 13 Dec 2009) | 8 lines 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 ........ ................ r76797 | benjamin.peterson | 2009-12-13 11:42:09 -0500 (Sun, 13 Dec 2009) | 12 lines 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. ........ ................ r76800 | benjamin.peterson | 2009-12-13 12:32:59 -0500 (Sun, 13 Dec 2009) | 12 lines 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 ........ ................ r76832 | r.david.murray | 2009-12-14 12:11:00 -0500 (Mon, 14 Dec 2009) | 12 lines 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. ........ ................ r76850 | tarek.ziade | 2009-12-15 01:30:35 -0500 (Tue, 15 Dec 2009) | 8 lines 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) ........ ................ r76921 | georg.brandl | 2009-12-20 09:20:59 -0500 (Sun, 20 Dec 2009) | 8 lines 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. ........ ................ r76928 | benjamin.peterson | 2009-12-20 10:24:32 -0500 (Sun, 20 Dec 2009) | 8 lines Blocked revisions 76927 via svnmerge ........ r76927 | benjamin.peterson | 2009-12-20 09:23:22 -0600 (Sun, 20 Dec 2009) | 1 line builtin-ins -> builtins ........ ................ r76947 | mark.dickinson | 2009-12-20 15:24:18 -0500 (Sun, 20 Dec 2009) | 8 lines 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. ........ ................ r76965 | mark.dickinson | 2009-12-21 06:22:47 -0500 (Mon, 21 Dec 2009) | 9 lines 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. ........ ................ r76970 | mark.dickinson | 2009-12-21 07:18:09 -0500 (Mon, 21 Dec 2009) | 12 lines 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. ........ ................ r76986 | mark.dickinson | 2009-12-21 11:30:51 -0500 (Mon, 21 Dec 2009) | 9 lines 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. ........ ................ r76999 | tarek.ziade | 2009-12-21 18:39:47 -0500 (Mon, 21 Dec 2009) | 8 lines 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 ........ ................ r77039 | benjamin.peterson | 2009-12-24 10:21:26 -0500 (Thu, 24 Dec 2009) | 8 lines 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 ........ ................ r77049 | ezio.melotti | 2009-12-24 18:01:34 -0500 (Thu, 24 Dec 2009) | 8 lines 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 ........ ................ r77113 | georg.brandl | 2009-12-29 06:26:30 -0500 (Tue, 29 Dec 2009) | 8 lines Blocked revisions 77111 via svnmerge ........ r77111 | georg.brandl | 2009-12-29 12:25:38 +0100 (Di, 29 Dez 2009) | 1 line Fix wrong markup. ........ ................ r77168 | benjamin.peterson | 2009-12-30 22:16:47 -0500 (Wed, 30 Dec 2009) | 23 lines 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. ........ ................ r77183 | ezio.melotti | 2009-12-31 08:56:50 -0500 (Thu, 31 Dec 2009) | 8 lines 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 ........ ................ r77184 | ezio.melotti | 2009-12-31 08:58:03 -0500 (Thu, 31 Dec 2009) | 8 lines 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 ........ ................ r77201 | brett.cannon | 2009-12-31 21:00:24 -0500 (Thu, 31 Dec 2009) | 9 lines Blocked revisions 77198 via svnmerge ........ r77198 | brett.cannon | 2009-12-31 17:44:57 -0800 (Thu, 31 Dec 2009) | 3 lines Add some missing command-line options to the main list. All but -V were already documented. Left -V undocumented for now (and -U was already undocumented). ........ ................ r77224 | benjamin.peterson | 2010-01-01 21:45:52 -0500 (Fri, 01 Jan 2010) | 8 lines Blocked revisions 77222 via svnmerge ........ r77222 | benjamin.peterson | 2010-01-01 20:43:04 -0600 (Fri, 01 Jan 2010) | 1 line remove use of deprecated os.popen #7619 ........ ................ r77253 | gregory.p.smith | 2010-01-02 17:32:00 -0500 (Sat, 02 Jan 2010) | 11 lines Blocked revisions 77252 via svnmerge ........ r77252 | gregory.p.smith | 2010-01-02 14:28:48 -0800 (Sat, 02 Jan 2010) | 5 lines Issue #3745: Undo the requirement for new buffer API only objects to be passed to hashlib functions in python 2.x. The module now uses the 's*' for argument parsing which auto encodes unicode objects to the system default encoding for us. ........ ................ r77255 | gregory.p.smith | 2010-01-02 17:44:17 -0500 (Sat, 02 Jan 2010) | 8 lines Blocked revisions 77254 via svnmerge ........ r77254 | gregory.p.smith | 2010-01-02 14:42:50 -0800 (Sat, 02 Jan 2010) | 2 lines mention the r77252 change ........ ................ r77285 | gregory.p.smith | 2010-01-03 09:57:46 -0500 (Sun, 03 Jan 2010) | 8 lines Blocked revisions 77284 via svnmerge ........ r77284 | gregory.p.smith | 2010-01-03 06:56:28 -0800 (Sun, 03 Jan 2010) | 2 lines remove an obsolete file that should've gone with r77252 ........ ................ r77312 | antoine.pitrou | 2010-01-04 18:29:25 -0500 (Mon, 04 Jan 2010) | 13 lines Blocked revisions 77310-77311 via svnmerge ........ r77310 | antoine.pitrou | 2010-01-05 00:22:44 +0100 (mar., 05 janv. 2010) | 4 lines Issue #7092: Fix the DeprecationWarnings emitted by the standard library when using the -3 flag. Patch by Florent Xicluna. ........ r77311 | antoine.pitrou | 2010-01-05 00:28:16 +0100 (mar., 05 janv. 2010) | 3 lines Kill a couple of "<>" ........ ................ r77363 | mark.dickinson | 2010-01-08 11:55:38 -0500 (Fri, 08 Jan 2010) | 8 lines Blocked revisions 77362 via svnmerge ........ r77362 | mark.dickinson | 2010-01-08 16:53:56 +0000 (Fri, 08 Jan 2010) | 1 line Backport some float repr tests that were missed in issue 7117. ........ ................ r77373 | antoine.pitrou | 2010-01-08 14:22:50 -0500 (Fri, 08 Jan 2010) | 11 lines Blocked revisions 77370 via svnmerge ........ r77370 | antoine.pitrou | 2010-01-08 20:20:17 +0100 (ven., 08 janv. 2010) | 5 lines Issue #7092: Remove py3k warning when importing cPickle. 2to3 handles renaming of `cPickle` to `pickle`. The warning was annoying since there's no alternative to cPickle if you care about performance. Patch by Florent Xicluna. ........ ................ r77387 | benjamin.peterson | 2010-01-09 12:36:21 -0500 (Sat, 09 Jan 2010) | 12 lines Blocked revisions 77384,77386 via svnmerge ........ r77384 | benjamin.peterson | 2010-01-09 10:34:06 -0600 (Sat, 09 Jan 2010) | 1 line bump version to 2.7a2 ........ r77386 | benjamin.peterson | 2010-01-09 11:30:31 -0600 (Sat, 09 Jan 2010) | 1 line post release version adjustment ........ ................ r77388 | benjamin.peterson | 2010-01-09 12:45:42 -0500 (Sat, 09 Jan 2010) | 25 lines Blocked revisions 77227,77256,77260,77368-77369 via svnmerge ........ r77227 | martin.v.loewis | 2010-01-02 03:53:18 -0600 (Sat, 02 Jan 2010) | 1 line Make script work with 2.5. ........ r77256 | georg.brandl | 2010-01-02 16:55:55 -0600 (Sat, 02 Jan 2010) | 1 line Fix typo. ........ r77260 | gregory.p.smith | 2010-01-02 18:43:02 -0600 (Sat, 02 Jan 2010) | 2 lines make setup.py similar to py3k's when reporting on _hashlib as missing or not. ........ r77368 | senthil.kumaran | 2010-01-08 12:41:40 -0600 (Fri, 08 Jan 2010) | 1 line Fixing - Issue7026 - RuntimeError: dictionary changed size during iteration. Patch by flox ........ r77369 | senthil.kumaran | 2010-01-08 13:04:16 -0600 (Fri, 08 Jan 2010) | 4 lines Reverting the Revision: 77368. I committed Flox's big patch for tests by mistake. ( It may come in for sure tough) ........ ................ r77407 | mark.dickinson | 2010-01-10 06:27:39 -0500 (Sun, 10 Jan 2010) | 9 lines Blocked revisions 77391 via svnmerge ........ r77391 | mark.dickinson | 2010-01-09 18:50:50 +0000 (Sat, 09 Jan 2010) | 3 lines Issue #7532: Add additional slicing test cases for new- and old-style classes. Patch by Florent Xicluna. ........ ................ r77429 | alexandre.vassalotti | 2010-01-11 18:21:10 -0500 (Mon, 11 Jan 2010) | 16 lines Blocked revisions 77400,77422,77428 via svnmerge ........ r77400 | alexandre.vassalotti | 2010-01-09 18:35:54 -0500 (Sat, 09 Jan 2010) | 2 lines Issue #2335: Backport set literals syntax from Python 3.x. ........ r77422 | alexandre.vassalotti | 2010-01-11 17:36:12 -0500 (Mon, 11 Jan 2010) | 2 lines Issue #2333: Backport set and dict comprehensions syntax. ........ r77428 | alexandre.vassalotti | 2010-01-11 18:17:10 -0500 (Mon, 11 Jan 2010) | 2 lines Issue #1967: Backport dictionary views. ........ ................ r77441 | alexandre.vassalotti | 2010-01-11 20:51:09 -0500 (Mon, 11 Jan 2010) | 8 lines Blocked revisions 77438 via svnmerge ........ r77438 | alexandre.vassalotti | 2010-01-11 20:34:43 -0500 (Mon, 11 Jan 2010) | 2 lines Fixed repr of dictionary views. ........ ................ r77444 | ezio.melotti | 2010-01-11 23:03:11 -0500 (Mon, 11 Jan 2010) | 8 lines Blocked revisions 77442 via svnmerge ........ r77442 | ezio.melotti | 2010-01-12 05:32:05 +0200 (Tue, 12 Jan 2010) | 1 line #5827: make sure that normpath preserves unicode ........ ................ r77674 | mark.dickinson | 2010-01-21 15:00:00 -0500 (Thu, 21 Jan 2010) | 8 lines Blocked revisions 77672 via svnmerge ........ r77672 | mark.dickinson | 2010-01-21 19:58:41 +0000 (Thu, 21 Jan 2010) | 1 line Use // for floor division. ........ ................ r77720 | tarek.ziade | 2010-01-23 20:29:58 -0500 (Sat, 23 Jan 2010) | 8 lines Blocked revisions 77717 via svnmerge ........ r77717 | tarek.ziade | 2010-01-24 01:33:32 +0100 (Sun, 24 Jan 2010) | 1 line Fixed #7748: now upload and register commands don't need to force the encoding anymore : DistributionMetada returns utf8 strings ........ ................ r77792 | benjamin.peterson | 2010-01-26 21:27:48 -0500 (Tue, 26 Jan 2010) | 8 lines Blocked revisions 77788 via svnmerge ........ r77788 | benjamin.peterson | 2010-01-26 20:15:28 -0600 (Tue, 26 Jan 2010) | 1 line for UserDict to be compatible with abcs, it must subclass object ........ ................ r77808 | benjamin.peterson | 2010-01-27 20:31:31 -0500 (Wed, 27 Jan 2010) | 8 lines Blocked revisions 77806 via svnmerge ........ r77806 | benjamin.peterson | 2010-01-27 19:24:46 -0600 (Wed, 27 Jan 2010) | 1 line add compat note ........ ................ r77813 | benjamin.peterson | 2010-01-27 21:22:10 -0500 (Wed, 27 Jan 2010) | 12 lines Blocked revisions 77811-77812 via svnmerge ........ r77811 | benjamin.peterson | 2010-01-27 20:15:02 -0600 (Wed, 27 Jan 2010) | 1 line an -> a ........ r77812 | benjamin.peterson | 2010-01-27 20:18:25 -0600 (Wed, 27 Jan 2010) | 1 line avoid a py3k warning from __hash__ ........ ................ r77935 | benjamin.peterson | 2010-02-02 20:57:04 -0500 (Tue, 02 Feb 2010) | 77 lines Blocked revisions 77401,77420,77423,77426,77486,77511,77513,77515,77544,77733,77755,77841,77871,77885,77910-77913 via svnmerge ........ r77401 | brett.cannon | 2010-01-09 20:48:50 -0600 (Sat, 09 Jan 2010) | 3 lines Update the version # of Python-ast.c based on the backport of set literals from r77400. ........ r77420 | benjamin.peterson | 2010-01-10 14:42:03 -0600 (Sun, 10 Jan 2010) | 1 line fix test_popen when the path to python has spaces #7671 ........ r77423 | alexandre.vassalotti | 2010-01-11 16:46:43 -0600 (Mon, 11 Jan 2010) | 2 lines Update version information for AST changes in r77422. ........ r77426 | alexandre.vassalotti | 2010-01-11 17:13:49 -0600 (Mon, 11 Jan 2010) | 2 lines Add missing NEWS entry for r77422. ........ r77486 | benjamin.peterson | 2010-01-13 20:40:10 -0600 (Wed, 13 Jan 2010) | 1 line use more robust quoting ........ r77511 | benjamin.peterson | 2010-01-14 20:26:07 -0600 (Thu, 14 Jan 2010) | 1 line try to fix for windows ........ r77513 | vinay.sajip | 2010-01-15 17:27:05 -0600 (Fri, 15 Jan 2010) | 1 line Fixed issue-number mistake in NEWS update. ........ r77515 | sean.reifschneider | 2010-01-15 22:27:58 -0600 (Fri, 15 Jan 2010) | 1 line issue5063: Fixes for building RPM on CentOS plus misc .spec file enhancements. ........ r77544 | ezio.melotti | 2010-01-16 12:38:01 -0600 (Sat, 16 Jan 2010) | 1 line typo: use one instead instead of two ........ r77733 | ezio.melotti | 2010-01-24 15:47:59 -0600 (Sun, 24 Jan 2010) | 1 line #7269: fix failures in test_bsddb3. Patch by Florent Xicluna. ........ r77755 | ezio.melotti | 2010-01-26 09:57:21 -0600 (Tue, 26 Jan 2010) | 1 line #7092: fix DeprecationWarnings for json when the tests are run with -3 -Wd. ........ r77841 | ezio.melotti | 2010-01-30 01:22:54 -0600 (Sat, 30 Jan 2010) | 1 line #7092: silence py3k warnings for deprecated modules ........ r77871 | ezio.melotti | 2010-01-31 05:46:54 -0600 (Sun, 31 Jan 2010) | 1 line #7092: silence more -3 and -Wd warnings ........ r77885 | benjamin.peterson | 2010-01-31 12:02:35 -0600 (Sun, 31 Jan 2010) | 1 line fix windows buildbot ........ r77910 | ezio.melotti | 2010-02-02 02:37:35 -0600 (Tue, 02 Feb 2010) | 1 line #7092: silence py3k warnings for bsddb. Patch by Florent Xicluna. ........ r77911 | ezio.melotti | 2010-02-02 09:12:42 -0600 (Tue, 02 Feb 2010) | 1 line Silence a couple of -3 warnings ........ r77912 | ezio.melotti | 2010-02-02 09:57:45 -0600 (Tue, 02 Feb 2010) | 1 line Fix idioms and a couple of py3k warnings. Patch by Florent Xicluna. ........ r77913 | ezio.melotti | 2010-02-02 11:34:37 -0600 (Tue, 02 Feb 2010) | 1 line #7092: Silence py3k warnings in test_exceptions and test_pep352. Patch by Florent Xicluna. ........ ................ r77939 | benjamin.peterson | 2010-02-02 21:46:37 -0500 (Tue, 02 Feb 2010) | 20 lines Blocked revisions 77607,77609,77679 via svnmerge ........ r77607 | gregory.p.smith | 2010-01-19 02:01:00 -0600 (Tue, 19 Jan 2010) | 6 lines Add a pydebug mode only debug print to help debug the errors in http://www.python.org/dev/buildbot/all/builders/x86%20gentoo%20trunk/builds/5700/ Will be removed shortly. ........ r77609 | gregory.p.smith | 2010-01-19 02:25:26 -0600 (Tue, 19 Jan 2010) | 2 lines Revert debugprint code in r77607. ........ r77679 | matthias.klose | 2010-01-21 18:34:48 -0600 (Thu, 21 Jan 2010) | 2 lines - Mention CVE-2009-3720 for change in r74429. ........ ................ r77940 | benjamin.peterson | 2010-02-02 21:53:11 -0500 (Tue, 02 Feb 2010) | 37 lines Blocked revisions 77575,77585,77587-77588 via svnmerge ........ r77575 | ronald.oussoren | 2010-01-17 06:38:11 -0600 (Sun, 17 Jan 2010) | 3 lines Add text to Mac/README to warn about non-universal libraries when building a universal Python. Based on issue7679. ........ r77585 | ronald.oussoren | 2010-01-17 10:25:57 -0600 (Sun, 17 Jan 2010) | 12 lines - Issue #7658: Ensure that the new pythonw executable works on OSX 10.4 - Issue #7714: Use ``gcc -dumpversion`` to detect the version of GCC on MacOSX. - Make configure look for util.h as well as libutil.h. The former is the header file that on OSX contains the defition of openpty. (Needed to compile for OSX 10.4 on OSX 10.6) - Use the correct definition of CC to compile the pythonw executable ........ r77587 | ronald.oussoren | 2010-01-17 13:27:57 -0600 (Sun, 17 Jan 2010) | 8 lines This patch ensures that the configure-script mentions checking for --enable-universalsdk and that it doesn't default to the 10.4u SDK when that SDK does not exist. (This affects OSX) This patch should fix most of issue 4834, although I haven't gotten enough information from the user to be sure. ........ r77588 | ronald.oussoren | 2010-01-17 13:32:00 -0600 (Sun, 17 Jan 2010) | 2 lines Explicitly use /usr/bin/arch on OSX, fixes issue 7715 ........ ................ r77984 | benjamin.peterson | 2010-02-04 21:14:20 -0500 (Thu, 04 Feb 2010) | 15 lines Blocked revisions 77983 via svnmerge ........ r77983 | benjamin.peterson | 2010-02-04 20:12:14 -0600 (Thu, 04 Feb 2010) | 9 lines normalize exceptions passed to the __exit__ method #7853 In Python 2.x, exceptions in finally blocks are not normalized. Since with statements are implemented using finally blocks, ceval.c had to be tweaked to distinguish between with finally blocks and normal ones. A test for the finalization of generators containing with statements was also added. ........ ................ r77991 | antoine.pitrou | 2010-02-05 12:14:05 -0500 (Fri, 05 Feb 2010) | 11 lines Blocked revisions 77989 via svnmerge ........ r77989 | antoine.pitrou | 2010-02-05 18:05:54 +0100 (ven., 05 f?vr. 2010) | 6 lines Issue #5677: Explicitly forbid write operations on read-only file objects, and read operations on write-only file objects. On Windows, the system C library would return a bogus result; on Solaris, it was possible to crash the interpreter. Patch by Stefan Krah. ........ ................ r77994 | barry.warsaw | 2010-02-05 14:01:58 -0500 (Fri, 05 Feb 2010) | 9 lines Blocked revisions 77992 via svnmerge ........ r77992 | barry.warsaw | 2010-02-05 13:45:25 -0500 (Fri, 05 Feb 2010) | 4 lines Resolve bug 7847 by including documentation for -J, -U, and -X under "Options you shouldn't use". ........ ................ r78023 | benjamin.peterson | 2010-02-06 13:29:29 -0500 (Sat, 06 Feb 2010) | 12 lines Blocked revisions 78020,78022 via svnmerge ........ r78020 | benjamin.peterson | 2010-02-06 10:37:32 -0600 (Sat, 06 Feb 2010) | 1 line bump version to 2.7a3 ........ r78022 | benjamin.peterson | 2010-02-06 12:26:27 -0600 (Sat, 06 Feb 2010) | 1 line post release updates ........ ................ r78120 | michael.foord | 2010-02-08 18:16:41 -0500 (Mon, 08 Feb 2010) | 8 lines Blocked revisions 78119 via svnmerge ........ r78119 | michael.foord | 2010-02-08 23:15:22 +0000 (Mon, 08 Feb 2010) | 1 line Doc fix for unittest. ........ ................ r78286 | mark.dickinson | 2010-02-21 08:46:40 -0500 (Sun, 21 Feb 2010) | 8 lines Blocked revisions 78280 via svnmerge ........ r78280 | mark.dickinson | 2010-02-21 12:57:35 +0000 (Sun, 21 Feb 2010) | 1 line Fix complex type to avoid implicit calls to complex.__coerce__. ........ ................ r78395 | victor.stinner | 2010-02-23 18:21:33 -0500 (Tue, 23 Feb 2010) | 10 lines Blocked revisions 78392 via svnmerge ........ r78392 | victor.stinner | 2010-02-24 00:16:07 +0100 (mer., 24 f?vr. 2010) | 4 lines Issue #7649: Fix u'%c' % char for character in range 0x80..0xFF => raise an UnicodeDecodeError. Patch written by Ezio Melotti. ........ ................ r78414 | r.david.murray | 2010-02-23 21:37:33 -0500 (Tue, 23 Feb 2010) | 12 lines Blocked revisions 78412 via svnmerge ........ r78412 | r.david.murray | 2010-02-23 21:31:27 -0500 (Tue, 23 Feb 2010) | 6 lines Issue 7975: in python 2.6 bsddb.dbshelve switched from DictMixin to MutableMapping, and thereby lost functionality because the replacement functionality was implemented incorrectly or incompletely). Since bsddb isn't in py3k, this patch just goes back to using DictMixin in order to correct the regression. ........ ................ r78451 | ezio.melotti | 2010-02-25 12:53:21 -0500 (Thu, 25 Feb 2010) | 8 lines Blocked revisions 78449 via svnmerge ........ r78449 | ezio.melotti | 2010-02-25 19:36:04 +0200 (Thu, 25 Feb 2010) | 1 line #7649: "u'%c' % char" now behaves like "u'%s' % char" and raises a UnicodeDecodeError if 'char' is a byte string that can't be decoded using the default encoding. ........ ................ r78473 | benjamin.peterson | 2010-02-26 19:17:04 -0500 (Fri, 26 Feb 2010) | 8 lines Blocked revisions 78468 via svnmerge ........ r78468 | benjamin.peterson | 2010-02-26 18:11:42 -0600 (Fri, 26 Feb 2010) | 1 line run autoconf ........ ................ r78478 | ezio.melotti | 2010-02-26 20:11:44 -0500 (Fri, 26 Feb 2010) | 8 lines Blocked revisions 78465 via svnmerge ........ r78465 | ezio.melotti | 2010-02-27 01:27:06 +0200 (Sat, 27 Feb 2010) | 1 line typo: __next__ -> next ........ ................ r78487 | ezio.melotti | 2010-02-27 07:43:58 -0500 (Sat, 27 Feb 2010) | 8 lines Blocked revisions 78486 via svnmerge ........ r78486 | ezio.melotti | 2010-02-27 14:42:52 +0200 (Sat, 27 Feb 2010) | 1 line Add a test for normpath to test_macpath. ........ ................ r78670 | tarek.ziade | 2010-03-04 19:36:02 -0500 (Thu, 04 Mar 2010) | 12 lines Blocked revisions 78666-78667 via svnmerge ........ r78666 | tarek.ziade | 2010-03-05 01:16:02 +0100 (Fri, 05 Mar 2010) | 1 line reverting partially distutils to its 2.6.x state so 2.7a4 looks more like the 2.7b1 in this. the whole revert will occur after a4 is tagged ........ r78667 | tarek.ziade | 2010-03-05 01:29:38 +0100 (Fri, 05 Mar 2010) | 1 line reverted the usage of compiler_obj in Python's setup.py ........ ................ r78691 | mark.dickinson | 2010-03-05 09:41:33 -0500 (Fri, 05 Mar 2010) | 10 lines Blocked revisions 78690 via svnmerge ........ r78690 | mark.dickinson | 2010-03-05 14:36:20 +0000 (Fri, 05 Mar 2010) | 3 lines Fix incorrect stacklevel for DeprecationWarnings originating from the struct module. Also clean up related tests in test_struct. The stacklevel fix should be backported to 2.6 once that branch is unfrozen. ........ ................ r78695 | mark.dickinson | 2010-03-05 09:50:47 -0500 (Fri, 05 Mar 2010) | 8 lines Blocked revisions 78694 via svnmerge ........ r78694 | mark.dickinson | 2010-03-05 14:50:22 +0000 (Fri, 05 Mar 2010) | 1 line Remove the redundant #define: PY_STRUCT_FLOAT_COERCE ........ ................ r78715 | tarek.ziade | 2010-03-05 21:30:14 -0500 (Fri, 05 Mar 2010) | 12 lines Blocked revisions 78706,78710 via svnmerge ........ r78706 | tarek.ziade | 2010-03-06 02:04:14 +0100 (Sat, 06 Mar 2010) | 1 line copied back the build_ext tests from 2.6 ........ r78710 | tarek.ziade | 2010-03-06 02:27:09 +0100 (Sat, 06 Mar 2010) | 1 line files used by win32 tests ........ ................ r78745 | benjamin.peterson | 2010-03-06 17:49:30 -0500 (Sat, 06 Mar 2010) | 12 lines Blocked revisions 78738,78743 via svnmerge ........ r78738 | benjamin.peterson | 2010-03-06 14:34:14 -0600 (Sat, 06 Mar 2010) | 1 line bump version to 2.7a4 ........ r78743 | benjamin.peterson | 2010-03-06 16:44:07 -0600 (Sat, 06 Mar 2010) | 1 line post release update ........ ................ r78747 | benjamin.peterson | 2010-03-06 19:03:46 -0500 (Sat, 06 Mar 2010) | 8 lines Blocked revisions 78746 via svnmerge ........ r78746 | benjamin.peterson | 2010-03-06 18:00:37 -0600 (Sat, 06 Mar 2010) | 1 line more specific exception for wrong kind of raise #8082 ........ ................ r78750 | benjamin.peterson | 2010-03-06 19:35:13 -0500 (Sat, 06 Mar 2010) | 8 lines Blocked revisions 78749 via svnmerge ........ r78749 | benjamin.peterson | 2010-03-06 18:29:44 -0600 (Sat, 06 Mar 2010) | 1 line eliminate py3k warnings in argparse ........ ................ r78763 | mark.dickinson | 2010-03-07 11:25:25 -0500 (Sun, 07 Mar 2010) | 14 lines Blocked revisions 78762 via svnmerge ........ r78762 | mark.dickinson | 2010-03-07 16:24:45 +0000 (Sun, 07 Mar 2010) | 8 lines Issue #1530559: When packing a non-integer with any integer conversion code using struct.pack, attempt to convert to an integer first using the argument's __int__ method (if present). Also raise a DeprecationWarning for any such usage of __int__. This fixes a regression from 2.6, where some (but not all) integer conversion codes already used __int__. ........ ................ r78765 | mark.dickinson | 2010-03-07 12:10:42 -0500 (Sun, 07 Mar 2010) | 8 lines Blocked revisions 78764 via svnmerge ........ r78764 | mark.dickinson | 2010-03-07 17:10:19 +0000 (Sun, 07 Mar 2010) | 1 line Silence compiler warning. ........ ................ r78803 | r.david.murray | 2010-03-08 12:16:58 -0500 (Mon, 08 Mar 2010) | 12 lines Blocked revisions 78558 via svnmerge ........ r78558 | r.david.murray | 2010-03-01 14:14:16 -0500 (Mon, 01 Mar 2010) | 6 lines Issue 3892 again. The bsddb3 replication test still fails randomly. Since this module is unmaintained in the library and gone in py3k, this patch skips the remainder of the replication test if a second timeout occurs, as it randomly does. This should improve buildbot stability. ........ ................ r78848 | benjamin.peterson | 2010-03-11 17:36:36 -0500 (Thu, 11 Mar 2010) | 8 lines Blocked revisions 78846 via svnmerge ........ r78846 | benjamin.peterson | 2010-03-11 16:33:25 -0600 (Thu, 11 Mar 2010) | 1 line normalize shebang lines to #!/usr/bin/env python ........ ................ r78927 | mark.dickinson | 2010-03-13 09:24:41 -0500 (Sat, 13 Mar 2010) | 8 lines Blocked revisions 78926 via svnmerge ........ r78926 | mark.dickinson | 2010-03-13 14:18:34 +0000 (Sat, 13 Mar 2010) | 1 line Fix incorrect error checks in structmember.c (backport of r78920 from py3k). ........ ................ r78938 | benjamin.peterson | 2010-03-13 16:20:06 -0500 (Sat, 13 Mar 2010) | 80 lines Blocked revisions 77942,78053,78061,78113-78114,78150,78215,78247,78385,78467,78563,78652,78726,78751,78812,78814 via svnmerge ........ r77942 | ezio.melotti | 2010-02-02 23:37:26 -0600 (Tue, 02 Feb 2010) | 1 line #7092: Silence more py3k warnings. Patch by Florent Xicluna. ........ r78053 | georg.brandl | 2010-02-06 17:54:43 -0600 (Sat, 06 Feb 2010) | 1 line Fix some name errors in Mac modules. ........ r78061 | ronald.oussoren | 2010-02-07 05:38:28 -0600 (Sun, 07 Feb 2010) | 10 lines A number of APIs in macostools cannot work in 64-bit mode because they use Carbon APIs that aren't available there. This patch disables tests for the affected entrypoints in macostools and mentions this in the documentation. In theory it is possible to replace the implementation by code that does work in 64-bit mode, but that would require further updates to the Carbon wrappers because the modern APIs aren't wrapped properly. ........ r78113 | georg.brandl | 2010-02-08 16:37:20 -0600 (Mon, 08 Feb 2010) | 1 line Fix missing string formatting argument. ........ r78114 | georg.brandl | 2010-02-08 16:37:52 -0600 (Mon, 08 Feb 2010) | 1 line Fix undefined local. ........ r78150 | ronald.oussoren | 2010-02-11 07:19:34 -0600 (Thu, 11 Feb 2010) | 3 lines Fix copy&paste error in the definition of ARCH_RUN_32BIT for a 3-way universal build (all other definition where correct). ........ r78215 | martin.v.loewis | 2010-02-18 06:45:45 -0600 (Thu, 18 Feb 2010) | 1 line Move bsddb47 macros before their use, to make VS 2010 happy. ........ r78247 | ezio.melotti | 2010-02-20 02:09:39 -0600 (Sat, 20 Feb 2010) | 1 line #3426: os.path.abspath now returns unicode when its arg is unicode. ........ r78385 | georg.brandl | 2010-02-23 15:33:17 -0600 (Tue, 23 Feb 2010) | 1 line #8000: fix deprecated directive. What a shame to lose that glorious issue number to such a minor bug :) ........ r78467 | ezio.melotti | 2010-02-26 18:05:42 -0600 (Fri, 26 Feb 2010) | 1 line Show an error when the value passed to --enable-unicode is not ucs2 or ucs4 (lowercase). ........ r78563 | florent.xicluna | 2010-03-01 14:45:01 -0600 (Mon, 01 Mar 2010) | 2 lines #7808: Fix reference leaks in _bsddb and related tests. ........ r78652 | florent.xicluna | 2010-03-04 09:57:20 -0600 (Thu, 04 Mar 2010) | 2 lines Fix transient refleak in test_popen2. ........ r78726 | florent.xicluna | 2010-03-06 08:38:09 -0600 (Sat, 06 Mar 2010) | 2 lines Backport "test.regrtest -R 2:3" syntax from py3k branch, and other minor adjustments. ........ r78751 | senthil.kumaran | 2010-03-06 22:09:30 -0600 (Sat, 06 Mar 2010) | 3 lines Reverting the change made in r78431. ........ r78812 | raymond.hettinger | 2010-03-09 03:58:53 -0600 (Tue, 09 Mar 2010) | 6 lines Have links in OrderedDicts be native Python lists instead of a custom class with __slots__. This simplifies the code a bit, reduces memory consumption, improves speed, and eliminates the need for weak reference proxies. ........ r78814 | raymond.hettinger | 2010-03-09 05:29:10 -0600 (Tue, 09 Mar 2010) | 1 line Improve code clarity a bit. ........ ................ r78956 | georg.brandl | 2010-03-14 06:24:29 -0400 (Sun, 14 Mar 2010) | 8 lines Blocked revisions 78949 via svnmerge ........ r78949 | georg.brandl | 2010-03-14 10:50:54 +0100 (So, 14 M?r 2010) | 1 line Format and rewrap 2.7 NEWS consistently. ........ ................ r79025 | ezio.melotti | 2010-03-17 10:28:47 -0400 (Wed, 17 Mar 2010) | 8 lines Blocked revisions 79023 via svnmerge ........ r79023 | ezio.melotti | 2010-03-17 15:52:48 +0200 (Wed, 17 Mar 2010) | 1 line #7092: silence some more py3k warnings. ........ ................ r79080 | benjamin.peterson | 2010-03-18 19:14:21 -0400 (Thu, 18 Mar 2010) | 8 lines Blocked revisions 79078 via svnmerge ........ r79078 | benjamin.peterson | 2010-03-18 18:12:43 -0500 (Thu, 18 Mar 2010) | 1 line make compiler's py3k warning a full deprecation warning #6837 ........ ................ r79087 | benjamin.peterson | 2010-03-18 21:08:38 -0400 (Thu, 18 Mar 2010) | 12 lines Blocked revisions 79078,79086 via svnmerge ........ r79078 | benjamin.peterson | 2010-03-18 18:12:43 -0500 (Thu, 18 Mar 2010) | 1 line make compiler's py3k warning a full deprecation warning #6837 ........ r79086 | benjamin.peterson | 2010-03-18 20:06:33 -0500 (Thu, 18 Mar 2010) | 1 line keep DeprecationWarning from failing test ........ ................ r79253 | benjamin.peterson | 2010-03-21 18:21:53 -0400 (Sun, 21 Mar 2010) | 79 lines Blocked revisions 78272,78580,78707,78709-78710,78712-78713,78811,78974,79096,79105,79123,79125,79165,79187-79189,79191 via svnmerge ........ r78272 | ezio.melotti | 2010-02-20 16:34:21 -0600 (Sat, 20 Feb 2010) | 1 line skip tests with a non-ascii cwd when the file system encoding is ascii ........ r78580 | andrew.kuchling | 2010-03-02 07:55:33 -0600 (Tue, 02 Mar 2010) | 1 line Add an item ........ r78707 | tarek.ziade | 2010-03-05 19:18:27 -0600 (Fri, 05 Mar 2010) | 1 line provide a fallback for xxmodule.c in case the buildir is not present ........ r78709 | tarek.ziade | 2010-03-05 19:23:21 -0600 (Fri, 05 Mar 2010) | 1 line simplified the fallback case ........ r78710 | tarek.ziade | 2010-03-05 19:27:09 -0600 (Fri, 05 Mar 2010) | 1 line files used by win32 tests ........ r78712 | tarek.ziade | 2010-03-05 20:11:14 -0600 (Fri, 05 Mar 2010) | 1 line fixed various failures and environment alterations in distutils.test_build_ext ........ r78713 | tarek.ziade | 2010-03-05 20:17:28 -0600 (Fri, 05 Mar 2010) | 1 line search in the alternative location for VCExpress ........ r78811 | raymond.hettinger | 2010-03-09 03:01:46 -0600 (Tue, 09 Mar 2010) | 4 lines Add nicer docstrings to namedtuples(). Provides better tooltips and looks better in help(). ........ r78974 | matthias.klose | 2010-03-15 07:46:18 -0500 (Mon, 15 Mar 2010) | 2 lines - Issue #6949: Allow the _bsddb extension to be built with db-4.8.x. ........ r79096 | matthias.klose | 2010-03-19 09:45:06 -0500 (Fri, 19 Mar 2010) | 2 lines - Issue #1039, #8154: Fix os.execlp() crash with missing 2nd argument. ........ r79105 | thomas.heller | 2010-03-19 14:59:30 -0500 (Fri, 19 Mar 2010) | 3 lines Initialized merge tracking via "svnmerge" with revisions "1-79104" from svn+ssh://pythondev at svn.python.org/python/branches/branch_libffi-3_0_10-win ........ r79123 | sean.reifschneider | 2010-03-19 18:19:55 -0500 (Fri, 19 Mar 2010) | 2 lines Adding an example of reproducing the rfc822.Message() parsing. ........ r79125 | sean.reifschneider | 2010-03-19 19:05:42 -0500 (Fri, 19 Mar 2010) | 2 lines Fixing the file call in the rfc822.Message replacement example. ........ r79165 | florent.xicluna | 2010-03-20 20:14:24 -0500 (Sat, 20 Mar 2010) | 2 lines #7092 - Silence more py3k deprecation warnings, using test_support.check_py3k_warnings() helper. ........ r79187 | florent.xicluna | 2010-03-21 05:50:44 -0500 (Sun, 21 Mar 2010) | 2 lines Silence more py3k warnings in unittest.case. ........ r79188 | florent.xicluna | 2010-03-21 05:51:40 -0500 (Sun, 21 Mar 2010) | 2 lines Fix py3k warnings in test_decimal, using unittest.assertItemsEqual. ........ r79189 | florent.xicluna | 2010-03-21 06:03:21 -0500 (Sun, 21 Mar 2010) | 2 lines Silence some py3k SyntaxWarning using check_py3k_warnings() with "exec" statements. ........ r79191 | florent.xicluna | 2010-03-21 06:50:17 -0500 (Sun, 21 Mar 2010) | 3 lines No more deprecation warnings for distutils.sysconfig, following r78666. But when the "dl" module is available, it gives a py3k deprecation warning. ........ ................ r79257 | benjamin.peterson | 2010-03-21 18:46:35 -0400 (Sun, 21 Mar 2010) | 8 lines Blocked revisions 78722 via svnmerge ........ r78722 | florent.xicluna | 2010-03-06 05:01:08 -0600 (Sat, 06 Mar 2010) | 2 lines #6906: TCL_LIBRARY and TK_LIBRARY environment variables should be encoded. ........ ................ r79400 | larry.hastings | 2010-03-24 20:57:10 -0400 (Wed, 24 Mar 2010) | 9 lines Blocked revisions 79397 via svnmerge ........ r79397 | larry.hastings | 2010-03-24 17:54:54 -0700 (Wed, 24 Mar 2010) | 4 lines Backported PyCapsule from 3.1, and converted most uses of CObject to PyCapsule. ........ ................ r79407 | benjamin.peterson | 2010-03-24 21:11:10 -0400 (Wed, 24 Mar 2010) | 12 lines Blocked revisions 79402,79406 via svnmerge ........ r79402 | benjamin.peterson | 2010-03-24 20:03:51 -0500 (Wed, 24 Mar 2010) | 1 line set bsddb eol style ........ r79406 | benjamin.peterson | 2010-03-24 20:05:57 -0500 (Wed, 24 Mar 2010) | 1 line fix eol properties on capsule files ........ ................ r79411 | larry.hastings | 2010-03-24 21:25:31 -0400 (Wed, 24 Mar 2010) | 8 lines Blocked revisions 79410 via svnmerge ........ r79410 | larry.hastings | 2010-03-24 18:23:27 -0700 (Wed, 24 Mar 2010) | 2 lines Remove extraneous experimental code checked in by accident. ........ ................ r79414 | benjamin.peterson | 2010-03-24 23:46:05 -0400 (Wed, 24 Mar 2010) | 8 lines Blocked revisions 79413 via svnmerge ........ r79413 | benjamin.peterson | 2010-03-24 22:44:24 -0500 (Wed, 24 Mar 2010) | 1 line make an attempt to add capsule to the Windows build ........ ................ r79454 | michael.foord | 2010-03-26 21:41:24 -0400 (Fri, 26 Mar 2010) | 8 lines Blocked revisions 79432 via svnmerge ........ r79432 | michael.foord | 2010-03-25 23:56:33 +0000 (Thu, 25 Mar 2010) | 1 line Turn unittest tests into a package ........ ................ r79462 | michael.foord | 2010-03-27 08:41:09 -0400 (Sat, 27 Mar 2010) | 8 lines Blocked revisions 79433 via svnmerge ........ r79433 | michael.foord | 2010-03-26 00:03:38 +0000 (Fri, 26 Mar 2010) | 1 line Remove incorrect docstring in unittest.test ........ ................ r79463 | michael.foord | 2010-03-27 08:49:01 -0400 (Sat, 27 Mar 2010) | 8 lines Blocked revisions 79436 via svnmerge ........ r79436 | michael.foord | 2010-03-26 02:53:56 +0000 (Fri, 26 Mar 2010) | 1 line Move a support TestCase out of the main namespace in unittest.test.test_suite ........ ................ r79467 | michael.foord | 2010-03-27 09:29:35 -0400 (Sat, 27 Mar 2010) | 8 lines Blocked revisions 79443 via svnmerge ........ r79443 | benjamin.peterson | 2010-03-26 13:53:32 +0000 (Fri, 26 Mar 2010) | 1 line reorder imports ........ ................ r79505 | antoine.pitrou | 2010-03-30 14:59:21 -0400 (Tue, 30 Mar 2010) | 8 lines Blocked revisions 79504 via svnmerge ........ r79504 | antoine.pitrou | 2010-03-30 20:58:22 +0200 (mar., 30 mars 2010) | 3 lines Fix small error in r79502 ........ ................ r79591 | larry.hastings | 2010-04-02 07:03:37 -0400 (Fri, 02 Apr 2010) | 16 lines Blocked revisions 79590 via svnmerge ........ r79590 | larry.hastings | 2010-04-02 04:01:35 -0700 (Fri, 02 Apr 2010) | 10 lines Capsule-related changes: * PyCObject_AsVoidPtr() can now open capsules. This addresses most of the remaining backwards-compatibility concerns about the conversion of Python 2.7 from CObjects to capsules. * CObjects were marked Pending Deprecation. * Documentation about this pending deprecation was added to cobject.h. * The capsule source files were added to the legacy PC build processes. ........ ................ r79593 | larry.hastings | 2010-04-02 07:20:07 -0400 (Fri, 02 Apr 2010) | 9 lines Blocked revisions 79592 via svnmerge ........ r79592 | larry.hastings | 2010-04-02 04:18:17 -0700 (Fri, 02 Apr 2010) | 3 lines Issue #8235: _socket: Add the constant ``SO_SETFIB``. SO_SETFIB is a socket option available on FreeBSD 7.1 and newer. ........ ................ r79628 | ezio.melotti | 2010-04-02 18:15:23 -0400 (Fri, 02 Apr 2010) | 8 lines Blocked revisions 79582 via svnmerge ........ r79582 | georg.brandl | 2010-04-02 11:51:31 +0300 (Fri, 02 Apr 2010) | 1 line Fix typo in unicode character name. ........ ................ r79641 | benjamin.peterson | 2010-04-02 21:02:00 -0400 (Fri, 02 Apr 2010) | 14 lines Blocked revisions 79636,79639 via svnmerge ........ r79636 | benjamin.peterson | 2010-04-02 18:59:41 -0500 (Fri, 02 Apr 2010) | 4 lines always check _PyString_Resize for error also normalize how this error is checked ........ r79639 | benjamin.peterson | 2010-04-02 19:57:33 -0500 (Fri, 02 Apr 2010) | 1 line more _PyString_Resize error checking ........ ................ r79656 | victor.stinner | 2010-04-03 04:43:28 -0400 (Sat, 03 Apr 2010) | 11 lines Blocked revisions 79654 via svnmerge ........ r79654 | victor.stinner | 2010-04-03 10:40:16 +0200 (sam., 03 avril 2010) | 5 lines Issue #8227: Fix C API documentation, argument parsing * 'z', 'z#', 'z*' does also accept Unicode * unify types name: replace "string or Unicode objet" by "string or Unicode" ........ ................ r79694 | ezio.melotti | 2010-04-03 11:39:17 -0400 (Sat, 03 Apr 2010) | 8 lines Blocked revisions 79624 via svnmerge ........ r79624 | ezio.melotti | 2010-04-03 00:43:10 +0300 (Sat, 03 Apr 2010) | 1 line Fix test_compiler.py that was using unittest.__file__ to find Lib/ (unittest is now a package). ........ ................ r79696 | benjamin.peterson | 2010-04-03 11:42:04 -0400 (Sat, 03 Apr 2010) | 12 lines Blocked revisions 79693,79695 via svnmerge ........ r79693 | benjamin.peterson | 2010-04-03 10:38:38 -0500 (Sat, 03 Apr 2010) | 1 line wrap ........ r79695 | benjamin.peterson | 2010-04-03 10:40:29 -0500 (Sat, 03 Apr 2010) | 1 line remove unneeded argument ........ ................ r79705 | benjamin.peterson | 2010-04-03 12:01:50 -0400 (Sat, 03 Apr 2010) | 16 lines Blocked revisions 79697-79698,79704 via svnmerge ........ r79697 | benjamin.peterson | 2010-04-03 10:44:56 -0500 (Sat, 03 Apr 2010) | 1 line silence PyCObject warnings in bsddb ........ r79698 | benjamin.peterson | 2010-04-03 10:45:59 -0500 (Sat, 03 Apr 2010) | 1 line spelling ........ r79704 | benjamin.peterson | 2010-04-03 10:58:15 -0500 (Sat, 03 Apr 2010) | 1 line remove deprecation warnings silence attempting ........ ................ r79708 | mark.dickinson | 2010-04-03 12:42:09 -0400 (Sat, 03 Apr 2010) | 11 lines Blocked revisions 79707 via svnmerge ........ r79707 | mark.dickinson | 2010-04-03 17:41:20 +0100 (Sat, 03 Apr 2010) | 5 lines Ensure 'module removed' warning messages contain the word 'module' or 'package'. This should fix the test_py3kwarn failure on OS X. test_support.import_module also requires this. ........ ................ r79715 | mark.dickinson | 2010-04-03 14:18:44 -0400 (Sat, 03 Apr 2010) | 8 lines Blocked revisions 79714 via svnmerge ........ r79714 | mark.dickinson | 2010-04-03 19:17:54 +0100 (Sat, 03 Apr 2010) | 1 line Silence DeprecationWarnings from uses of has_key and <> in plat-mac. ........ ................ r79720 | benjamin.peterson | 2010-04-03 17:57:26 -0400 (Sat, 03 Apr 2010) | 8 lines Blocked revisions 79712 via svnmerge ........ r79712 | raymond.hettinger | 2010-04-03 12:10:05 -0500 (Sat, 03 Apr 2010) | 1 line Silence a compiler warning. ........ ................ r79721 | benjamin.peterson | 2010-04-03 18:11:20 -0400 (Sat, 03 Apr 2010) | 12 lines Blocked revisions 79718-79719 via svnmerge ........ r79718 | antoine.pitrou | 2010-04-03 16:42:18 -0500 (Sat, 03 Apr 2010) | 3 lines Remove useless (?) import from r79706 ........ r79719 | benjamin.peterson | 2010-04-03 16:50:40 -0500 (Sat, 03 Apr 2010) | 1 line import bsddb more robustly ........ ................ r79770 | benjamin.peterson | 2010-04-04 19:25:45 -0400 (Sun, 04 Apr 2010) | 8 lines Blocked revisions 79769 via svnmerge ........ r79769 | benjamin.peterson | 2010-04-04 18:23:22 -0500 (Sun, 04 Apr 2010) | 1 line fix dis on new style classes #8310 ........ ................ r79933 | benjamin.peterson | 2010-04-10 14:57:52 -0400 (Sat, 10 Apr 2010) | 20 lines Blocked revisions 79927-79928,79930,79932 via svnmerge ........ r79927 | benjamin.peterson | 2010-04-10 11:22:05 -0500 (Sat, 10 Apr 2010) | 1 line bump version to 2.7b1 ........ r79928 | benjamin.peterson | 2010-04-10 11:28:34 -0500 (Sat, 10 Apr 2010) | 1 line update pydoc-topics ........ r79930 | raymond.hettinger | 2010-04-10 11:57:36 -0500 (Sat, 10 Apr 2010) | 1 line Issue 8361: Remove assert from functools.total_ordering ........ r79932 | benjamin.peterson | 2010-04-10 13:53:58 -0500 (Sat, 10 Apr 2010) | 1 line towards beta 2 ........ ................ r79948 | benjamin.peterson | 2010-04-10 22:17:08 -0400 (Sat, 10 Apr 2010) | 162 lines Blocked revisions 79285,79292,79384,79387,79480-79481,79483,79509,79511,79528,79549,79569,79575-79578,79625,79650-79651,79706,79710,79713,79722,79730,79744,79750,79755,79808,79915,79918,79920,79937,79939 via svnmerge ................ r79285 | jesus.cea | 2010-03-22 09:22:26 -0500 (Mon, 22 Mar 2010) | 1 line pybsddb 4.8.4 integration. Please, comment in issue #8156 ................ r79292 | jesus.cea | 2010-03-22 10:18:46 -0500 (Mon, 22 Mar 2010) | 1 line Missing testsuite files ................ r79384 | antoine.pitrou | 2010-03-24 16:55:12 -0500 (Wed, 24 Mar 2010) | 3 lines Trying to fix #8108. Will watch the buildbot(s). ................ r79387 | antoine.pitrou | 2010-03-24 17:12:15 -0500 (Wed, 24 Mar 2010) | 3 lines Revert r79384 (the fix failed). ................ r79480 | raymond.hettinger | 2010-03-28 13:02:41 -0500 (Sun, 28 Mar 2010) | 1 line Update itertools recipes. ................ r79481 | raymond.hettinger | 2010-03-28 13:08:15 -0500 (Sun, 28 Mar 2010) | 1 line Add a note on optimizing the itertools recipes for production. ................ r79483 | raymond.hettinger | 2010-03-28 13:25:01 -0500 (Sun, 28 Mar 2010) | 1 line Update itertools recipe for consume(). ................ r79509 | thomas.heller | 2010-03-30 14:46:23 -0500 (Tue, 30 Mar 2010) | 24 lines Merged revisions 79115,79424,79491 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/branch_libffi-3_0_10-win ........ r79115 | thomas.heller | 2010-03-19 22:14:47 +0100 (Fr, 19 Mrz 2010) | 7 lines Work in progress. 2 tests fail on x86/win32 because the stack checking code in ffi_call_win32 is not yet implemented. Remove most files from _ctypes/libffi_msvc, only two include files stay (updated from _ctypes/libffi/...). Other files are used in the cross-platform _ctypes/libffi directory. ........ r79424 | thomas.heller | 2010-03-25 19:28:02 +0100 (Do, 25 Mrz 2010) | 1 line Build _ctypes on Win64. ........ r79491 | thomas.heller | 2010-03-29 21:30:33 +0200 (Mo, 29 Mrz 2010) | 4 lines On Windows, ctypes does no longer check the stack before and after calling a foreign function. This allows to use the unmodified libffi library. ........ ................ r79511 | thomas.heller | 2010-03-30 14:55:34 -0500 (Tue, 30 Mar 2010) | 3 lines Removed merge tracking for "svnmerge" for svn+ssh://pythondev at svn.python.org/python/branches/branch_libffi-3_0_10-win ................ r79528 | ezio.melotti | 2010-03-31 03:33:50 -0500 (Wed, 31 Mar 2010) | 1 line Silence a py3k warning. ................ r79549 | raymond.hettinger | 2010-04-01 02:54:16 -0500 (Thu, 01 Apr 2010) | 1 line Document link to Sorting HowTo ................ r79569 | raymond.hettinger | 2010-04-01 21:44:31 -0500 (Thu, 01 Apr 2010) | 1 line Add and update itertools recipes. ................ r79575 | raymond.hettinger | 2010-04-02 01:23:12 -0500 (Fri, 02 Apr 2010) | 1 line Cleanup itertools recipes ................ r79576 | florent.xicluna | 2010-04-02 02:24:52 -0500 (Fri, 02 Apr 2010) | 2 lines #7092: Fix additional "-3" warnings in the idlelib package, and convert to absolute imports. ................ r79577 | florent.xicluna | 2010-04-02 03:15:26 -0500 (Fri, 02 Apr 2010) | 2 lines #7092: Drop the cmp argument. ................ r79578 | florent.xicluna | 2010-04-02 03:30:21 -0500 (Fri, 02 Apr 2010) | 2 lines #7092: silence some py3k warnings ................ r79625 | brian.curtin | 2010-04-02 16:51:37 -0500 (Fri, 02 Apr 2010) | 2 lines Add a line about #7347 to Misc\News ................ r79650 | raymond.hettinger | 2010-04-02 22:14:28 -0500 (Fri, 02 Apr 2010) | 1 line Improve clear() method. Keeps key/value refcnts >= 1 until final dict.clear() so that decrefs to zero won't trigger arbitrary code . Also runs a bit faster. ................ r79651 | raymond.hettinger | 2010-04-03 02:57:09 -0500 (Sat, 03 Apr 2010) | 1 line Factor-out constant expressions ................ r79706 | benjamin.peterson | 2010-04-03 11:06:42 -0500 (Sat, 03 Apr 2010) | 1 line stop CObject deprecation warnings in test___all__ ................ r79710 | mark.dickinson | 2010-04-03 11:54:02 -0500 (Sat, 03 Apr 2010) | 1 line Replace backquotes with repr(), to silence a SyntaxWarning. ................ r79713 | raymond.hettinger | 2010-04-03 13:10:37 -0500 (Sat, 03 Apr 2010) | 1 line Add count() method to collections.deque(). ................ r79722 | raymond.hettinger | 2010-04-03 17:34:15 -0500 (Sat, 03 Apr 2010) | 1 line Expand test coverage for deque.count(). ................ r79730 | raymond.hettinger | 2010-04-03 20:24:59 -0500 (Sat, 03 Apr 2010) | 1 line Issue 5479: Add functools.total_ordering class decorator. ................ r79744 | raymond.hettinger | 2010-04-04 02:33:46 -0500 (Sun, 04 Apr 2010) | 1 line Documentation nit ................ r79750 | raymond.hettinger | 2010-04-04 13:34:45 -0500 (Sun, 04 Apr 2010) | 1 line Add functools.CmpToKey() ................ r79755 | raymond.hettinger | 2010-04-04 16:45:01 -0500 (Sun, 04 Apr 2010) | 6 lines Add tests for cmp_to_key. Adopt PEP 8 compliant function name. Factor-out existing uses cmp_to_key. Update documentation to use internal pointers instead of external resource. ................ r79808 | raymond.hettinger | 2010-04-05 13:53:43 -0500 (Mon, 05 Apr 2010) | 1 line Classes that override __eq__ also need to define __hash__. ................ r79915 | antoine.pitrou | 2010-04-09 16:00:36 -0500 (Fri, 09 Apr 2010) | 3 lines Temporarily commit fix to issue #8108, to check for buildbot response ................ r79918 | antoine.pitrou | 2010-04-09 17:41:31 -0500 (Fri, 09 Apr 2010) | 3 lines Revert r79915 (temporary commit to check for buildbots -> the fix was successful) ................ r79920 | raymond.hettinger | 2010-04-10 02:01:32 -0500 (Sat, 10 Apr 2010) | 1 line Fixup new itertools recipes. ................ r79937 | antoine.pitrou | 2010-04-10 17:43:05 -0500 (Sat, 10 Apr 2010) | 3 lines Temporary commit of fix to issue #5380 (in order to watch buildbot response) ................ r79939 | raymond.hettinger | 2010-04-10 19:01:23 -0500 (Sat, 10 Apr 2010) | 1 line Add the sorting HOWTO to the main docs. ................ ................ r79953 | benjamin.peterson | 2010-04-11 10:49:17 -0400 (Sun, 11 Apr 2010) | 12 lines Blocked revisions 79938,79949 via svnmerge ........ r79938 | antoine.pitrou | 2010-04-10 18:32:12 -0500 (Sat, 10 Apr 2010) | 3 lines Revert temporary commit in r79937 ........ r79949 | raymond.hettinger | 2010-04-11 03:14:45 -0500 (Sun, 11 Apr 2010) | 1 line Add descriptor howto to main documentation ........ ................ r79955 | benjamin.peterson | 2010-04-11 11:41:33 -0400 (Sun, 11 Apr 2010) | 20 lines Blocked revisions 79493,79515,79637,79760 via svnmerge ........ r79493 | michael.foord | 2010-03-29 15:04:23 -0500 (Mon, 29 Mar 2010) | 1 line Backport of weakref.WeakSet and tests from Python 3. ........ r79515 | thomas.heller | 2010-03-30 15:57:06 -0500 (Tue, 30 Mar 2010) | 1 line Revert rev. 79509; ctypes doesn't build on linux. ........ r79637 | raymond.hettinger | 2010-04-02 19:39:26 -0500 (Fri, 02 Apr 2010) | 1 line Clear cyclical references in list based OrderedDict. ........ r79760 | raymond.hettinger | 2010-04-04 17:24:03 -0500 (Sun, 04 Apr 2010) | 1 line Add tests for functools.total_ordering. ........ ................ r79966 | benjamin.peterson | 2010-04-11 16:49:42 -0400 (Sun, 11 Apr 2010) | 8 lines Blocked revisions 79962 via svnmerge ........ r79962 | raymond.hettinger | 2010-04-11 15:39:28 -0500 (Sun, 11 Apr 2010) | 1 line Minor factoring ........ ................ r79967 | benjamin.peterson | 2010-04-11 17:03:55 -0400 (Sun, 11 Apr 2010) | 15 lines Blocked revisions 79935 via svnmerge ........ r79935 | jean-paul.calderone | 2010-04-10 14:59:28 -0500 (Sat, 10 Apr 2010) | 9 lines Refactor a couple inspect module tests to remove duplicate code The test_classify_oldstyle and test_classify_newstyle methods of test.test_inspect.TestClassesAndFunctions were previously almost identical (aside from irrelevant whitespace and one semantic difference). They now share a single helper. Fixes issue #8363. ........ ................ r79972 | benjamin.peterson | 2010-04-11 17:56:02 -0400 (Sun, 11 Apr 2010) | 8 lines Blocked revisions 79307 via svnmerge ........ r79307 | florent.xicluna | 2010-03-22 17:45:50 -0500 (Mon, 22 Mar 2010) | 2 lines #7667: Fix doctest failures with non-ASCII paths. ........ ................ r80019 | benjamin.peterson | 2010-04-12 17:18:30 -0400 (Mon, 12 Apr 2010) | 8 lines Blocked revisions 80017 via svnmerge ........ r80017 | raymond.hettinger | 2010-04-12 16:12:06 -0500 (Mon, 12 Apr 2010) | 1 line Add usage notes for collections.Counter(). ........ ................ r80083 | georg.brandl | 2010-04-14 17:42:41 -0400 (Wed, 14 Apr 2010) | 8 lines Blocked revisions 80082 via svnmerge ........ r80082 | georg.brandl | 2010-04-14 23:36:49 +0200 (Mi, 14 Apr 2010) | 1 line #8370: fix module name in backported doc addition. ........ ................ r80122 | benjamin.peterson | 2010-04-16 17:56:43 -0400 (Fri, 16 Apr 2010) | 8 lines Blocked revisions 80121 via svnmerge ........ r80121 | benjamin.peterson | 2010-04-16 16:55:10 -0500 (Fri, 16 Apr 2010) | 1 line remove check for unicode ........ ................ r80206 | benjamin.peterson | 2010-04-18 19:08:30 -0400 (Sun, 18 Apr 2010) | 8 lines Blocked revisions 80202 via svnmerge ........ r80202 | raymond.hettinger | 2010-04-18 17:57:57 -0500 (Sun, 18 Apr 2010) | 1 line Issue 8436: set.__init__ accepts keyword args ........ ................ r80217 | antoine.pitrou | 2010-04-19 15:38:22 -0400 (Mon, 19 Apr 2010) | 9 lines Blocked revisions 80215 via svnmerge ........ r80215 | antoine.pitrou | 2010-04-19 20:52:43 +0200 (lun., 19 avril 2010) | 4 lines Issue #8438: Remove reference to the missing "surrogateescape" encoding error handler from the new IO library. ........ ................ r80272 | ezio.melotti | 2010-04-20 12:57:51 -0400 (Tue, 20 Apr 2010) | 8 lines Blocked revisions 80270 via svnmerge ........ r80270 | ezio.melotti | 2010-04-20 19:49:48 +0300 (Tue, 20 Apr 2010) | 1 line #8472: fix wrong function name in functions.rst: itertools.filterfalse -> itertools.ifilterfalse ........ ................ r80493 | brett.cannon | 2010-04-25 18:35:57 -0400 (Sun, 25 Apr 2010) | 12 lines Blocked revisions 80492 via svnmerge ........ r80492 | brett.cannon | 2010-04-25 15:33:36 -0700 (Sun, 25 Apr 2010) | 6 lines When DeprecationWarning was silenced by default, it also silenced any use of -Q by default as well. This change fixes that by treating -Q like -3 when it comes to DeprecationWarning; using it causes the silencing to not occur. Fixes issue #7319. ........ ................ r80497 | benjamin.peterson | 2010-04-25 19:18:00 -0400 (Sun, 25 Apr 2010) | 8 lines Blocked revisions 80496 via svnmerge ........ r80496 | brett.cannon | 2010-04-25 18:11:51 -0500 (Sun, 25 Apr 2010) | 1 line Revert an accidental commit from r80492. ........ ................ r80550 | benjamin.peterson | 2010-04-27 17:19:15 -0400 (Tue, 27 Apr 2010) | 12 lines Blocked revisions 80546-80547 via svnmerge ........ r80546 | benjamin.peterson | 2010-04-27 16:15:28 -0500 (Tue, 27 Apr 2010) | 1 line fix comment ........ r80547 | benjamin.peterson | 2010-04-27 16:17:22 -0500 (Tue, 27 Apr 2010) | 1 line fold __future__ imports ........ ................ r80697 | mark.dickinson | 2010-05-02 05:40:10 -0400 (Sun, 02 May 2010) | 8 lines Blocked revisions 80695 via svnmerge ........ r80695 | mark.dickinson | 2010-05-02 10:38:43 +0100 (Sun, 02 May 2010) | 2 lines Improve error message from nb_int returning a non-integer, in various PyInt_As* functions: ........ ................ r80740 | benjamin.peterson | 2010-05-03 20:36:36 -0400 (Mon, 03 May 2010) | 10 lines Blocked revisions 80738 via svnmerge ........ r80738 | brett.cannon | 2010-05-03 19:30:17 -0500 (Mon, 03 May 2010) | 4 lines Remove a redundant string length check and variable assignment. Found with Clang's static analyzer. ........ ................ r80750 | alexandre.vassalotti | 2010-05-03 23:26:10 -0400 (Mon, 03 May 2010) | 8 lines Blocked revisions 80749 via svnmerge ........ r80749 | alexandre.vassalotti | 2010-05-03 20:21:51 -0700 (Mon, 03 May 2010) | 2 lines Issue #8404: Fix set operations on dictionary views. ........ ................ r80760 | mark.dickinson | 2010-05-04 12:50:06 -0400 (Tue, 04 May 2010) | 18 lines Blocked revisions 80758-80759 via svnmerge ........ r80758 | mark.dickinson | 2010-05-04 17:18:25 +0100 (Tue, 04 May 2010) | 9 lines Issue #1533: fix inconsistency in range function argument processing: any non-float non-integer argument is now converted to an integer (if possible) using its __int__ method. Previously, only small arguments were treated this way; larger arguments (those whose __int__ was outside the range of a C long) would produce a TypeError. Patch by Alexander Belopolsky (with minor modifications). ........ r80759 | mark.dickinson | 2010-05-04 17:19:06 +0100 (Tue, 04 May 2010) | 1 line Fix trailing whitespace. ........ ................ r80778 | victor.stinner | 2010-05-05 08:42:20 -0400 (Wed, 05 May 2010) | 9 lines Blocked revisions 80777 via svnmerge ........ r80777 | victor.stinner | 2010-05-05 14:40:49 +0200 (mer., 05 mai 2010) | 3 lines Issue #8313: traceback.format_exception_only() encodes unicode message to ASCII with backslashreplace error handler if str(value) failed ........ ................ r80806 | ronald.oussoren | 2010-05-05 15:12:30 -0400 (Wed, 05 May 2010) | 14 lines Blocked revisions 80804 via svnmerge ........ r80804 | ronald.oussoren | 2010-05-05 21:09:31 +0200 (Wed, 05 May 2010) | 8 lines In a number of places code still revers to "sys.platform == 'mac'" and that is dead code because it refers to a platform that is no longer supported (and hasn't been supported for several releases). Fixes issue #7908 for the trunk. ........ ................ r80842 | mark.dickinson | 2010-05-05 18:44:34 -0400 (Wed, 05 May 2010) | 9 lines Blocked revisions 80839 via svnmerge ........ r80839 | mark.dickinson | 2010-05-05 23:42:51 +0100 (Wed, 05 May 2010) | 3 lines Issue #1533: test_range in test_builtin: fix test comment and add test for rejection of small floats. Thanks Alexander Belopolsky. ........ ................ r80973 | matthias.klose | 2010-05-08 07:12:56 -0400 (Sat, 08 May 2010) | 27 lines Blocked revisions 80964-80966,80969-80970 via svnmerge ........ r80964 | matthias.klose | 2010-05-08 12:00:28 +0200 (Sa, 08 Mai 2010) | 2 lines - Issue #8510: Update to autoconf2.65. ........ r80965 | matthias.klose | 2010-05-08 12:14:46 +0200 (Sa, 08 Mai 2010) | 2 lines - configure.in: Replace AC_HELP_STRING with AS_HELP_STRING ........ r80966 | matthias.klose | 2010-05-08 12:17:27 +0200 (Sa, 08 Mai 2010) | 2 lines configure.in: s/AC_AIX/AC_USE_SYSTEM_EXTENSIONS/ ........ r80969 | matthias.klose | 2010-05-08 13:01:39 +0200 (Sa, 08 Mai 2010) | 3 lines configure.in: convert all obsolete AC_TRY_* macros to AC_*_IFELSE, only whitespace changes in generated configure (diff -uEwB). ........ r80970 | matthias.klose | 2010-05-08 13:04:18 +0200 (Sa, 08 Mai 2010) | 4 lines configure.in: Avoid autoconf warning: Assume C89 semantics that RETSIGTYPE is always void (issue #8510). pyconfig.h: Regenerate ........ ................ r81003 | benjamin.peterson | 2010-05-08 14:57:34 -0400 (Sat, 08 May 2010) | 16 lines Blocked revisions 80996,80998,81002 via svnmerge ........ r80996 | benjamin.peterson | 2010-05-08 12:05:19 -0500 (Sat, 08 May 2010) | 1 line update pydoc-topics ........ r80998 | benjamin.peterson | 2010-05-08 12:08:17 -0500 (Sat, 08 May 2010) | 1 line bump version to 2.7 beta 2 ........ r81002 | benjamin.peterson | 2010-05-08 13:53:42 -0500 (Sat, 08 May 2010) | 1 line towards 2.7 release candidate 1 ........ ................ r81009 | benjamin.peterson | 2010-05-08 17:03:44 -0400 (Sat, 08 May 2010) | 8 lines Blocked revisions 81008 via svnmerge ........ r81008 | benjamin.peterson | 2010-05-08 15:59:42 -0500 (Sat, 08 May 2010) | 1 line remove svn:mergeinfo property ........ ................ r81021 | mark.dickinson | 2010-05-09 05:30:53 -0400 (Sun, 09 May 2010) | 9 lines Blocked revisions 81020 via svnmerge ........ r81020 | mark.dickinson | 2010-05-09 10:30:06 +0100 (Sun, 09 May 2010) | 3 lines Issue #8644: Improve accuracy of timedelta.total_seconds method. (Backport of r80979 to py3k.) Thanks Alexander Belopolsky. ........ ................ r81028 | eric.smith | 2010-05-09 10:09:25 -0400 (Sun, 09 May 2010) | 8 lines Blocked revisions 81026 via svnmerge ........ r81026 | eric.smith | 2010-05-09 10:04:59 -0400 (Sun, 09 May 2010) | 1 line Issue 8671: Whitespace fix. ........ ................ r81136 | victor.stinner | 2010-05-13 12:20:26 -0400 (Thu, 13 May 2010) | 12 lines Blocked revisions 81135 via svnmerge (r81135 is a merge of r80163 from py3k) ........ r81135 | victor.stinner | 2010-05-13 18:18:14 +0200 (jeu., 13 mai 2010) | 6 lines Issue #8422, test_genericpath: skip the creation of a directory with an invalid UTF name on Mac OS X because the OS deny it (the name have to be a valid UTF8 string). Merge r80163 from py3k branch. ........ ................ r81138 | victor.stinner | 2010-05-13 12:23:09 -0400 (Thu, 13 May 2010) | 10 lines Blocked revisions 81137 via svnmerge ........ r81137 | victor.stinner | 2010-05-13 18:22:15 +0200 (jeu., 13 mai 2010) | 4 lines Fix verb tense in skip message. Ooops, merge also r80334 (patch by r.david.murray) ........ ................ r81211 | amaury.forgeotdarc | 2010-05-15 17:49:45 -0400 (Sat, 15 May 2010) | 8 lines Blocked revisions 81210 via svnmerge ........ r81210 | amaury.forgeotdarc | 2010-05-15 23:45:30 +0200 (sam., 15 mai 2010) | 2 lines Remove unused variable, and fix a compilation warning on Windows ........ ................ r81378 | victor.stinner | 2010-05-20 07:30:37 -0400 (Thu, 20 May 2010) | 14 lines Blocked revisions 81377 via svnmerge ........ r81377 | victor.stinner | 2010-05-20 13:29:45 +0200 (jeu., 20 mai 2010) | 8 lines libpython.py: fix support of non-BMP unicode characters Forward port some code from Python3: * join surrogate pairs if sizeof(Py_UNICODE)==2 * Enable non-BMP test on narrow builds using u"\U0001D121" instead of unichr(0x1D121) ........ ................ r81424 | georg.brandl | 2010-05-21 17:03:02 -0400 (Fri, 21 May 2010) | 8 lines Blocked revisions 81419 via svnmerge ........ r81419 | georg.brandl | 2010-05-21 22:58:12 +0200 (Fr, 21 Mai 2010) | 1 line Add missing parameter in SimpleXMLRPCServer signature. ........ ................ r81455 | victor.stinner | 2010-05-21 18:52:10 -0400 (Fri, 21 May 2010) | 9 lines Blocked revisions 81454 via svnmerge ........ r81454 | victor.stinner | 2010-05-22 00:50:28 +0200 (sam., 22 mai 2010) | 3 lines Issue #5640: Fix Shift-JIS incremental encoder for error handlers different than strict ........ ................ r81511 | benjamin.peterson | 2010-05-24 22:27:55 -0400 (Mon, 24 May 2010) | 8 lines Blocked revisions 81509 via svnmerge ........ r81509 | benjamin.peterson | 2010-05-24 21:23:32 -0500 (Mon, 24 May 2010) | 1 line correct default docs ........ ................ r81519 | r.david.murray | 2010-05-25 11:26:21 -0400 (Tue, 25 May 2010) | 13 lines Blocked revisions 81518 via svnmerge ........ r81518 | r.david.murray | 2010-05-25 11:20:46 -0400 (Tue, 25 May 2010) | 8 lines Issue 8143: sync unquote in urlparse with urllib; add comment about doing so. unquote is duplicated in the two files to avoid a circular reference. (This is fixed in Python3.) Updates keep getting made to the public unquote without fixing the urlparse one, however, so this fix syncs the two and adds a comment to both to make sure changes are applied to both. ........ ................ r81538 | victor.stinner | 2010-05-25 18:35:40 -0400 (Tue, 25 May 2010) | 11 lines Blocked revisions 81537 via svnmerge ........ r81537 | victor.stinner | 2010-05-26 00:30:32 +0200 (mer., 26 mai 2010) | 3 lines Issue #3798: Write sys.exit() message to sys.stderr to use stderr encoding and error handler, instead of writing to the C stderr file in utf-8 ........ py3k was already fixed by r81252. ................ r81581 | benjamin.peterson | 2010-05-27 23:23:57 -0400 (Thu, 27 May 2010) | 12 lines Blocked revisions 81578-81579 via svnmerge ........ r81578 | benjamin.peterson | 2010-05-27 21:12:36 -0500 (Thu, 27 May 2010) | 1 line remove non-ascii coding per PEP 8 ........ r81579 | benjamin.peterson | 2010-05-27 22:10:31 -0500 (Thu, 27 May 2010) | 1 line 2to3 doesn't fix test_support #6583 ........ ................ r81607 | mark.dickinson | 2010-05-30 08:12:56 -0400 (Sun, 30 May 2010) | 10 lines Blocked revisions 81606 via svnmerge ........ r81606 | mark.dickinson | 2010-05-30 13:12:25 +0100 (Sun, 30 May 2010) | 4 lines Issue #5211: Complete removal of implicit coercions for the complex type. Coercion for arithmetic operations was already removed in r78280, but that commit didn't remove coercion for rich comparisons. ........ ................ r81609 | mark.dickinson | 2010-05-30 08:17:39 -0400 (Sun, 30 May 2010) | 8 lines Blocked revisions 81608 via svnmerge ........ r81608 | mark.dickinson | 2010-05-30 13:17:11 +0100 (Sun, 30 May 2010) | 1 line Remove declaration for unused variable. ........ ................ r81737 | mark.dickinson | 2010-06-05 07:53:11 -0400 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81736 via svnmerge ........ r81736 | mark.dickinson | 2010-06-05 12:52:24 +0100 (Sat, 05 Jun 2010) | 1 line Issue #8627: remove out-of-date warning about overriding __cmp__ ........ ................ r81743 | mark.dickinson | 2010-06-05 08:38:00 -0400 (Sat, 05 Jun 2010) | 10 lines Blocked revisions 81740 via svnmerge ........ r81740 | mark.dickinson | 2010-06-05 13:14:43 +0100 (Sat, 05 Jun 2010) | 5 lines Issue #8627: Fix "XXX undetected error" from unchecked PyErr_WarnPy3k return. This is just a quick fix: if the warning is turned into an exception, the exception simply gets ignored. ........ ................ r81746 | mark.dickinson | 2010-06-05 08:52:23 -0400 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81744 via svnmerge ........ r81744 | mark.dickinson | 2010-06-05 13:51:21 +0100 (Sat, 05 Jun 2010) | 1 line Fix comment typo. ........ ................ r81751 | mark.dickinson | 2010-06-05 09:27:17 -0400 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81749 via svnmerge ........ r81749 | mark.dickinson | 2010-06-05 14:18:33 +0100 (Sat, 05 Jun 2010) | 2 lines Fix test_py3kwarn not to test for __cmp__-related DeprecationWarning. ........ ................ r81762 | michael.foord | 2010-06-05 15:58:25 -0400 (Sat, 05 Jun 2010) | 8 lines Blocked revisions 81761 via svnmerge ........ r81761 | michael.foord | 2010-06-05 20:51:38 +0100 (Sat, 05 Jun 2010) | 1 line Updated NEWS file. ........ ................ r81778 | benjamin.peterson | 2010-06-05 22:14:27 -0400 (Sat, 05 Jun 2010) | 16 lines Blocked revisions 81772-81773,81777 via svnmerge ........ r81772 | benjamin.peterson | 2010-06-05 19:22:09 -0500 (Sat, 05 Jun 2010) | 1 line bump version to 2.7 rc1 ........ r81773 | benjamin.peterson | 2010-06-05 19:49:27 -0500 (Sat, 05 Jun 2010) | 1 line update pydoc-topics ........ r81777 | benjamin.peterson | 2010-06-05 21:09:33 -0500 (Sat, 05 Jun 2010) | 1 line careening towards 2.7rc2 we go ........ ................ r81816 | ezio.melotti | 2010-06-07 17:57:18 -0400 (Mon, 07 Jun 2010) | 8 lines Blocked revisions 81769 via svnmerge ........ r81769 | ezio.melotti | 2010-06-06 01:28:10 +0300 (Sun, 06 Jun 2010) | 1 line Replace deprecated fail* methods with the equivalent assert* ones. ........ ................ r81818 | ezio.melotti | 2010-06-07 18:02:50 -0400 (Mon, 07 Jun 2010) | 8 lines Blocked revisions 81817 via svnmerge ........ r81817 | ezio.melotti | 2010-06-08 01:00:18 +0300 (Tue, 08 Jun 2010) | 1 line Silence deprecation warning in test___all__ caused by an import bsddb. ........ ................ r81827 | benjamin.peterson | 2010-06-07 18:36:44 -0400 (Mon, 07 Jun 2010) | 8 lines Blocked revisions 81825 via svnmerge ........ r81825 | benjamin.peterson | 2010-06-07 17:33:09 -0500 (Mon, 07 Jun 2010) | 1 line use unicode literals ........ ................ r81829 | stefan.krah | 2010-06-08 09:26:49 -0400 (Tue, 08 Jun 2010) | 21 lines Blocked revisions 81669,81672,81683 via svnmerge ........ r81669 | stefan.krah | 2010-06-03 14:39:50 +0200 (Thu, 03 Jun 2010) | 9 lines Issue #7384: If the system readline library is linked against ncurses, the curses module must be linked against ncurses as well. Otherwise it is not safe to load both the readline and curses modules in an application. Thanks Thomas Dickey for answering questions about ncurses/ncursesw and readline! ........ r81672 | stefan.krah | 2010-06-03 16:25:16 +0200 (Thu, 03 Jun 2010) | 3 lines Use compiler rather than compiler_obj. Thanks Michael Foord for noticing. ........ r81683 | stefan.krah | 2010-06-04 11:49:20 +0200 (Fri, 04 Jun 2010) | 1 line Detect missing ldd on all systems. ........ ................ r81877 | michael.foord | 2010-06-10 12:33:34 -0400 (Thu, 10 Jun 2010) | 8 lines Blocked revisions 81876 via svnmerge ........ r81876 | michael.foord | 2010-06-10 17:32:00 +0100 (Thu, 10 Jun 2010) | 1 line NEWS update for issue 8948. ........ ................ r81901 | victor.stinner | 2010-06-11 15:24:36 -0400 (Fri, 11 Jun 2010) | 8 lines Blocked revisions 81899 via svnmerge ........ r81899 | victor.stinner | 2010-06-11 21:22:28 +0200 (ven., 11 juin 2010) | 2 lines Issue #8362: Add Misc/maintainers.rst: list of module maintainers ........ ................ r81905 | mark.dickinson | 2010-06-11 16:29:09 -0400 (Fri, 11 Jun 2010) | 10 lines Blocked revisions 81904 via svnmerge ........ r81904 | mark.dickinson | 2010-06-11 21:27:05 +0100 (Fri, 11 Jun 2010) | 4 lines Fix possible undefined behaviour from signed overflow in struct module. Backport of revisions 81897, 81898 and 81902 from py3k. ........ ................ r81946 | nick.coghlan | 2010-06-12 09:46:56 -0400 (Sat, 12 Jun 2010) | 8 lines Blocked revisions 81945 via svnmerge ........ r81945 | nick.coghlan | 2010-06-12 23:45:37 +1000 (Sat, 12 Jun 2010) | 1 line Backport a fix from Py3k for a potentially misleading example ........ ................ r81958 | mark.dickinson | 2010-06-12 14:54:20 -0400 (Sat, 12 Jun 2010) | 11 lines Blocked revisions 81957 via svnmerge ........ r81957 | mark.dickinson | 2010-06-12 19:50:34 +0100 (Sat, 12 Jun 2010) | 5 lines Issue #8469: Add standard sizes to table in struct documentation; additional clarifications and documentation tweaks. Backport of revisions 81955-81956 from py3k. ........ ................ r82014 | r.david.murray | 2010-06-16 08:53:07 -0400 (Wed, 16 Jun 2010) | 20 lines Blocked revisions 81571,81678 via svnmerge I'm going to merge 81678 by hand. ........ r81571 | victor.stinner | 2010-05-27 18:29:48 -0400 (Thu, 27 May 2010) | 3 lines Issue #8835: test_support.transient_internet() catchs gaierror(EAI_NONAME) and gaierror(EAI_NODATA) ........ r81678 | r.david.murray | 2010-06-03 16:19:25 -0400 (Thu, 03 Jun 2010) | 7 lines #8889: rewrite transient_internet so we don't use EAI_NODATA on FreeBSD. FreeBSD doesn't have socket.EAI_NODATA. I rewrote the routine because there's no easy way to conditionally include a context manager in a with statement. As a side benefit, instead of a stack of context managers there's now only one. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Thu Jun 17 00:38:15 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Thu, 17 Jun 2010 00:38:15 +0200 (CEST) Subject: [Python-checkins] r82034 - in python/branches/py3k: Modules/_time.c Modules/_time.h Modules/timemodule.c setup.py Message-ID: <20100616223815.92DF1EECE0@mail.python.org> Author: alexander.belopolsky Date: Thu Jun 17 00:38:15 2010 New Revision: 82034 Log: Issue #9012: "Separate compilation of time and datetime modules." Segregated code shared between time and datetime modules into Modules/_time.c. Added a new header file, Modules/_time.h, which will be used instead of Include/timefuncs.h for declarations shared between time and datetime modules. Added: python/branches/py3k/Modules/_time.c python/branches/py3k/Modules/_time.h Modified: python/branches/py3k/Modules/timemodule.c python/branches/py3k/setup.py Added: python/branches/py3k/Modules/_time.c ============================================================================== --- (empty file) +++ python/branches/py3k/Modules/_time.c Thu Jun 17 00:38:15 2010 @@ -0,0 +1,28 @@ +#include "Python.h" +#include "_time.h" + +/* Exposed in timefuncs.h. */ +time_t +_PyTime_DoubleToTimet(double x) +{ + time_t result; + double diff; + + result = (time_t)x; + /* How much info did we lose? time_t may be an integral or + * floating type, and we don't know which. If it's integral, + * we don't know whether C truncates, rounds, returns the floor, + * etc. If we lost a second or more, the C rounding is + * unreasonable, or the input just doesn't fit in a time_t; + * call it an error regardless. Note that the original cast to + * time_t can cause a C error too, but nothing we can do to + * worm around that. + */ + diff = x - (double)result; + if (diff <= -1.0 || diff >= 1.0) { + PyErr_SetString(PyExc_ValueError, + "timestamp out of range for platform time_t"); + result = (time_t)-1; + } + return result; +} Added: python/branches/py3k/Modules/_time.h ============================================================================== --- (empty file) +++ python/branches/py3k/Modules/_time.h Thu Jun 17 00:38:15 2010 @@ -0,0 +1,3 @@ +/* XXX: It is probably best to move timefuncs.h content in here, and + remove it but user code may rely on it. */ +#include "timefuncs.h" Modified: python/branches/py3k/Modules/timemodule.c ============================================================================== --- python/branches/py3k/Modules/timemodule.c (original) +++ python/branches/py3k/Modules/timemodule.c Thu Jun 17 00:38:15 2010 @@ -90,32 +90,6 @@ /* For Y2K check */ static PyObject *moddict; -/* Exposed in timefuncs.h. */ -time_t -_PyTime_DoubleToTimet(double x) -{ - time_t result; - double diff; - - result = (time_t)x; - /* How much info did we lose? time_t may be an integral or - * floating type, and we don't know which. If it's integral, - * we don't know whether C truncates, rounds, returns the floor, - * etc. If we lost a second or more, the C rounding is - * unreasonable, or the input just doesn't fit in a time_t; - * call it an error regardless. Note that the original cast to - * time_t can cause a C error too, but nothing we can do to - * worm around that. - */ - diff = x - (double)result; - if (diff <= -1.0 || diff >= 1.0) { - PyErr_SetString(PyExc_ValueError, - "timestamp out of range for platform time_t"); - result = (time_t)-1; - } - return result; -} - static PyObject * time_time(PyObject *self, PyObject *unused) { Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Thu Jun 17 00:38:15 2010 @@ -450,9 +450,9 @@ depends=['_math.h'], libraries=math_libs) ) # time operations and variables - exts.append( Extension('time', ['timemodule.c'], + exts.append( Extension('time', ['timemodule.c', '_time.c'], libraries=math_libs) ) - exts.append( Extension('datetime', ['datetimemodule.c', 'timemodule.c'], + exts.append( Extension('datetime', ['datetimemodule.c', '_time.c'], libraries=math_libs) ) # fast iterator tools implemented in C exts.append( Extension("itertools", ["itertoolsmodule.c"]) ) From python-checkins at python.org Thu Jun 17 01:05:06 2010 From: python-checkins at python.org (victor.stinner) Date: Thu, 17 Jun 2010 01:05:06 +0200 (CEST) Subject: [Python-checkins] r82035 - python/branches/py3k/PCbuild/pythoncore.vcproj Message-ID: <20100616230506.6A0BDEED25@mail.python.org> Author: victor.stinner Date: Thu Jun 17 01:05:06 2010 New Revision: 82035 Log: Issue #9012: Add _time.c and _time.h to the Visual Studio project file Add these new files, added by r82034, to the pythoncore project. Modified: python/branches/py3k/PCbuild/pythoncore.vcproj Modified: python/branches/py3k/PCbuild/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PCbuild/pythoncore.vcproj (original) +++ python/branches/py3k/PCbuild/pythoncore.vcproj Thu Jun 17 01:05:06 2010 @@ -1040,6 +1040,14 @@ > + + + + From python-checkins at python.org Thu Jun 17 01:17:44 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Thu, 17 Jun 2010 01:17:44 +0200 (CEST) Subject: [Python-checkins] r82036 - python/branches/release31-maint Message-ID: <20100616231744.BDAE7EECC8@mail.python.org> Author: alexander.belopolsky Date: Thu Jun 17 01:17:44 2010 New Revision: 82036 Log: Blocked revisions 82034-82035 via svnmerge ........ r82034 | alexander.belopolsky | 2010-06-16 18:38:15 -0400 (Wed, 16 Jun 2010) | 6 lines Issue #9012: "Separate compilation of time and datetime modules." Segregated code shared between time and datetime modules into Modules/_time.c. Added a new header file, Modules/_time.h, which will be used instead of Include/timefuncs.h for declarations shared between time and datetime modules. ........ r82035 | victor.stinner | 2010-06-16 19:05:06 -0400 (Wed, 16 Jun 2010) | 4 lines Issue #9012: Add _time.c and _time.h to the Visual Studio project file Add these new files, added by r82034, to the pythoncore project. ........ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Thu Jun 17 01:24:31 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 17 Jun 2010 01:24:31 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r82028): sum=0 Message-ID: <20100616232431.D549E1771C@ns6635.ovh.net> py3k results for svn r82028 (hg cset cc88396dd91b) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog8gFDYB', '-x'] From python-checkins at python.org Thu Jun 17 01:33:54 2010 From: python-checkins at python.org (victor.stinner) Date: Thu, 17 Jun 2010 01:33:54 +0200 (CEST) Subject: [Python-checkins] r82037 - in python/branches/py3k: Doc/library/codecs.rst Lib/ctypes/__init__.py Lib/test/test_codecs.py Misc/NEWS Objects/unicodeobject.c Message-ID: <20100616233354.D4D79EEA2E@mail.python.org> Author: victor.stinner Date: Thu Jun 17 01:33:54 2010 New Revision: 82037 Log: Issue #850997: mbcs encoding (Windows only) handles errors argument: strict mode raises unicode errors. The encoder only supports "strict" and "replace" error handlers, the decoder only supports "strict" and "ignore" error handlers. Modified: python/branches/py3k/Doc/library/codecs.rst python/branches/py3k/Lib/ctypes/__init__.py python/branches/py3k/Lib/test/test_codecs.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Doc/library/codecs.rst ============================================================================== --- python/branches/py3k/Doc/library/codecs.rst (original) +++ python/branches/py3k/Doc/library/codecs.rst Thu Jun 17 01:33:54 2010 @@ -1223,6 +1223,23 @@ Convert a label to Unicode, as specified in :rfc:`3490`. +:mod:`encodings.mbcs` --- Windows ANSI codepage +----------------------------------------------- + +.. module:: encodings.mbcs + :synopsis: Windows ANSI codepage + +Encode operand according to the ANSI codepage (CP_ACP). This codec only +supports ``'strict'`` and ``'replace'`` error handlers to encode, and +``'strict'`` and ``'ignore'`` error handlers to decode. + +Availability: Windows only. + +.. versionchanged:: 3.2 + Before 3.2, the *errors* argument was ignored; ``'replace'`` was always used + to encode, and ``'ignore'`` to decode. + + :mod:`encodings.utf_8_sig` --- UTF-8 codec with BOM signature ------------------------------------------------------------- Modified: python/branches/py3k/Lib/ctypes/__init__.py ============================================================================== --- python/branches/py3k/Lib/ctypes/__init__.py (original) +++ python/branches/py3k/Lib/ctypes/__init__.py Thu Jun 17 01:33:54 2010 @@ -265,7 +265,7 @@ pass else: if _os.name in ("nt", "ce"): - set_conversion_mode("mbcs", "ignore") + set_conversion_mode("mbcs", "strict") else: set_conversion_mode("ascii", "strict") Modified: python/branches/py3k/Lib/test/test_codecs.py ============================================================================== --- python/branches/py3k/Lib/test/test_codecs.py (original) +++ python/branches/py3k/Lib/test/test_codecs.py Thu Jun 17 01:33:54 2010 @@ -1358,11 +1358,6 @@ "idna", ] -# The following encodings only support "strict" mode -only_strict_mode = [ - "idna", -] - class BasicUnicodeTest(unittest.TestCase, MixInCheckStateHandling): def test_basics(self): s = "abc123" # all codecs should be able to encode these @@ -1437,7 +1432,7 @@ result = "".join(codecs.iterdecode(codecs.iterencode("", encoding), encoding)) self.assertEqual(result, "") - if encoding not in only_strict_mode: + if encoding not in ("idna", "mbcs"): # check incremental decoder/encoder with errors argument try: encoder = codecs.getincrementalencoder(encoding)("ignore") Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 17 01:33:54 2010 @@ -12,6 +12,11 @@ Core and Builtins ----------------- +- Issue #850997: mbcs encoding (Windows only) handles errors argument: strict + mode raises unicode errors. The encoder only supports "strict" and "replace" + error handlers, the decoder only supports "strict" and "ignore" error + handlers. + - Issue #8592: PyArg_Parse*() functions raise a TypeError for "y", "u" and "Z" formats if the string contains a null byte/character. Write unit tests for string formats. Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Thu Jun 17 01:33:54 2010 @@ -1767,6 +1767,33 @@ return 0; } +/* create or adjust a UnicodeDecodeError */ +static void +make_decode_exception(PyObject **exceptionObject, + const char *encoding, + const char *input, Py_ssize_t length, + Py_ssize_t startpos, Py_ssize_t endpos, + const char *reason) +{ + if (*exceptionObject == NULL) { + *exceptionObject = PyUnicodeDecodeError_Create( + encoding, input, length, startpos, endpos, reason); + } + else { + if (PyUnicodeDecodeError_SetStart(*exceptionObject, startpos)) + goto onError; + if (PyUnicodeDecodeError_SetEnd(*exceptionObject, endpos)) + goto onError; + if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason)) + goto onError; + } + return; + +onError: + Py_DECREF(*exceptionObject); + *exceptionObject = NULL; +} + /* error handling callback helper: build arguments, call the callback and check the arguments, if no exception occurred, copy the replacement to the output @@ -1800,20 +1827,13 @@ goto onError; } - if (*exceptionObject == NULL) { - *exceptionObject = PyUnicodeDecodeError_Create( - encoding, *input, *inend-*input, *startinpos, *endinpos, reason); - if (*exceptionObject == NULL) - goto onError; - } - else { - if (PyUnicodeDecodeError_SetStart(*exceptionObject, *startinpos)) - goto onError; - if (PyUnicodeDecodeError_SetEnd(*exceptionObject, *endinpos)) - goto onError; - if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason)) - goto onError; - } + make_decode_exception(exceptionObject, + encoding, + *input, *inend - *input, + *startinpos, *endinpos, + reason); + if (*exceptionObject == NULL) + goto onError; restuple = PyObject_CallFunctionObjArgs(*errorHandler, *exceptionObject, NULL); if (restuple == NULL) @@ -4552,32 +4572,46 @@ static int decode_mbcs(PyUnicodeObject **v, const char *s, /* MBCS string */ int size, /* sizeof MBCS string */ - int final) + int final, + const char *errors) { Py_UNICODE *p; - Py_ssize_t n = 0; - int usize = 0; + Py_ssize_t n; + DWORD usize; + DWORD flags; assert(size >= 0); + /* check and handle 'errors' arg */ + if (errors==NULL || strcmp(errors, "strict")==0) + flags = MB_ERR_INVALID_CHARS; + else if (strcmp(errors, "ignore")==0) + flags = 0; + else { + PyErr_Format(PyExc_ValueError, + "mbcs encoding does not support errors='%s'", + errors); + return -1; + } + /* Skip trailing lead-byte unless 'final' is set */ if (!final && size >= 1 && is_dbcs_lead_byte(s, size - 1)) --size; /* First get the size of the result */ if (size > 0) { - usize = MultiByteToWideChar(CP_ACP, 0, s, size, NULL, 0); - if (usize == 0) { - PyErr_SetFromWindowsErrWithFilename(0, NULL); - return -1; - } - } + usize = MultiByteToWideChar(CP_ACP, flags, s, size, NULL, 0); + if (usize==0) + goto mbcs_decode_error; + } else + usize = 0; if (*v == NULL) { /* Create unicode object */ *v = _PyUnicode_New(usize); if (*v == NULL) return -1; + n = 0; } else { /* Extend unicode object */ @@ -4587,15 +4621,35 @@ } /* Do the conversion */ - if (size > 0) { + if (usize > 0) { p = PyUnicode_AS_UNICODE(*v) + n; - if (0 == MultiByteToWideChar(CP_ACP, 0, s, size, p, usize)) { - PyErr_SetFromWindowsErrWithFilename(0, NULL); - return -1; + if (0 == MultiByteToWideChar(CP_ACP, flags, s, size, p, usize)) { + goto mbcs_decode_error; } } - return size; + +mbcs_decode_error: + /* If the last error was ERROR_NO_UNICODE_TRANSLATION, then + we raise a UnicodeDecodeError - else it is a 'generic' + windows error + */ + if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION) { + /* Ideally, we should get reason from FormatMessage - this + is the Windows 2000 English version of the message + */ + PyObject *exc = NULL; + const char *reason = "No mapping for the Unicode character exists " + "in the target multi-byte code page."; + make_decode_exception(&exc, "mbcs", s, size, 0, 0, reason); + if (exc != NULL) { + PyCodec_StrictErrors(exc); + Py_DECREF(exc); + } + } else { + PyErr_SetFromWindowsErrWithFilename(0, NULL); + } + return -1; } PyObject *PyUnicode_DecodeMBCSStateful(const char *s, @@ -4612,10 +4666,10 @@ #ifdef NEED_RETRY retry: if (size > INT_MAX) - done = decode_mbcs(&v, s, INT_MAX, 0); + done = decode_mbcs(&v, s, INT_MAX, 0, errors); else #endif - done = decode_mbcs(&v, s, (int)size, !consumed); + done = decode_mbcs(&v, s, (int)size, !consumed, errors); if (done < 0) { Py_XDECREF(v); @@ -4649,20 +4703,45 @@ */ static int encode_mbcs(PyObject **repr, const Py_UNICODE *p, /* unicode */ - int size) /* size of unicode */ + int size, /* size of unicode */ + const char* errors) { - int mbcssize = 0; - Py_ssize_t n = 0; + BOOL usedDefaultChar = FALSE; + BOOL *pusedDefaultChar; + int mbcssize; + Py_ssize_t n; + PyObject *exc = NULL; + DWORD flags; assert(size >= 0); + /* check and handle 'errors' arg */ + if (errors==NULL || strcmp(errors, "strict")==0) { + flags = WC_NO_BEST_FIT_CHARS; + pusedDefaultChar = &usedDefaultChar; + } else if (strcmp(errors, "replace")==0) { + flags = 0; + pusedDefaultChar = NULL; + } else { + PyErr_Format(PyExc_ValueError, + "mbcs encoding does not support errors='%s'", + errors); + return -1; + } + /* First get the size of the result */ if (size > 0) { - mbcssize = WideCharToMultiByte(CP_ACP, 0, p, size, NULL, 0, NULL, NULL); + mbcssize = WideCharToMultiByte(CP_ACP, flags, p, size, NULL, 0, + NULL, pusedDefaultChar); if (mbcssize == 0) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } + /* If we used a default char, then we failed! */ + if (pusedDefaultChar && *pusedDefaultChar) + goto mbcs_encode_error; + } else { + mbcssize = 0; } if (*repr == NULL) { @@ -4670,6 +4749,7 @@ *repr = PyBytes_FromStringAndSize(NULL, mbcssize); if (*repr == NULL) return -1; + n = 0; } else { /* Extend string object */ @@ -4681,13 +4761,20 @@ /* Do the conversion */ if (size > 0) { char *s = PyBytes_AS_STRING(*repr) + n; - if (0 == WideCharToMultiByte(CP_ACP, 0, p, size, s, mbcssize, NULL, NULL)) { + if (0 == WideCharToMultiByte(CP_ACP, flags, p, size, s, mbcssize, + NULL, pusedDefaultChar)) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } + if (pusedDefaultChar && *pusedDefaultChar) + goto mbcs_encode_error; } - return 0; + +mbcs_encode_error: + raise_encode_exception(&exc, "mbcs", p, size, 0, 0, "invalid character"); + Py_XDECREF(exc); + return -1; } PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p, @@ -4700,10 +4787,10 @@ #ifdef NEED_RETRY retry: if (size > INT_MAX) - ret = encode_mbcs(&repr, p, INT_MAX); + ret = encode_mbcs(&repr, p, INT_MAX, errors); else #endif - ret = encode_mbcs(&repr, p, (int)size); + ret = encode_mbcs(&repr, p, (int)size, errors); if (ret < 0) { Py_XDECREF(repr); From python-checkins at python.org Thu Jun 17 01:48:50 2010 From: python-checkins at python.org (victor.stinner) Date: Thu, 17 Jun 2010 01:48:50 +0200 (CEST) Subject: [Python-checkins] r82038 - python/branches/py3k/Misc/NEWS Message-ID: <20100616234850.00B2CEEC53@mail.python.org> Author: victor.stinner Date: Thu Jun 17 01:48:49 2010 New Revision: 82038 Log: Issue #850997: Oops, I forgot the author of the patch: Mark Hammond Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 17 01:48:49 2010 @@ -15,7 +15,7 @@ - Issue #850997: mbcs encoding (Windows only) handles errors argument: strict mode raises unicode errors. The encoder only supports "strict" and "replace" error handlers, the decoder only supports "strict" and "ignore" error - handlers. + handlers. Patch written by Mark Hammond. - Issue #8592: PyArg_Parse*() functions raise a TypeError for "y", "u" and "Z" formats if the string contains a null byte/character. Write unit tests for From python-checkins at python.org Thu Jun 17 03:36:52 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 17 Jun 2010 03:36:52 +0200 (CEST) Subject: [Python-checkins] r82039 - in python/trunk: Lib/inspect.py Lib/test/test_inspect.py Misc/NEWS Message-ID: <20100617013652.F3EDBEEC84@mail.python.org> Author: r.david.murray Date: Thu Jun 17 03:36:52 2010 New Revision: 82039 Log: #8720: fix inspect regression by teaching getsourcefile about linecache. The fix for issue 4050 caused a regression: before that fix, source lines in the linecache would eventually be found by inspect. After the fix inspect reports an error earlier, and the source isn't found. The fix for the fix is to have getsourcefile look in the linecache for the file and return the psuedo-filename if the source is there, just as it already returns it if there is a PEP 302 loader. Modified: python/trunk/Lib/inspect.py python/trunk/Lib/test/test_inspect.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/inspect.py ============================================================================== --- python/trunk/Lib/inspect.py (original) +++ python/trunk/Lib/inspect.py Thu Jun 17 03:36:52 2010 @@ -440,7 +440,9 @@ if info: return info[0] def getsourcefile(object): - """Return the Python source file an object was defined in, if it exists.""" + """Return the filename that can be used to locate an object's source. + Return None if no way can be identified to get the source. + """ filename = getfile(object) if string.lower(filename[-4:]) in ('.pyc', '.pyo'): filename = filename[:-4] + '.py' @@ -453,6 +455,9 @@ # only return a non-existent filename if the module has a PEP 302 loader if hasattr(getmodule(object, filename), '__loader__'): return filename + # or it is in the linecache + if filename in linecache.cache: + return filename def getabsfile(object, _filename=None): """Return an absolute path to the source or compiled file for an object. Modified: python/trunk/Lib/test/test_inspect.py ============================================================================== --- python/trunk/Lib/test/test_inspect.py (original) +++ python/trunk/Lib/test/test_inspect.py Thu Jun 17 03:36:52 2010 @@ -3,6 +3,7 @@ import types import unittest import inspect +import linecache import datetime from UserList import UserList from UserDict import UserDict @@ -274,6 +275,11 @@ def test_getsourcefile(self): self.assertEqual(inspect.getsourcefile(mod.spam), modfile) self.assertEqual(inspect.getsourcefile(git.abuse), modfile) + fn = "_non_existing_filename_used_for_sourcefile_test.py" + co = compile("None", fn, "exec") + self.assertEqual(inspect.getsourcefile(co), None) + linecache.cache[co.co_filename] = (1, None, "None", co.co_filename) + self.assertEqual(inspect.getsourcefile(co), fn) def test_getfile(self): self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__) @@ -372,6 +378,15 @@ self.assertRaises(IOError, inspect.getsource, unicodedata) self.assertRaises(IOError, inspect.findsource, unicodedata) + def test_findsource_code_in_linecache(self): + lines = ["x=1"] + co = compile(lines[0], "_dynamically_created_file", "exec") + self.assertRaises(IOError, inspect.findsource, co) + self.assertRaises(IOError, inspect.getsource, co) + linecache.cache[co.co_filename] = (1, None, lines, co.co_filename) + self.assertEquals(inspect.findsource(co), (lines,0)) + self.assertEquals(inspect.getsource(co), lines[0]) + # Helper for testing classify_class_attrs. def attrs_wo_objs(cls): return [t[:3] for t in inspect.classify_class_attrs(cls)] Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Jun 17 03:36:52 2010 @@ -26,6 +26,9 @@ Library ------- +- Issue #8720: fix regression caused by fix for #4050 by making getsourcefile + smart enough to find source files in the linecache. + - Issue #8986: math.erfc was incorrectly raising OverflowError for values between -27.3 and -30.0 on some platforms. From python-checkins at python.org Thu Jun 17 03:45:28 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 17 Jun 2010 03:45:28 +0200 (CEST) Subject: [Python-checkins] r82040 - python/branches/release26-maint Message-ID: <20100617014528.0E3D8EE9FD@mail.python.org> Author: r.david.murray Date: Thu Jun 17 03:45:27 2010 New Revision: 82040 Log: Blocked revisions 82039 via svnmerge ........ r82039 | r.david.murray | 2010-06-16 21:36:52 -0400 (Wed, 16 Jun 2010) | 10 lines #8720: fix inspect regression by teaching getsourcefile about linecache. The fix for issue 4050 caused a regression: before that fix, source lines in the linecache would eventually be found by inspect. After the fix inspect reports an error earlier, and the source isn't found. The fix for the fix is to have getsourcefile look in the linecache for the file and return the psuedo-filename if the source is there, just as it already returns it if there is a PEP 302 loader. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Jun 17 04:04:30 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 17 Jun 2010 04:04:30 +0200 (CEST) Subject: [Python-checkins] r82041 - in python/branches/py3k: Lib/inspect.py Lib/test/test_inspect.py Misc/NEWS Message-ID: <20100617020430.02D7BEEACB@mail.python.org> Author: r.david.murray Date: Thu Jun 17 04:04:29 2010 New Revision: 82041 Log: Merged revisions 82039 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82039 | r.david.murray | 2010-06-16 21:36:52 -0400 (Wed, 16 Jun 2010) | 10 lines #8720: fix inspect regression by teaching getsourcefile about linecache. The fix for issue 4050 caused a regression: before that fix, source lines in the linecache would eventually be found by inspect. After the fix inspect reports an error earlier, and the source isn't found. The fix for the fix is to have getsourcefile look in the linecache for the file and return the psuedo-filename if the source is there, just as it already returns it if there is a PEP 302 loader. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/inspect.py python/branches/py3k/Lib/test/test_inspect.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/inspect.py ============================================================================== --- python/branches/py3k/Lib/inspect.py (original) +++ python/branches/py3k/Lib/inspect.py Thu Jun 17 04:04:29 2010 @@ -437,7 +437,9 @@ if info: return info[0] def getsourcefile(object): - """Return the Python source file an object was defined in, if it exists.""" + """Return the filename that can be used to locate an object's source. + Return None if no way can be identified to get the source. + """ filename = getfile(object) if filename[-4:].lower() in ('.pyc', '.pyo'): filename = filename[:-4] + '.py' @@ -450,6 +452,9 @@ # only return a non-existent filename if the module has a PEP 302 loader if hasattr(getmodule(object, filename), '__loader__'): return filename + # or it is in the linecache + if filename in linecache.cache: + return filename def getabsfile(object, _filename=None): """Return an absolute path to the source or compiled file for an object. Modified: python/branches/py3k/Lib/test/test_inspect.py ============================================================================== --- python/branches/py3k/Lib/test/test_inspect.py (original) +++ python/branches/py3k/Lib/test/test_inspect.py Thu Jun 17 04:04:29 2010 @@ -3,6 +3,7 @@ import types import unittest import inspect +import linecache import datetime import collections from os.path import normcase @@ -275,6 +276,11 @@ def test_getsourcefile(self): self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile) self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile) + fn = "_non_existing_filename_used_for_sourcefile_test.py" + co = compile("None", fn, "exec") + self.assertEqual(normcase(inspect.getsourcefile(co)), None) + linecache.cache[co.co_filename] = (1, None, "None", co.co_filename) + self.assertEqual(normcase(inspect.getsourcefile(co)), fn) def test_getfile(self): self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__) @@ -373,6 +379,15 @@ self.assertRaises(IOError, inspect.getsource, unicodedata) self.assertRaises(IOError, inspect.findsource, unicodedata) + def test_findsource_code_in_linecache(self): + lines = ["x=1"] + co = compile(lines[0], "_dynamically_created_file", "exec") + self.assertRaises(IOError, inspect.findsource, co) + self.assertRaises(IOError, inspect.getsource, co) + linecache.cache[co.co_filename] = (1, None, lines, co.co_filename) + self.assertEquals(inspect.findsource(co), (lines,0)) + self.assertEquals(inspect.getsource(co), lines[0]) + # Helper for testing classify_class_attrs. def attrs_wo_objs(cls): return [t[:3] for t in inspect.classify_class_attrs(cls)] Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 17 04:04:29 2010 @@ -437,6 +437,9 @@ Library ------- +- Issue #8720: fix regression caused by fix for #4050 by making getsourcefile + smart enough to find source files in the linecache. + - Issue #5610: feedparser no longer eats extra characters at the end of a body part if the body part ends with a \r\n. From python-checkins at python.org Thu Jun 17 04:06:12 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 17 Jun 2010 04:06:12 +0200 (CEST) Subject: [Python-checkins] r82042 - in python/branches/release31-maint: Lib/inspect.py Lib/test/test_inspect.py Misc/NEWS Message-ID: <20100617020612.4B951EEC4B@mail.python.org> Author: r.david.murray Date: Thu Jun 17 04:06:12 2010 New Revision: 82042 Log: Merged revisions 82041 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r82041 | r.david.murray | 2010-06-16 22:04:29 -0400 (Wed, 16 Jun 2010) | 16 lines Merged revisions 82039 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82039 | r.david.murray | 2010-06-16 21:36:52 -0400 (Wed, 16 Jun 2010) | 10 lines #8720: fix inspect regression by teaching getsourcefile about linecache. The fix for issue 4050 caused a regression: before that fix, source lines in the linecache would eventually be found by inspect. After the fix inspect reports an error earlier, and the source isn't found. The fix for the fix is to have getsourcefile look in the linecache for the file and return the psuedo-filename if the source is there, just as it already returns it if there is a PEP 302 loader. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/inspect.py python/branches/release31-maint/Lib/test/test_inspect.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/inspect.py ============================================================================== --- python/branches/release31-maint/Lib/inspect.py (original) +++ python/branches/release31-maint/Lib/inspect.py Thu Jun 17 04:06:12 2010 @@ -435,7 +435,9 @@ if info: return info[0] def getsourcefile(object): - """Return the Python source file an object was defined in, if it exists.""" + """Return the filename that can be used to locate an object's source. + Return None if no way can be identified to get the source. + """ filename = getfile(object) if filename[-4:].lower() in ('.pyc', '.pyo'): filename = filename[:-4] + '.py' @@ -448,6 +450,9 @@ # only return a non-existent filename if the module has a PEP 302 loader if hasattr(getmodule(object, filename), '__loader__'): return filename + # or it is in the linecache + if filename in linecache.cache: + return filename def getabsfile(object, _filename=None): """Return an absolute path to the source or compiled file for an object. Modified: python/branches/release31-maint/Lib/test/test_inspect.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_inspect.py (original) +++ python/branches/release31-maint/Lib/test/test_inspect.py Thu Jun 17 04:06:12 2010 @@ -2,6 +2,7 @@ import types import unittest import inspect +import linecache import datetime import collections from os.path import normcase @@ -272,6 +273,11 @@ def test_getsourcefile(self): self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile) self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile) + fn = "_non_existing_filename_used_for_sourcefile_test.py" + co = compile("None", fn, "exec") + self.assertEqual(normcase(inspect.getsourcefile(co)), None) + linecache.cache[co.co_filename] = (1, None, "None", co.co_filename) + self.assertEqual(normcase(inspect.getsourcefile(co)), fn) def test_getfile(self): self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__) @@ -370,6 +376,15 @@ self.assertRaises(IOError, inspect.getsource, unicodedata) self.assertRaises(IOError, inspect.findsource, unicodedata) + def test_findsource_code_in_linecache(self): + lines = ["x=1"] + co = compile(lines[0], "_dynamically_created_file", "exec") + self.assertRaises(IOError, inspect.findsource, co) + self.assertRaises(IOError, inspect.getsource, co) + linecache.cache[co.co_filename] = (1, None, lines, co.co_filename) + self.assertEquals(inspect.findsource(co), (lines,0)) + self.assertEquals(inspect.getsource(co), lines[0]) + # Helper for testing classify_class_attrs. def attrs_wo_objs(cls): return [t[:3] for t in inspect.classify_class_attrs(cls)] Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Jun 17 04:06:12 2010 @@ -61,6 +61,9 @@ Library ------- +- Issue #8720: fix regression caused by fix for #4050 by making getsourcefile + smart enough to find source files in the linecache. + - Issue #5610: feedparser no longer eats extra characters at the end of a body part if the body part ends with a \r\n. From python-checkins at python.org Thu Jun 17 14:33:22 2010 From: python-checkins at python.org (mark.dickinson) Date: Thu, 17 Jun 2010 14:33:22 +0200 (CEST) Subject: [Python-checkins] r82043 - in python/branches/py3k: Lib/test/test_parser.py Misc/NEWS Python/ast.c Message-ID: <20100617123322.A9EF6EE9A5@mail.python.org> Author: mark.dickinson Date: Thu Jun 17 14:33:22 2010 New Revision: 82043 Log: Issue #9011: Remove buggy and unnecessary ST->AST compilation code dealing with unary minus applied to a constant. The removed code was mutating the ST, causing a second compilation to fail. (The peephole optimizer already takes care of optimizing this case, so there's no lost optimization opportunity here.) Modified: python/branches/py3k/Lib/test/test_parser.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/ast.c 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 Thu Jun 17 14:33:22 2010 @@ -484,8 +484,18 @@ st = parser.suite('a = "\\u1"') self.assertRaises(SyntaxError, parser.compilest, st) + def test_issue_9011(self): + # Issue 9011: compilation of an unary minus expression changed + # the meaning of the ST, so that a second compilation produced + # incorrect results. + st = parser.expr('-3') + code1 = parser.compilest(st) + self.assertEqual(eval(code1), -3) + code2 = parser.compilest(st) + self.assertEqual(eval(code2), -3) + class ParserStackLimitTestCase(unittest.TestCase): - """try to push the parser to/over it's limits. + """try to push the parser to/over its limits. see http://bugs.python.org/issue1881 for a discussion """ def _nested_expression(self, level): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 17 14:33:22 2010 @@ -12,6 +12,11 @@ Core and Builtins ----------------- +- Issue #9011: Remove buggy and unnecessary (in 3.x) ST->AST + compilation code dealing with unary minus applied to a constant. + The removed code was mutating the ST, causing a second compilation + to fail. + - Issue #850997: mbcs encoding (Windows only) handles errors argument: strict mode raises unicode errors. The encoder only supports "strict" and "replace" error handlers, the decoder only supports "strict" and "ignore" error Modified: python/branches/py3k/Python/ast.c ============================================================================== --- python/branches/py3k/Python/ast.c (original) +++ python/branches/py3k/Python/ast.c Thu Jun 17 14:33:22 2010 @@ -1678,34 +1678,8 @@ static expr_ty ast_for_factor(struct compiling *c, const node *n) { - node *pfactor, *ppower, *patom, *pnum; expr_ty expression; - /* If the unary - operator is applied to a constant, don't generate - a UNARY_NEGATIVE opcode. Just store the approriate value as a - constant. The peephole optimizer already does something like - this but it doesn't handle the case where the constant is - (sys.maxint - 1). In that case, we want a PyIntObject, not a - PyLongObject. - */ - if (TYPE(CHILD(n, 0)) == MINUS - && NCH(n) == 2 - && TYPE((pfactor = CHILD(n, 1))) == factor - && NCH(pfactor) == 1 - && TYPE((ppower = CHILD(pfactor, 0))) == power - && NCH(ppower) == 1 - && TYPE((patom = CHILD(ppower, 0))) == atom - && TYPE((pnum = CHILD(patom, 0))) == NUMBER) { - char *s = PyObject_MALLOC(strlen(STR(pnum)) + 2); - if (s == NULL) - return NULL; - s[0] = '-'; - strcpy(s + 1, STR(pnum)); - PyObject_FREE(STR(pnum)); - STR(pnum) = s; - return ast_for_atom(c, patom); - } - expression = ast_for_expr(c, CHILD(n, 1)); if (!expression) return NULL; From python-checkins at python.org Thu Jun 17 14:37:17 2010 From: python-checkins at python.org (mark.dickinson) Date: Thu, 17 Jun 2010 14:37:17 +0200 (CEST) Subject: [Python-checkins] r82044 - in python/branches/release31-maint: Lib/test/test_parser.py Misc/NEWS Python/ast.c Message-ID: <20100617123717.4C2C2EE9C1@mail.python.org> Author: mark.dickinson Date: Thu Jun 17 14:37:17 2010 New Revision: 82044 Log: Merged revisions 82043 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r82043 | mark.dickinson | 2010-06-17 13:33:22 +0100 (Thu, 17 Jun 2010) | 6 lines Issue #9011: Remove buggy and unnecessary ST->AST compilation code dealing with unary minus applied to a constant. The removed code was mutating the ST, causing a second compilation to fail. (The peephole optimizer already takes care of optimizing this case, so there's no lost optimization opportunity here.) ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_parser.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Python/ast.c Modified: python/branches/release31-maint/Lib/test/test_parser.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_parser.py (original) +++ python/branches/release31-maint/Lib/test/test_parser.py Thu Jun 17 14:37:17 2010 @@ -479,8 +479,18 @@ st = parser.suite('a = "\\u1"') self.assertRaises(SyntaxError, parser.compilest, st) + def test_issue_9011(self): + # Issue 9011: compilation of an unary minus expression changed + # the meaning of the ST, so that a second compilation produced + # incorrect results. + st = parser.expr('-3') + code1 = parser.compilest(st) + self.assertEqual(eval(code1), -3) + code2 = parser.compilest(st) + self.assertEqual(eval(code2), -3) + class ParserStackLimitTestCase(unittest.TestCase): - """try to push the parser to/over it's limits. + """try to push the parser to/over its limits. see http://bugs.python.org/issue1881 for a discussion """ def _nested_expression(self, level): Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Jun 17 14:37:17 2010 @@ -12,6 +12,11 @@ Core and Builtins ----------------- +- Issue #9011: Remove buggy and unnecessary (in 3.x) ST->AST + compilation code dealing with unary minus applied to a constant. + The removed code was mutating the ST, causing a second compilation + to fail. + - Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). Modified: python/branches/release31-maint/Python/ast.c ============================================================================== --- python/branches/release31-maint/Python/ast.c (original) +++ python/branches/release31-maint/Python/ast.c Thu Jun 17 14:37:17 2010 @@ -1664,34 +1664,8 @@ static expr_ty ast_for_factor(struct compiling *c, const node *n) { - node *pfactor, *ppower, *patom, *pnum; expr_ty expression; - /* If the unary - operator is applied to a constant, don't generate - a UNARY_NEGATIVE opcode. Just store the approriate value as a - constant. The peephole optimizer already does something like - this but it doesn't handle the case where the constant is - (sys.maxint - 1). In that case, we want a PyIntObject, not a - PyLongObject. - */ - if (TYPE(CHILD(n, 0)) == MINUS - && NCH(n) == 2 - && TYPE((pfactor = CHILD(n, 1))) == factor - && NCH(pfactor) == 1 - && TYPE((ppower = CHILD(pfactor, 0))) == power - && NCH(ppower) == 1 - && TYPE((patom = CHILD(ppower, 0))) == atom - && TYPE((pnum = CHILD(patom, 0))) == NUMBER) { - char *s = PyObject_MALLOC(strlen(STR(pnum)) + 2); - if (s == NULL) - return NULL; - s[0] = '-'; - strcpy(s + 1, STR(pnum)); - PyObject_FREE(STR(pnum)); - STR(pnum) = s; - return ast_for_atom(c, patom); - } - expression = ast_for_expr(c, CHILD(n, 1)); if (!expression) return NULL; From python-checkins at python.org Thu Jun 17 15:23:18 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 17 Jun 2010 15:23:18 +0200 (CEST) Subject: [Python-checkins] r82045 - python/branches/py3k/Lib/test/test_inspect.py Message-ID: <20100617132318.E8936EE9EA@mail.python.org> Author: r.david.murray Date: Thu Jun 17 15:23:18 2010 New Revision: 82045 Log: Don't use os.normcase when the result we are expecting is None. This worked fine on linux but fails on Windows. That may or may not be a but in normcase. Modified: python/branches/py3k/Lib/test/test_inspect.py Modified: python/branches/py3k/Lib/test/test_inspect.py ============================================================================== --- python/branches/py3k/Lib/test/test_inspect.py (original) +++ python/branches/py3k/Lib/test/test_inspect.py Thu Jun 17 15:23:18 2010 @@ -278,7 +278,7 @@ self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile) fn = "_non_existing_filename_used_for_sourcefile_test.py" co = compile("None", fn, "exec") - self.assertEqual(normcase(inspect.getsourcefile(co)), None) + self.assertEqual(inspect.getsourcefile(co), None) linecache.cache[co.co_filename] = (1, None, "None", co.co_filename) self.assertEqual(normcase(inspect.getsourcefile(co)), fn) From python-checkins at python.org Thu Jun 17 15:27:41 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 17 Jun 2010 15:27:41 +0200 (CEST) Subject: [Python-checkins] r82046 - in python/branches/release31-maint: Lib/test/test_inspect.py Message-ID: <20100617132741.1F89DEE9EA@mail.python.org> Author: r.david.murray Date: Thu Jun 17 15:27:40 2010 New Revision: 82046 Log: Merged revisions 82045 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r82045 | r.david.murray | 2010-06-17 09:23:18 -0400 (Thu, 17 Jun 2010) | 5 lines Don't use os.normcase when the result we are expecting is None. This worked fine on linux but fails on Windows. That may or may not be a but in normcase. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_inspect.py Modified: python/branches/release31-maint/Lib/test/test_inspect.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_inspect.py (original) +++ python/branches/release31-maint/Lib/test/test_inspect.py Thu Jun 17 15:27:40 2010 @@ -275,7 +275,7 @@ self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile) fn = "_non_existing_filename_used_for_sourcefile_test.py" co = compile("None", fn, "exec") - self.assertEqual(normcase(inspect.getsourcefile(co)), None) + self.assertEqual(inspect.getsourcefile(co), None) linecache.cache[co.co_filename] = (1, None, "None", co.co_filename) self.assertEqual(normcase(inspect.getsourcefile(co)), fn) From jimjjewett at gmail.com Thu Jun 17 15:59:33 2010 From: jimjjewett at gmail.com (Jim Jewett) Date: Thu, 17 Jun 2010 09:59:33 -0400 Subject: [Python-checkins] r82045 - python/branches/py3k/Lib/test/test_inspect.py In-Reply-To: <20100617132318.E8936EE9EA@mail.python.org> References: <20100617132318.E8936EE9EA@mail.python.org> Message-ID: (1) Do you mean a "bug" (as opposed to "but") in normcase? (2) It is probably worth clearing up what normcase should do if the path isn't a string-like object. Windows fails because None doesn't support s.replace, but linux only works because the method is a no-op. And it is commented as a buggy no-op that *ought* to do something on Mac OS X. -jJ On Thu, Jun 17, 2010 at 9:23 AM, r.david.murray wrote: > Author: r.david.murray > Date: Thu Jun 17 15:23:18 2010 > New Revision: 82045 > > Log: > Don't use os.normcase when the result we are expecting is None. > > This worked fine on linux but fails on Windows. ?That may or may > not be a but in normcase. > > > Modified: > ? python/branches/py3k/Lib/test/test_inspect.py > > Modified: python/branches/py3k/Lib/test/test_inspect.py > ============================================================================== > --- python/branches/py3k/Lib/test/test_inspect.py ? ? ? (original) > +++ python/branches/py3k/Lib/test/test_inspect.py ? ? ? Thu Jun 17 15:23:18 2010 > @@ -278,7 +278,7 @@ > ? ? ? ? self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile) > ? ? ? ? fn = "_non_existing_filename_used_for_sourcefile_test.py" > ? ? ? ? co = compile("None", fn, "exec") > - ? ? ? ?self.assertEqual(normcase(inspect.getsourcefile(co)), None) > + ? ? ? ?self.assertEqual(inspect.getsourcefile(co), None) > ? ? ? ? linecache.cache[co.co_filename] = (1, None, "None", co.co_filename) > ? ? ? ? self.assertEqual(normcase(inspect.getsourcefile(co)), fn) > > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > From python-checkins at python.org Thu Jun 17 17:26:54 2010 From: python-checkins at python.org (r.david.murray) Date: Thu, 17 Jun 2010 17:26:54 +0200 (CEST) Subject: [Python-checkins] r82046 - svn:log Message-ID: <20100617152654.E4FE2EEA4D@mail.python.org> Author: r.david.murray Revision: 82046 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -7,5 +7,5 @@ Don't use os.normcase when the result we are expecting is None. This worked fine on linux but fails on Windows. That may or may - not be a but in normcase. + not be a bug in normcase. ........ From rdmurray at bitdance.com Thu Jun 17 17:30:48 2010 From: rdmurray at bitdance.com (R. David Murray) Date: Thu, 17 Jun 2010 11:30:48 -0400 Subject: [Python-checkins] r82045 - python/branches/py3k/Lib/test/test_inspect.py In-Reply-To: References: <20100617132318.E8936EE9EA@mail.python.org> Message-ID: <20100617153048.D5A831FD38B@kimball.webabinitio.net> On Thu, 17 Jun 2010 09:59:33 -0400, Jim Jewett wrote: > (1) Do you mean a "bug" (as opposed to "but") in normcase? Oops, yes. > (2) It is probably worth clearing up what normcase should do if the > path isn't a string-like object. Windows fails because None doesn't > support s.replace, but linux only works because the method is a no-op. > And it is commented as a buggy no-op that *ought* to do something on > Mac OS X. I've opened issue #9018 to address the linux None problem. --David From python-checkins at python.org Thu Jun 17 18:38:34 2010 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 17 Jun 2010 18:38:34 +0200 (CEST) Subject: [Python-checkins] r82047 - python/trunk/Modules/posixmodule.c Message-ID: <20100617163834.68645EEC77@mail.python.org> Author: senthil.kumaran Date: Thu Jun 17 18:38:34 2010 New Revision: 82047 Log: Fix Issue4452 - Incorrect docstring of os.setpgrp Modified: python/trunk/Modules/posixmodule.c Modified: python/trunk/Modules/posixmodule.c ============================================================================== --- python/trunk/Modules/posixmodule.c (original) +++ python/trunk/Modules/posixmodule.c Thu Jun 17 18:38:34 2010 @@ -3946,7 +3946,7 @@ #ifdef HAVE_SETPGRP PyDoc_STRVAR(posix_setpgrp__doc__, "setpgrp()\n\n\ -Make this process a session leader."); +Make this process the process group leader."); static PyObject * posix_setpgrp(PyObject *self, PyObject *noargs) From python-checkins at python.org Thu Jun 17 18:41:48 2010 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 17 Jun 2010 18:41:48 +0200 (CEST) Subject: [Python-checkins] r82048 - in python/branches/release26-maint: Modules/posixmodule.c Message-ID: <20100617164148.2A196EEACC@mail.python.org> Author: senthil.kumaran Date: Thu Jun 17 18:41:47 2010 New Revision: 82048 Log: Merged revisions 82047 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82047 | senthil.kumaran | 2010-06-17 22:08:34 +0530 (Thu, 17 Jun 2010) | 3 lines Fix Issue4452 - Incorrect docstring of os.setpgrp ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Modules/posixmodule.c Modified: python/branches/release26-maint/Modules/posixmodule.c ============================================================================== --- python/branches/release26-maint/Modules/posixmodule.c (original) +++ python/branches/release26-maint/Modules/posixmodule.c Thu Jun 17 18:41:47 2010 @@ -3940,7 +3940,7 @@ #ifdef HAVE_SETPGRP PyDoc_STRVAR(posix_setpgrp__doc__, "setpgrp()\n\n\ -Make this process a session leader."); +Make this process the process group leader."); static PyObject * posix_setpgrp(PyObject *self, PyObject *noargs) From python-checkins at python.org Thu Jun 17 18:48:06 2010 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 17 Jun 2010 18:48:06 +0200 (CEST) Subject: [Python-checkins] r82049 - in python/branches/py3k: Modules/posixmodule.c Message-ID: <20100617164806.BE92FEEC4B@mail.python.org> Author: senthil.kumaran Date: Thu Jun 17 18:48:06 2010 New Revision: 82049 Log: Merged revisions 82047 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82047 | senthil.kumaran | 2010-06-17 22:08:34 +0530 (Thu, 17 Jun 2010) | 3 lines Fix Issue4452 - Incorrect docstring of os.setpgrp ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/posixmodule.c Modified: python/branches/py3k/Modules/posixmodule.c ============================================================================== --- python/branches/py3k/Modules/posixmodule.c (original) +++ python/branches/py3k/Modules/posixmodule.c Thu Jun 17 18:48:06 2010 @@ -3925,7 +3925,7 @@ #ifdef HAVE_SETPGRP PyDoc_STRVAR(posix_setpgrp__doc__, "setpgrp()\n\n\ -Make this process a session leader."); +Make this process the process group leader."); static PyObject * posix_setpgrp(PyObject *self, PyObject *noargs) From python-checkins at python.org Thu Jun 17 18:51:08 2010 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 17 Jun 2010 18:51:08 +0200 (CEST) Subject: [Python-checkins] r82050 - in python/branches/release31-maint: Modules/posixmodule.c Message-ID: <20100617165108.9B978EEBB3@mail.python.org> Author: senthil.kumaran Date: Thu Jun 17 18:51:08 2010 New Revision: 82050 Log: Merged revisions 82049 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r82049 | senthil.kumaran | 2010-06-17 22:18:06 +0530 (Thu, 17 Jun 2010) | 9 lines Merged revisions 82047 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82047 | senthil.kumaran | 2010-06-17 22:08:34 +0530 (Thu, 17 Jun 2010) | 3 lines Fix Issue4452 - Incorrect docstring of os.setpgrp ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Modules/posixmodule.c Modified: python/branches/release31-maint/Modules/posixmodule.c ============================================================================== --- python/branches/release31-maint/Modules/posixmodule.c (original) +++ python/branches/release31-maint/Modules/posixmodule.c Thu Jun 17 18:51:08 2010 @@ -4059,7 +4059,7 @@ #ifdef HAVE_SETPGRP PyDoc_STRVAR(posix_setpgrp__doc__, "setpgrp()\n\n\ -Make this process a session leader."); +Make this process the process group leader."); static PyObject * posix_setpgrp(PyObject *self, PyObject *noargs) From python-checkins at python.org Thu Jun 17 20:24:52 2010 From: python-checkins at python.org (mark.dickinson) Date: Thu, 17 Jun 2010 20:24:52 +0200 (CEST) Subject: [Python-checkins] r82051 - python/branches/py3k/Doc/whatsnew/3.0.rst Message-ID: <20100617182452.7E29FEED17@mail.python.org> Author: mark.dickinson Date: Thu Jun 17 20:24:52 2010 New Revision: 82051 Log: Add note about changes to the `round` function between 2.x and 3.x. Modified: python/branches/py3k/Doc/whatsnew/3.0.rst Modified: python/branches/py3k/Doc/whatsnew/3.0.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.0.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.0.rst Thu Jun 17 20:24:52 2010 @@ -798,6 +798,15 @@ * A new built-in function :func:`next` was added to call the :meth:`__next__` method on an object. +* The :func:`round` function rounding strategy and return type have + changed. Exact halfway cases are now rounded to the nearest even + result instead of away from zero. (For example, ``round(2.5)`` now + returns ``2`` rather than ``3``.) :func:`round(x[, n])` now + delegates to ``x.__round__([n])`` instead of always returning a + float. It generally returns an integer when called with a single + argument and a value of the same type as ``x`` when called with two + arguments. + * Moved :func:`intern` to :func:`sys.intern`. * Removed: :func:`apply`. Instead of ``apply(f, args)`` use From python-checkins at python.org Thu Jun 17 20:25:38 2010 From: python-checkins at python.org (mark.dickinson) Date: Thu, 17 Jun 2010 20:25:38 +0200 (CEST) Subject: [Python-checkins] r82052 - in python/branches/release31-maint: Doc/whatsnew/3.0.rst Message-ID: <20100617182538.A0638EECF4@mail.python.org> Author: mark.dickinson Date: Thu Jun 17 20:25:38 2010 New Revision: 82052 Log: Merged revisions 82051 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r82051 | mark.dickinson | 2010-06-17 19:24:52 +0100 (Thu, 17 Jun 2010) | 2 lines Add note about changes to the `round` function between 2.x and 3.x. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/whatsnew/3.0.rst Modified: python/branches/release31-maint/Doc/whatsnew/3.0.rst ============================================================================== --- python/branches/release31-maint/Doc/whatsnew/3.0.rst (original) +++ python/branches/release31-maint/Doc/whatsnew/3.0.rst Thu Jun 17 20:25:38 2010 @@ -798,6 +798,15 @@ * A new builtin :func:`next` was added to call the :meth:`__next__` method on an object. +* The :func:`round` function rounding strategy and return type have + changed. Exact halfway cases are now rounded to the nearest even + result instead of away from zero. (For example, ``round(2.5)`` now + returns ``2`` rather than ``3``.) :func:`round(x[, n])` now + delegates to ``x.__round__([n])`` instead of always returning a + float. It generally returns an integer when called with a single + argument and a value of the same type as ``x`` when called with two + arguments. + * Moved :func:`intern` to :func:`sys.intern`. * Removed: :func:`apply`. Instead of ``apply(f, args)`` use From python-checkins at python.org Thu Jun 17 20:30:34 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Thu, 17 Jun 2010 20:30:34 +0200 (CEST) Subject: [Python-checkins] r82053 - in python/branches/py3k: Doc/library/datetime.rst Lib/_strptime.py Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c Message-ID: <20100617183034.C4540EECF8@mail.python.org> Author: alexander.belopolsky Date: Thu Jun 17 20:30:34 2010 New Revision: 82053 Log: Issue #6641: The datetime.strptime method now supports the %z directive. Modified: python/branches/py3k/Doc/library/datetime.rst python/branches/py3k/Lib/_strptime.py python/branches/py3k/Lib/test/test_datetime.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/datetimemodule.c Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Thu Jun 17 20:30:34 2010 @@ -1760,3 +1760,10 @@ (5) For example, if :meth:`utcoffset` returns ``timedelta(hours=-3, minutes=-30)``, ``%z`` is replaced with the string ``'-0330'``. + +.. versionadded:: 3.2 + + When the ``%z`` directive is provided to the :meth:`strptime` + method, an aware :class:`datetime` object will be produced. The + ``tzinfo`` of the result will be set to a :class:`timezone` + instance. \ No newline at end of file Modified: python/branches/py3k/Lib/_strptime.py ============================================================================== --- python/branches/py3k/Lib/_strptime.py (original) +++ python/branches/py3k/Lib/_strptime.py Thu Jun 17 20:30:34 2010 @@ -16,7 +16,10 @@ from re import compile as re_compile from re import IGNORECASE, ASCII from re import escape as re_escape -from datetime import date as datetime_date +from datetime import (date as datetime_date, + datetime as datetime_datetime, + timedelta as datetime_timedelta, + timezone as datetime_timezone) try: from _thread import allocate_lock as _thread_allocate_lock except: @@ -204,6 +207,7 @@ #XXX: Does 'Y' need to worry about having less or more than # 4 digits? 'Y': r"(?P\d\d\d\d)", + 'z': r"(?P[+-]\d\d[0-5]\d)", 'A': self.__seqToRE(self.locale_time.f_weekday, 'A'), 'a': self.__seqToRE(self.locale_time.a_weekday, 'a'), 'B': self.__seqToRE(self.locale_time.f_month[1:], 'B'), @@ -293,7 +297,9 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): - """Return a time struct based on the input string and the format string.""" + """Return a 2-tuple consisting of a time struct and an int containg + the number of microseconds based on the input string and the + format string.""" for index, arg in enumerate([data_string, format]): if not isinstance(arg, str): @@ -333,10 +339,12 @@ if len(data_string) != found.end(): raise ValueError("unconverted data remains: %s" % data_string[found.end():]) + year = 1900 month = day = 1 hour = minute = second = fraction = 0 tz = -1 + tzoffset = None # Default to -1 to signify that values not known; not critical to have, # though week_of_year = -1 @@ -417,6 +425,11 @@ else: # W starts week on Monday. week_of_year_start = 0 + elif group_key == 'z': + z = found_dict['z'] + tzoffset = int(z[1:3]) * 60 + int(z[3:5]) + if z.startswith("-"): + tzoffset = -tzoffset elif group_key == 'Z': # Since -1 is default value only need to worry about setting tz if # it can be something other than -1. @@ -453,9 +466,35 @@ day = datetime_result.day if weekday == -1: weekday = datetime_date(year, month, day).weekday() - return (time.struct_time((year, month, day, - hour, minute, second, - weekday, julian, tz)), fraction) + # Add timezone info + tzname = found_dict.get("Z") + if tzoffset is not None: + gmtoff = tzoffset * 60 + else: + gmtoff = None + + return (year, month, day, + hour, minute, second, + weekday, julian, tz, gmtoff, tzname), fraction def _strptime_time(data_string, format="%a %b %d %H:%M:%S %Y"): - return _strptime(data_string, format)[0] + """Return a time struct based on the input string and the + format string.""" + tt = _strptime(data_string, format)[0] + return time.struct_time(tt[:9]) + +def _strptime_datetime(data_string, format="%a %b %d %H:%M:%S %Y"): + """Return a datetime instace based on the input string and the + format string.""" + tt, fraction = _strptime(data_string, format) + gmtoff, tzname = tt[-2:] + args = tt[:6] + (fraction,) + if gmtoff is not None: + tzdelta = datetime_timedelta(seconds=gmtoff) + if tzname: + tz = datetime_timezone(tzdelta, tzname) + else: + tz = datetime_timezone(tzdelta) + args += (tz,) + + return datetime_datetime(*args) 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 Thu Jun 17 20:30:34 2010 @@ -17,6 +17,7 @@ from datetime import time from datetime import timezone from datetime import date, datetime +import time as _time pickle_choices = [(pickle, pickle, proto) for proto in range(3)] assert len(pickle_choices) == 3 @@ -1731,11 +1732,41 @@ string = '2004-12-01 13:02:47.197' format = '%Y-%m-%d %H:%M:%S.%f' - result, frac = _strptime._strptime(string, format) - expected = self.theclass(*(result[0:6]+(frac,))) + expected = _strptime._strptime_datetime(string, format) got = self.theclass.strptime(string, format) self.assertEqual(expected, got) + strptime = self.theclass.strptime + self.assertEqual(strptime("+0002", "%z").utcoffset(), 2 * MINUTE) + self.assertEqual(strptime("-0002", "%z").utcoffset(), -2 * MINUTE) + # Only local timezone and UTC are supported + for tzseconds, tzname in ((0, 'UTC'), (0, 'GMT'), + (-_time.timezone, _time.tzname[0])): + if tzseconds < 0: + sign = '-' + seconds = -tzseconds + else: + sign ='+' + seconds = tzseconds + hours, minutes = divmod(seconds//60, 60) + dtstr = "{}{:02d}{:02d} {}".format(sign, hours, minutes, tzname) + dt = strptime(dtstr, "%z %Z") + self.assertEqual(dt.utcoffset(), timedelta(seconds=tzseconds)) + self.assertEqual(dt.tzname(), tzname) + # Can produce inconsistent datetime + dtstr, fmt = "+1234 UTC", "%z %Z" + dt = strptime(dtstr, fmt) + self.assertEqual(dt.utcoffset(), 12 * HOUR + 34 * MINUTE) + self.assertEqual(dt.tzname(), 'UTC') + # yet will roundtrip + self.assertEqual(dt.strftime(fmt), dtstr) + + # Produce naive datetime if no %z is provided + self.assertEqual(strptime("UTC", "%Z").tzinfo, None) + + with self.assertRaises(ValueError): strptime("-2400", "%z") + with self.assertRaises(ValueError): strptime("-000", "%z") + def test_more_timetuple(self): # This tests fields beyond those tested by the TestDate.test_timetuple. t = self.theclass(2004, 12, 31, 6, 22, 33) @@ -3196,6 +3227,7 @@ return dt ZERO = timedelta(0) +MINUTE = timedelta(minutes=1) HOUR = timedelta(hours=1) DAY = timedelta(days=1) # In the US, DST starts at 2am (standard time) on the first Sunday in April. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 17 20:30:34 2010 @@ -1322,6 +1322,14 @@ Extension Modules ----------------- +- Issue #6641: The ``datetime.strptime`` method now supports the + ``%z`` directive. When the ``%z`` directive is present in the + format string, an aware ``datetime`` object is returned with + ``tzinfo`` bound to a ``datetime.timezone`` instance constructed + from the parsed offset. If both ``%z`` and ``%Z`` are present, the + data in ``%Z`` field is used for timezone name, but ``%Z`` data + without ``%z`` is discarded. + - Issue #5094: The ``datetime`` module now has a simple concrete class implementing ``datetime.tzinfo`` interface. Instances of the new class, ``datetime.timezone``, return fixed name and UTC offset from Modified: python/branches/py3k/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k/Modules/datetimemodule.c (original) +++ python/branches/py3k/Modules/datetimemodule.c Thu Jun 17 20:30:34 2010 @@ -4362,82 +4362,23 @@ return result; } -/* Return new datetime from time.strptime(). */ +/* Return new datetime from _strptime.strptime_datetime(). */ static PyObject * datetime_strptime(PyObject *cls, PyObject *args) { static PyObject *module = NULL; - PyObject *result = NULL, *obj, *st = NULL, *frac = NULL; const Py_UNICODE *string, *format; if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format)) return NULL; - if (module == NULL && - (module = PyImport_ImportModuleNoBlock("_strptime")) == NULL) - return NULL; - - /* _strptime._strptime returns a two-element tuple. The first - element is a time.struct_time object. The second is the - microseconds (which are not defined for time.struct_time). */ - obj = PyObject_CallMethod(module, "_strptime", "uu", string, format); - if (obj != NULL) { - int i, good_timetuple = 1; - long int ia[7]; - if (PySequence_Check(obj) && PySequence_Size(obj) == 2) { - st = PySequence_GetItem(obj, 0); - frac = PySequence_GetItem(obj, 1); - if (st == NULL || frac == NULL) - good_timetuple = 0; - /* copy y/m/d/h/m/s values out of the - time.struct_time */ - if (good_timetuple && - PySequence_Check(st) && - PySequence_Size(st) >= 6) { - for (i=0; i < 6; i++) { - PyObject *p = PySequence_GetItem(st, i); - if (p == NULL) { - good_timetuple = 0; - break; - } - if (PyLong_Check(p)) - ia[i] = PyLong_AsLong(p); - else - good_timetuple = 0; - Py_DECREF(p); - } -/* if (PyLong_CheckExact(p)) { - ia[i] = PyLong_AsLongAndOverflow(p, &overflow); - if (overflow) - good_timetuple = 0; - } - else - good_timetuple = 0; - Py_DECREF(p); -*/ } - else - good_timetuple = 0; - /* follow that up with a little dose of microseconds */ - if (PyLong_Check(frac)) - ia[6] = PyLong_AsLong(frac); - else - good_timetuple = 0; - } - else - good_timetuple = 0; - if (good_timetuple) - result = PyObject_CallFunction(cls, "iiiiiii", - ia[0], ia[1], ia[2], - ia[3], ia[4], ia[5], - ia[6]); - else - PyErr_SetString(PyExc_ValueError, - "unexpected value from _strptime._strptime"); + if (module == NULL) { + module = PyImport_ImportModuleNoBlock("_strptime"); + if(module == NULL) + return NULL; } - Py_XDECREF(obj); - Py_XDECREF(st); - Py_XDECREF(frac); - return result; + return PyObject_CallMethod(module, "_strptime_datetime", "uu", + string, format); } /* Return new datetime from date/datetime and time arguments. */ From python-checkins at python.org Thu Jun 17 20:32:37 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Thu, 17 Jun 2010 20:32:37 +0200 (CEST) Subject: [Python-checkins] r82054 - python/branches/release31-maint Message-ID: <20100617183237.EAED4EECF3@mail.python.org> Author: alexander.belopolsky Date: Thu Jun 17 20:32:37 2010 New Revision: 82054 Log: Blocked revisions 82053 via svnmerge ........ r82053 | alexander.belopolsky | 2010-06-17 14:30:34 -0400 (Thu, 17 Jun 2010) | 2 lines Issue #6641: The datetime.strptime method now supports the %z directive. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Thu Jun 17 20:38:20 2010 From: python-checkins at python.org (barry.warsaw) Date: Thu, 17 Jun 2010 20:38:20 +0200 (CEST) Subject: [Python-checkins] r82055 - python/branches/py3k/Python/import.c Message-ID: <20100617183820.3102FEA93@mail.python.org> Author: barry.warsaw Date: Thu Jun 17 20:38:20 2010 New Revision: 82055 Log: Typo repair. 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 Jun 17 20:38:20 2010 @@ -558,10 +558,10 @@ copy can be retrieved from there by calling _PyImport_FindExtension(). - Modules which do support multiple multiple initialization set - their m_size field to a non-negative number (indicating the size - of the module-specific state). They are still recorded in the - extensions dictionary, to avoid loading shared libraries twice. + Modules which do support multiple initialization set their m_size + field to a non-negative number (indicating the size of the + module-specific state). They are still recorded in the extensions + dictionary, to avoid loading shared libraries twice. */ int From python-checkins at python.org Thu Jun 17 22:30:56 2010 From: python-checkins at python.org (florent.xicluna) Date: Thu, 17 Jun 2010 22:30:56 +0200 (CEST) Subject: [Python-checkins] r82056 - python/trunk/Lib/test/test_genericpath.py Message-ID: <20100617203056.E3647EECCC@mail.python.org> Author: florent.xicluna Date: Thu Jun 17 22:30:56 2010 New Revision: 82056 Log: Add few words about test.test_genericpath.CommonTest Modified: python/trunk/Lib/test/test_genericpath.py Modified: python/trunk/Lib/test/test_genericpath.py ============================================================================== --- python/trunk/Lib/test/test_genericpath.py (original) +++ python/trunk/Lib/test/test_genericpath.py Thu Jun 17 22:30:56 2010 @@ -155,6 +155,9 @@ safe_rmdir(test_support.TESTFN) +# Following TestCase is not supposed to be run from test_genericpath. +# It is inherited by other test modules (macpath, ntpath, posixpath). + class CommonTest(GenericTest): # The path module to be tested pathmodule = None From python-checkins at python.org Thu Jun 17 23:43:33 2010 From: python-checkins at python.org (victor.stinner) Date: Thu, 17 Jun 2010 23:43:33 +0200 (CEST) Subject: [Python-checkins] r82057 - in python/branches/py3k: Lib/idlelib/textView.py Misc/NEWS Message-ID: <20100617214333.B960CC31B@mail.python.org> Author: victor.stinner Date: Thu Jun 17 23:43:33 2010 New Revision: 82057 Log: Issue #8203: Fix IDLE Credits dialog: view_file() uses its encoding argument. Modified: python/branches/py3k/Lib/idlelib/textView.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/idlelib/textView.py ============================================================================== --- python/branches/py3k/Lib/idlelib/textView.py (original) +++ python/branches/py3k/Lib/idlelib/textView.py Thu Jun 17 23:43:33 2010 @@ -62,11 +62,7 @@ def view_file(parent, title, filename, encoding=None): try: - if encoding: - import codecs - textFile = codecs.open(filename, 'r') - else: - textFile = open(filename, 'r') + textFile = open(filename, 'r', encoding=encoding) except IOError: import tkinter.messagebox as tkMessageBox tkMessageBox.showerror(title='File Load Error', Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Jun 17 23:43:33 2010 @@ -2047,6 +2047,8 @@ Library ------- +- Issue #8203: Fix IDLE Credits dialog: view_file() uses its encoding argument. + - Issue #5311: bdist_msi can now build packages that do not depend on a specific Python version. From python-checkins at python.org Thu Jun 17 23:45:56 2010 From: python-checkins at python.org (victor.stinner) Date: Thu, 17 Jun 2010 23:45:56 +0200 (CEST) Subject: [Python-checkins] r82058 - in python/branches/release31-maint: Lib/idlelib/textView.py Misc/NEWS Message-ID: <20100617214556.EF866EC57@mail.python.org> Author: victor.stinner Date: Thu Jun 17 23:45:56 2010 New Revision: 82058 Log: Merged revisions 82057 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r82057 | victor.stinner | 2010-06-17 23:43:33 +0200 (jeu., 17 juin 2010) | 2 lines Issue #8203: Fix IDLE Credits dialog: view_file() uses its encoding argument. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/idlelib/textView.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/idlelib/textView.py ============================================================================== --- python/branches/release31-maint/Lib/idlelib/textView.py (original) +++ python/branches/release31-maint/Lib/idlelib/textView.py Thu Jun 17 23:45:56 2010 @@ -62,11 +62,7 @@ def view_file(parent, title, filename, encoding=None): try: - if encoding: - import codecs - textFile = codecs.open(filename, 'r') - else: - textFile = open(filename, 'r') + textFile = open(filename, 'r', encoding=encoding) except IOError: import tkinter.messagebox as tkMessageBox tkMessageBox.showerror(title='File Load Error', Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Jun 17 23:45:56 2010 @@ -66,6 +66,8 @@ Library ------- +- Issue #8203: Fix IDLE Credits dialog: view_file() uses its encoding argument. + - Issue #8720: fix regression caused by fix for #4050 by making getsourcefile smart enough to find source files in the linecache. From python-checkins at python.org Fri Jun 18 01:08:51 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 18 Jun 2010 01:08:51 +0200 (CEST) Subject: [Python-checkins] r82059 - in python/branches/py3k: Include/traceback.h Misc/NEWS Python/_warnings.c Python/compile.c Python/pythonrun.c Python/traceback.c Message-ID: <20100617230851.1A0C2EEDC5@mail.python.org> Author: victor.stinner Date: Fri Jun 18 01:08:50 2010 New Revision: 82059 Log: Issue #6543: Write the traceback in the terminal encoding instead of utf-8. Fix the encoding of the modules filename. Reindent also traceback.h, just because I hate tabs :-) Modified: python/branches/py3k/Include/traceback.h python/branches/py3k/Misc/NEWS python/branches/py3k/Python/_warnings.c python/branches/py3k/Python/compile.c python/branches/py3k/Python/pythonrun.c python/branches/py3k/Python/traceback.c Modified: python/branches/py3k/Include/traceback.h ============================================================================== --- python/branches/py3k/Include/traceback.h (original) +++ python/branches/py3k/Include/traceback.h Fri Jun 18 01:08:50 2010 @@ -10,16 +10,16 @@ /* Traceback interface */ typedef struct _traceback { - PyObject_HEAD - struct _traceback *tb_next; - struct _frame *tb_frame; - int tb_lasti; - int tb_lineno; + PyObject_HEAD + struct _traceback *tb_next; + struct _frame *tb_frame; + int tb_lasti; + int tb_lineno; } PyTracebackObject; PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); -PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, const char *, int, int); +PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); /* Reveal traceback type so we can typecheck traceback objects */ PyAPI_DATA(PyTypeObject) PyTraceBack_Type; Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 18 01:08:50 2010 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #6543: Write the traceback in the terminal encoding instead of utf-8. + Fix the encoding of the modules filename. + - Issue #9011: Remove buggy and unnecessary (in 3.x) ST->AST compilation code dealing with unary minus applied to a constant. The removed code was mutating the ST, causing a second compilation Modified: python/branches/py3k/Python/_warnings.c ============================================================================== --- python/branches/py3k/Python/_warnings.c (original) +++ python/branches/py3k/Python/_warnings.c Fri Jun 18 01:08:50 2010 @@ -282,8 +282,7 @@ PyFile_WriteString("\n", f_stderr); } else - if (_Py_DisplaySourceLine(f_stderr, _PyUnicode_AsString(filename), - lineno, 2) < 0) + if (_Py_DisplaySourceLine(f_stderr, filename, lineno, 2) < 0) return; PyErr_Clear(); } Modified: python/branches/py3k/Python/compile.c ============================================================================== --- python/branches/py3k/Python/compile.c (original) +++ python/branches/py3k/Python/compile.c Fri Jun 18 01:08:50 2010 @@ -3942,7 +3942,7 @@ freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars)); if (!freevars) goto error; - filename = PyUnicode_DecodeFSDefault(c->c_filename); + filename = PyUnicode_FromString(c->c_filename); if (!filename) goto error; Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Fri Jun 18 01:08:50 2010 @@ -1190,7 +1190,7 @@ d = PyModule_GetDict(m); if (PyDict_GetItemString(d, "__file__") == NULL) { PyObject *f; - f = PyUnicode_DecodeFSDefault(filename); + f = PyUnicode_FromString(filename); if (f == NULL) return -1; if (PyDict_SetItemString(d, "__file__", f) < 0) { Modified: python/branches/py3k/Python/traceback.c ============================================================================== --- python/branches/py3k/Python/traceback.c (original) +++ python/branches/py3k/Python/traceback.c Fri Jun 18 01:08:50 2010 @@ -133,33 +133,38 @@ return 0; } -static int -_Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open_flags) +static PyObject * +_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io) { - int i; - int fd = -1; + Py_ssize_t i; + PyObject *binary; PyObject *v; - Py_ssize_t _npath; - int npath; + Py_ssize_t npath; size_t taillen; PyObject *syspath; const char* path; const char* tail; + const char* filepath; Py_ssize_t len; + filepath = _PyUnicode_AsString(filename); + if (filepath == NULL) { + PyErr_Clear(); + return NULL; + } + /* Search tail of filename in sys.path before giving up */ - tail = strrchr(filename, SEP); + tail = strrchr(filepath, SEP); if (tail == NULL) - tail = filename; + tail = filepath; else tail++; taillen = strlen(tail); syspath = PySys_GetObject("path"); if (syspath == NULL || !PyList_Check(syspath)) - return -1; - _npath = PyList_Size(syspath); - npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int); + return NULL; + npath = PyList_Size(syspath); for (i = 0; i < npath; i++) { v = PyList_GetItem(syspath, i); @@ -170,6 +175,10 @@ if (!PyUnicode_Check(v)) continue; path = _PyUnicode_AsStringAndSize(v, &len); + if (path == NULL) { + PyErr_Clear(); + continue; + } if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) continue; /* Too long */ strcpy(namebuf, path); @@ -178,31 +187,27 @@ if (len > 0 && namebuf[len-1] != SEP) namebuf[len++] = SEP; strcpy(namebuf+len, tail); - Py_BEGIN_ALLOW_THREADS - fd = open(namebuf, open_flags); - Py_END_ALLOW_THREADS - if (0 <= fd) { - return fd; - } + + binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb"); + if (binary != NULL) + return binary; + PyErr_Clear(); } - return -1; + return NULL; } int -_Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent) +_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) { int err = 0; int fd; int i; char *found_encoding; char *encoding; + PyObject *io; + PyObject *binary; PyObject *fob = NULL; PyObject *lineobj = NULL; -#ifdef O_BINARY - const int open_flags = O_RDONLY | O_BINARY; /* necessary for Windows */ -#else - const int open_flags = O_RDONLY; -#endif char buf[MAXPATHLEN+1]; Py_UNICODE *u, *p; Py_ssize_t len; @@ -210,27 +215,32 @@ /* open the file */ if (filename == NULL) return 0; - Py_BEGIN_ALLOW_THREADS - fd = open(filename, open_flags); - Py_END_ALLOW_THREADS - if (fd < 0) { - fd = _Py_FindSourceFile(filename, buf, sizeof(buf), open_flags); - if (fd < 0) + + io = PyImport_ImportModuleNoBlock("io"); + if (io == NULL) + return -1; + binary = PyObject_CallMethod(io, "open", "Os", filename, "rb"); + + if (binary == NULL) { + binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io); + if (binary == NULL) { + Py_DECREF(io); return 0; - filename = buf; + } } /* use the right encoding to decode the file as unicode */ + fd = PyObject_AsFileDescriptor(binary); found_encoding = PyTokenizer_FindEncoding(fd); - encoding = (found_encoding != NULL) ? found_encoding : - (char*)PyUnicode_GetDefaultEncoding(); + encoding = (found_encoding != NULL) ? found_encoding : "utf-8"; lseek(fd, 0, 0); /* Reset position */ - fob = PyFile_FromFd(fd, (char*)filename, "r", -1, (char*)encoding, - NULL, NULL, 1); + fob = PyObject_CallMethod(io, "TextIOWrapper", "Os", binary, encoding); + Py_DECREF(io); + Py_DECREF(binary); PyMem_FREE(found_encoding); + if (fob == NULL) { PyErr_Clear(); - close(fd); return 0; } @@ -287,17 +297,19 @@ } static int -tb_displayline(PyObject *f, const char *filename, int lineno, const char *name) +tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name) { - int err = 0; - char linebuf[2000]; + int err; + PyObject *line; if (filename == NULL || name == NULL) return -1; - /* This is needed by Emacs' compile command */ -#define FMT " File \"%.500s\", line %d, in %.500s\n" - PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name); - err = PyFile_WriteString(linebuf, f); + line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", + filename, lineno, name); + if (line == NULL) + return -1; + err = PyFile_WriteObject(line, f, Py_PRINT_RAW); + Py_DECREF(line); if (err != 0) return err; return _Py_DisplaySourceLine(f, filename, lineno, 4); @@ -316,10 +328,9 @@ while (tb != NULL && err == 0) { if (depth <= limit) { err = tb_displayline(f, - _PyUnicode_AsString( - tb->tb_frame->f_code->co_filename), - tb->tb_lineno, - _PyUnicode_AsString(tb->tb_frame->f_code->co_name)); + tb->tb_frame->f_code->co_filename, + tb->tb_lineno, + tb->tb_frame->f_code->co_name); } depth--; tb = tb->tb_next; From python-checkins at python.org Fri Jun 18 01:11:18 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 18 Jun 2010 01:11:18 +0200 (CEST) Subject: [Python-checkins] r82060 - python/branches/release31-maint Message-ID: <20100617231118.C753FEE9D1@mail.python.org> Author: victor.stinner Date: Fri Jun 18 01:11:18 2010 New Revision: 82060 Log: Blocked revisions 82059 via svnmerge ........ r82059 | victor.stinner | 2010-06-18 01:08:50 +0200 (ven., 18 juin 2010) | 5 lines Issue #6543: Write the traceback in the terminal encoding instead of utf-8. Fix the encoding of the modules filename. Reindent also traceback.h, just because I hate tabs :-) ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Jun 18 01:17:37 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 18 Jun 2010 01:17:37 +0200 (CEST) Subject: [Python-checkins] r82061 - python/branches/py3k/Misc/NEWS Message-ID: <20100617231737.36EBEEEC5B@mail.python.org> Author: victor.stinner Date: Fri Jun 18 01:17:37 2010 New Revision: 82061 Log: Issue #6543: Mention the author of the patch, Amaury Forgeot d'Arc Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 18 01:17:37 2010 @@ -13,7 +13,8 @@ ----------------- - Issue #6543: Write the traceback in the terminal encoding instead of utf-8. - Fix the encoding of the modules filename. + Fix the encoding of the modules filename. Patch written by Amaury Forgeot + d'Arc. - Issue #9011: Remove buggy and unnecessary (in 3.x) ST->AST compilation code dealing with unary minus applied to a constant. From python-checkins at python.org Fri Jun 18 01:20:38 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 18 Jun 2010 01:20:38 +0200 (CEST) Subject: [Python-checkins] r82062 - python/branches/release31-maint Message-ID: <20100617232038.199C3EECA3@mail.python.org> Author: victor.stinner Date: Fri Jun 18 01:20:37 2010 New Revision: 82062 Log: Oops, I did't want to block r82059 (revert r82060) Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Jun 18 01:23:37 2010 From: python-checkins at python.org (victor.stinner) Date: Fri, 18 Jun 2010 01:23:37 +0200 (CEST) Subject: [Python-checkins] r82063 - in python/branches/release31-maint: Include/traceback.h Misc/NEWS Python/_warnings.c Python/compile.c Python/pythonrun.c Python/traceback.c Message-ID: <20100617232337.4CE7AEEDAF@mail.python.org> Author: victor.stinner Date: Fri Jun 18 01:23:37 2010 New Revision: 82063 Log: Merged revisions 82059,82061 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r82059 | victor.stinner | 2010-06-18 01:08:50 +0200 (ven., 18 juin 2010) | 5 lines Issue #6543: Write the traceback in the terminal encoding instead of utf-8. Fix the encoding of the modules filename. Reindent also traceback.h, just because I hate tabs :-) ........ r82061 | victor.stinner | 2010-06-18 01:17:37 +0200 (ven., 18 juin 2010) | 2 lines Issue #6543: Mention the author of the patch, Amaury Forgeot d'Arc ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Include/traceback.h python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Python/_warnings.c python/branches/release31-maint/Python/compile.c python/branches/release31-maint/Python/pythonrun.c python/branches/release31-maint/Python/traceback.c Modified: python/branches/release31-maint/Include/traceback.h ============================================================================== --- python/branches/release31-maint/Include/traceback.h (original) +++ python/branches/release31-maint/Include/traceback.h Fri Jun 18 01:23:37 2010 @@ -10,16 +10,16 @@ /* Traceback interface */ typedef struct _traceback { - PyObject_HEAD - struct _traceback *tb_next; - struct _frame *tb_frame; - int tb_lasti; - int tb_lineno; + PyObject_HEAD + struct _traceback *tb_next; + struct _frame *tb_frame; + int tb_lasti; + int tb_lineno; } PyTracebackObject; PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); -PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, const char *, int, int); +PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); /* Reveal traceback type so we can typecheck traceback objects */ PyAPI_DATA(PyTypeObject) PyTraceBack_Type; Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Jun 18 01:23:37 2010 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #6543: Write the traceback in the terminal encoding instead of utf-8. + Fix the encoding of the modules filename. Patch written by Amaury Forgeot + d'Arc. + - Issue #9011: Remove buggy and unnecessary (in 3.x) ST->AST compilation code dealing with unary minus applied to a constant. The removed code was mutating the ST, causing a second compilation Modified: python/branches/release31-maint/Python/_warnings.c ============================================================================== --- python/branches/release31-maint/Python/_warnings.c (original) +++ python/branches/release31-maint/Python/_warnings.c Fri Jun 18 01:23:37 2010 @@ -282,8 +282,7 @@ PyFile_WriteString("\n", f_stderr); } else - if (_Py_DisplaySourceLine(f_stderr, _PyUnicode_AsString(filename), - lineno, 2) < 0) + if (_Py_DisplaySourceLine(f_stderr, filename, lineno, 2) < 0) return; PyErr_Clear(); } Modified: python/branches/release31-maint/Python/compile.c ============================================================================== --- python/branches/release31-maint/Python/compile.c (original) +++ python/branches/release31-maint/Python/compile.c Fri Jun 18 01:23:37 2010 @@ -4046,7 +4046,7 @@ freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars)); if (!freevars) goto error; - filename = PyUnicode_DecodeFSDefault(c->c_filename); + filename = PyUnicode_FromString(c->c_filename); if (!filename) goto error; Modified: python/branches/release31-maint/Python/pythonrun.c ============================================================================== --- python/branches/release31-maint/Python/pythonrun.c (original) +++ python/branches/release31-maint/Python/pythonrun.c Fri Jun 18 01:23:37 2010 @@ -1160,7 +1160,7 @@ d = PyModule_GetDict(m); if (PyDict_GetItemString(d, "__file__") == NULL) { PyObject *f; - f = PyUnicode_DecodeFSDefault(filename); + f = PyUnicode_FromString(filename); if (f == NULL) return -1; if (PyDict_SetItemString(d, "__file__", f) < 0) { Modified: python/branches/release31-maint/Python/traceback.c ============================================================================== --- python/branches/release31-maint/Python/traceback.c (original) +++ python/branches/release31-maint/Python/traceback.c Fri Jun 18 01:23:37 2010 @@ -134,33 +134,38 @@ return 0; } -static int -_Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open_flags) +static PyObject * +_Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io) { - int i; - int fd = -1; + Py_ssize_t i; + PyObject *binary; PyObject *v; - Py_ssize_t _npath; - int npath; + Py_ssize_t npath; size_t taillen; PyObject *syspath; const char* path; const char* tail; + const char* filepath; Py_ssize_t len; + filepath = _PyUnicode_AsString(filename); + if (filepath == NULL) { + PyErr_Clear(); + return NULL; + } + /* Search tail of filename in sys.path before giving up */ - tail = strrchr(filename, SEP); + tail = strrchr(filepath, SEP); if (tail == NULL) - tail = filename; + tail = filepath; else tail++; taillen = strlen(tail); syspath = PySys_GetObject("path"); if (syspath == NULL || !PyList_Check(syspath)) - return -1; - _npath = PyList_Size(syspath); - npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int); + return NULL; + npath = PyList_Size(syspath); for (i = 0; i < npath; i++) { v = PyList_GetItem(syspath, i); @@ -171,6 +176,10 @@ if (!PyUnicode_Check(v)) continue; path = _PyUnicode_AsStringAndSize(v, &len); + if (path == NULL) { + PyErr_Clear(); + continue; + } if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) continue; /* Too long */ strcpy(namebuf, path); @@ -179,31 +188,27 @@ if (len > 0 && namebuf[len-1] != SEP) namebuf[len++] = SEP; strcpy(namebuf+len, tail); - Py_BEGIN_ALLOW_THREADS - fd = open(namebuf, open_flags); - Py_END_ALLOW_THREADS - if (0 <= fd) { - return fd; - } + + binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb"); + if (binary != NULL) + return binary; + PyErr_Clear(); } - return -1; + return NULL; } int -_Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent) +_Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) { int err = 0; int fd; int i; char *found_encoding; char *encoding; + PyObject *io; + PyObject *binary; PyObject *fob = NULL; PyObject *lineobj = NULL; -#ifdef O_BINARY - const int open_flags = O_RDONLY | O_BINARY; /* necessary for Windows */ -#else - const int open_flags = O_RDONLY; -#endif char buf[MAXPATHLEN+1]; Py_UNICODE *u, *p; Py_ssize_t len; @@ -211,27 +216,32 @@ /* open the file */ if (filename == NULL) return 0; - Py_BEGIN_ALLOW_THREADS - fd = open(filename, open_flags); - Py_END_ALLOW_THREADS - if (fd < 0) { - fd = _Py_FindSourceFile(filename, buf, sizeof(buf), open_flags); - if (fd < 0) + + io = PyImport_ImportModuleNoBlock("io"); + if (io == NULL) + return -1; + binary = PyObject_CallMethod(io, "open", "Os", filename, "rb"); + + if (binary == NULL) { + binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io); + if (binary == NULL) { + Py_DECREF(io); return 0; - filename = buf; + } } /* use the right encoding to decode the file as unicode */ + fd = PyObject_AsFileDescriptor(binary); found_encoding = PyTokenizer_FindEncoding(fd); - encoding = (found_encoding != NULL) ? found_encoding : - (char*)PyUnicode_GetDefaultEncoding(); + encoding = (found_encoding != NULL) ? found_encoding : "utf-8"; lseek(fd, 0, 0); /* Reset position */ - fob = PyFile_FromFd(fd, (char*)filename, "r", -1, (char*)encoding, - NULL, NULL, 1); + fob = PyObject_CallMethod(io, "TextIOWrapper", "Os", binary, encoding); + Py_DECREF(io); + Py_DECREF(binary); PyMem_FREE(found_encoding); + if (fob == NULL) { PyErr_Clear(); - close(fd); return 0; } @@ -288,17 +298,19 @@ } static int -tb_displayline(PyObject *f, const char *filename, int lineno, const char *name) +tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name) { - int err = 0; - char linebuf[2000]; + int err; + PyObject *line; if (filename == NULL || name == NULL) return -1; - /* This is needed by Emacs' compile command */ -#define FMT " File \"%.500s\", line %d, in %.500s\n" - PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name); - err = PyFile_WriteString(linebuf, f); + line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", + filename, lineno, name); + if (line == NULL) + return -1; + err = PyFile_WriteObject(line, f, Py_PRINT_RAW); + Py_DECREF(line); if (err != 0) return err; return _Py_DisplaySourceLine(f, filename, lineno, 4); @@ -317,10 +329,9 @@ while (tb != NULL && err == 0) { if (depth <= limit) { err = tb_displayline(f, - _PyUnicode_AsString( - tb->tb_frame->f_code->co_filename), - tb->tb_lineno, - _PyUnicode_AsString(tb->tb_frame->f_code->co_name)); + tb->tb_frame->f_code->co_filename, + tb->tb_lineno, + tb->tb_frame->f_code->co_name); } depth--; tb = tb->tb_next; From solipsis at pitrou.net Fri Jun 18 01:26:08 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 18 Jun 2010 01:26:08 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r82055): sum=0 Message-ID: <20100617232608.53B3917720@ns6635.ovh.net> py3k results for svn r82055 (hg cset 61c85c90cc3e) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogT8W_yo', '-x'] From python-checkins at python.org Fri Jun 18 02:19:08 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 18 Jun 2010 02:19:08 +0200 (CEST) Subject: [Python-checkins] r82064 - sandbox/branches/py3k-datetime Message-ID: <20100618001908.9DB7AEE984@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 18 02:19:05 2010 New Revision: 82064 Log: A branch to port datetime.py to py3k Added: sandbox/branches/py3k-datetime/ - copied from r82063, /sandbox/trunk/datetime/ From python-checkins at python.org Fri Jun 18 03:18:47 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 18 Jun 2010 03:18:47 +0200 (CEST) Subject: [Python-checkins] r82065 - sandbox/branches/py3k-datetime/datetime.py Message-ID: <20100618011847.DCC4CEEAA9@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 18 03:18:47 2010 New Revision: 82065 Log: Applied changes from PyPy. The result passes original tests. See http://codespeak.net/pypy/dist/pypy/lib/datetime.py Modified: sandbox/branches/py3k-datetime/datetime.py Modified: sandbox/branches/py3k-datetime/datetime.py ============================================================================== --- sandbox/branches/py3k-datetime/datetime.py (original) +++ sandbox/branches/py3k-datetime/datetime.py Fri Jun 18 03:18:47 2010 @@ -12,6 +12,8 @@ Sources for time zone and DST data: http://www.twinsun.com/tz/tz-link.htm +This was originally copied from the sandbox of the CPython CVS repository. +Thanks to Tim Peters for suggesting using it. """ import time as _time @@ -575,9 +577,11 @@ def __add__(self, other): if isinstance(other, timedelta): - return self.__class__(self.__days + other.__days, - self.__seconds + other.__seconds, - self.__microseconds + other.__microseconds) + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self.__days + other.__days, + self.__seconds + other.__seconds, + self.__microseconds + other.__microseconds) return NotImplemented __radd__ = __add__ @@ -593,9 +597,11 @@ return NotImplemented def __neg__(self): - return self.__class__(-self.__days, - -self.__seconds, - -self.__microseconds) + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(-self.__days, + -self.__seconds, + -self.__microseconds) def __pos__(self): return self @@ -608,9 +614,11 @@ def __mul__(self, other): if isinstance(other, (int, long)): - return self.__class__(self.__days * other, - self.__seconds * other, - self.__microseconds * other) + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self.__days * other, + self.__seconds * other, + self.__microseconds * other) return NotImplemented __rmul__ = __mul__ @@ -619,7 +627,7 @@ if isinstance(other, (int, long)): usec = ((self.__days * (24*3600L) + self.__seconds) * 1000000 + self.__microseconds) - return self.__class__(0, 0, usec // other) + return timedelta(0, 0, usec // other) return NotImplemented __floordiv__ = __div__ @@ -728,7 +736,7 @@ if isinstance(year, str): # Pickle support self = object.__new__(cls) - self.__setstate((year,)) + self.__setstate(year) return self _check_date_fields(year, month, day) self = object.__new__(cls) @@ -901,7 +909,7 @@ self.__month, self.__day + other.days) self._checkOverflow(t.year) - result = self.__class__(t.year, t.month, t.day) + result = date(t.year, t.month, t.day) return result raise TypeError # XXX Should be 'return NotImplemented', but there's a bug in 2.2... @@ -964,10 +972,9 @@ yhi, ylo = divmod(self.__year, 256) return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) - def __setstate(self, t): - assert isinstance(t, tuple) and len(t) == 1, `t` - string = t[0] - assert len(string) == 4 + def __setstate(self, string): + if len(string) != 4 or not (1 <= ord(string[2]) <= 12): + raise TypeError("not enough arguments") yhi, ylo, self.__month, self.__day = map(ord, string) self.__year = yhi * 256 + ylo @@ -1090,7 +1097,7 @@ self = object.__new__(cls) if isinstance(hour, str): # Pickle support - self.__setstate((hour, minute or None)) + self.__setstate(hour, minute or None) return self _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) @@ -1328,21 +1335,16 @@ else: return (basestate, self._tzinfo) - def __setstate(self, state): - assert isinstance(state, tuple) - assert 1 <= len(state) <= 2 - string = state[0] - assert len(string) == 6 + def __setstate(self, string, tzinfo): + if len(string) != 6 or ord(string[0]) >= 24: + raise TypeError("an integer is required") self.__hour, self.__minute, self.__second, us1, us2, us3 = \ map(ord, string) self.__microsecond = (((us1 << 8) | us2) << 8) | us3 - if len(state) == 1: - self._tzinfo = None - else: - self._tzinfo = state[1] + self._tzinfo = tzinfo def __reduce__(self): - return (self.__class__, self.__getstate()) + return (time, self.__getstate()) _time_class = time # so functions w/ args named "time" can get at the class @@ -1360,7 +1362,7 @@ if isinstance(year, str): # Pickle support self = date.__new__(cls, year[:4]) - self.__setstate((year, month)) + self.__setstate(year, month) return self _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) @@ -1395,6 +1397,10 @@ converter = _time.localtime else: converter = _time.gmtime + if 1 - (t % 1.0) < 0.000001: + t = float(int(t)) + 1 + if t < 0: + t -= 1 y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) us = int((t % 1.0) * 1000000) ss = min(ss, 59) # clamp out leap seconds if the platform has them @@ -1406,6 +1412,10 @@ def utcfromtimestamp(cls, t): "Construct a UTC datetime from a POSIX timestamp (like time.time())." + if 1 - (t % 1.0) < 0.000001: + t = float(int(t)) + 1 + if t < 0: + t -= 1 y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t) us = int((t % 1.0) * 1000000) ss = min(ss, 59) # clamp out leap seconds if the platform has them @@ -1559,8 +1569,10 @@ "Convert to formal string, for repr()." L = [self.__year, self.__month, self.__day, # These are never zero self.__hour, self.__minute, self.__second, self.__microsecond] - while L[-1] == 0: + if L[-1] == 0: del L[-1] + if L[-1] == 0: + del L[-1] s = ", ".join(map(str, L)) s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s) if self._tzinfo is not None: @@ -1572,6 +1584,11 @@ "Convert to string, for str()." return self.isoformat(sep=' ') + @classmethod + def strptime(cls, date_string, format): + 'string, format -> new datetime parsed from a string (like time.strptime()).' + return cls(*_time.strptime(date_string, format)[0:6]) + def utcoffset(self): """Return the timezone offset in minutes east of UTC (negative west of UTC).""" @@ -1624,7 +1641,7 @@ def __eq__(self, other): if isinstance(other, datetime): return self.__cmp(other) == 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: return False @@ -1632,7 +1649,7 @@ def __ne__(self, other): if isinstance(other, datetime): return self.__cmp(other) != 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: return True @@ -1640,7 +1657,7 @@ def __le__(self, other): if isinstance(other, datetime): return self.__cmp(other) <= 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1648,7 +1665,7 @@ def __lt__(self, other): if isinstance(other, datetime): return self.__cmp(other) < 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1656,7 +1673,7 @@ def __ge__(self, other): if isinstance(other, datetime): return self.__cmp(other) >= 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1664,7 +1681,7 @@ def __gt__(self, other): if isinstance(other, datetime): return self.__cmp(other) > 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1712,7 +1729,7 @@ self.__second + other.seconds, self.__microsecond + other.microseconds) self._checkOverflow(t.year) - result = self.__class__(t.year, t.month, t.day, + result = datetime(t.year, t.month, t.day, t.hour, t.minute, t.second, t.microsecond, tzinfo=self._tzinfo) return result @@ -1767,19 +1784,12 @@ else: return (basestate, self._tzinfo) - def __setstate(self, state): - assert isinstance(state, tuple) - assert 1 <= len(state) <= 2 - string = state[0] - assert len(string) == 10 + def __setstate(self, string, tzinfo): (yhi, ylo, self.__month, self.__day, self.__hour, self.__minute, self.__second, us1, us2, us3) = map(ord, string) self.__year = yhi * 256 + ylo self.__microsecond = (((us1 << 8) | us2) << 8) | us3 - if len(state) == 1: - self._tzinfo = None - else: - self._tzinfo = state[1] + self._tzinfo = tzinfo def __reduce__(self): return (self.__class__, self.__getstate()) @@ -1999,9 +2009,3 @@ pretty bizarre, and a tzinfo subclass can override fromutc() if it is. """ -def _test(): - import test_datetime - test_datetime.test_main() - -if __name__ == "__main__": - _test() From python-checkins at python.org Fri Jun 18 03:25:47 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 18 Jun 2010 03:25:47 +0200 (CEST) Subject: [Python-checkins] r82066 - in sandbox/branches/py3k-datetime: datetime.py test_datetime.py Message-ID: <20100618012547.1FBF3EE9AA@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 18 03:25:46 2010 New Revision: 82066 Log: Added 2.7 features Modified: sandbox/branches/py3k-datetime/datetime.py sandbox/branches/py3k-datetime/test_datetime.py Modified: sandbox/branches/py3k-datetime/datetime.py ============================================================================== --- sandbox/branches/py3k-datetime/datetime.py (original) +++ sandbox/branches/py3k-datetime/datetime.py Fri Jun 18 03:25:46 2010 @@ -180,6 +180,7 @@ raise ValueError("year=%d is before 1900; the datetime strftime() " "methods require year >= 1900" % year) # Don't call _utcoffset() or tzname() unless actually needed. + freplace = None # the string to use for %f zreplace = None # the string to use for %z Zreplace = None # the string to use for %Z @@ -194,7 +195,12 @@ if i < n: ch = format[i] i += 1 - if ch == 'z': + if ch == 'f': + if freplace is None: + freplace = '%06d' % getattr(object, + 'microsecond', 0) + newformat.append(freplace) + elif ch == 'z': if zreplace is None: zreplace = "" if hasattr(object, "_utcoffset"): @@ -570,6 +576,9 @@ s = s + ".%06d" % self.__microseconds return s + def total_seconds(self): + return ((self.days * 86400 + self.seconds)*10**6 + + self.microseconds).__truediv__(10**6) days = property(lambda self: self.__days, doc="days") seconds = property(lambda self: self.__seconds, doc="seconds") microseconds = property(lambda self: self.__microseconds, @@ -790,6 +799,11 @@ "Format using strftime()." return _wrap_strftime(self, fmt, self.timetuple()) + def __format__(self, fmt): + if len(fmt) != 0: + return self.strftime(fmt) + return str(self) + def isoformat(self): """Return the date formatted according to ISO. @@ -1249,6 +1263,11 @@ 0, 1, -1) return _wrap_strftime(self, fmt, timetuple) + def __format__(self, fmt): + if len(fmt) != 0: + return self.strftime(fmt) + return str(self) + # Timezone functions def utcoffset(self): @@ -1587,7 +1606,9 @@ @classmethod def strptime(cls, date_string, format): 'string, format -> new datetime parsed from a string (like time.strptime()).' - return cls(*_time.strptime(date_string, format)[0:6]) + import _strptime + tt, us = _strptime._strptime(date_string, format) + return cls(*(tt[0:6] + (us,))) def utcoffset(self): """Return the timezone offset in minutes east of UTC (negative west of Modified: sandbox/branches/py3k-datetime/test_datetime.py ============================================================================== --- sandbox/branches/py3k-datetime/test_datetime.py (original) +++ sandbox/branches/py3k-datetime/test_datetime.py Fri Jun 18 03:25:46 2010 @@ -2,19 +2,20 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ - +from __future__ import division import sys import pickle import cPickle import unittest +from test import test_support + from datetime import MINYEAR, MAXYEAR from datetime import timedelta from datetime import tzinfo from datetime import time from datetime import date, datetime -# Before Python 2.3, proto=2 was taken as a synonym for proto=1. pickle_choices = [(pickler, unpickler, proto) for pickler in pickle, cPickle for unpickler in pickle, cPickle @@ -78,9 +79,9 @@ def __init__(self, offset, name): self.__offset = offset self.__name = name - self.failUnless(issubclass(NotEnough, tzinfo)) + self.assertTrue(issubclass(NotEnough, tzinfo)) ne = NotEnough(3, "NotByALongShot") - self.failUnless(isinstance(ne, tzinfo)) + self.assertIsInstance(ne, tzinfo) dt = datetime.now() self.assertRaises(NotImplementedError, ne.tzname, dt) @@ -89,7 +90,7 @@ def test_normal(self): fo = FixedOffset(3, "Three") - self.failUnless(isinstance(fo, tzinfo)) + self.assertIsInstance(fo, tzinfo) for dt in datetime.now(), None: self.assertEqual(fo.utcoffset(dt), timedelta(minutes=3)) self.assertEqual(fo.tzname(dt), "Three") @@ -100,33 +101,33 @@ # carry no data), but they need to be picklable anyway else # concrete subclasses can't be pickled. orig = tzinfo.__new__(tzinfo) - self.failUnless(type(orig) is tzinfo) + self.assertTrue(type(orig) is tzinfo) for pickler, unpickler, proto in pickle_choices: - green = pickler.dumps(orig, proto) - derived = unpickler.loads(green) - self.failUnless(type(derived) is tzinfo) + green = pickler.dumps(orig, proto) + derived = unpickler.loads(green) + self.assertTrue(type(derived) is tzinfo) def test_pickling_subclass(self): # Make sure we can pickle/unpickle an instance of a subclass. offset = timedelta(minutes=-300) orig = PicklableFixedOffset(offset, 'cookie') - self.failUnless(isinstance(orig, tzinfo)) - self.failUnless(type(orig) is PicklableFixedOffset) + self.assertIsInstance(orig, tzinfo) + self.assertTrue(type(orig) is PicklableFixedOffset) self.assertEqual(orig.utcoffset(None), offset) self.assertEqual(orig.tzname(None), 'cookie') for pickler, unpickler, proto in pickle_choices: - green = pickler.dumps(orig, proto) - derived = unpickler.loads(green) - self.failUnless(isinstance(derived, tzinfo)) - self.failUnless(type(derived) is PicklableFixedOffset) - self.assertEqual(derived.utcoffset(None), offset) - self.assertEqual(derived.tzname(None), 'cookie') + green = pickler.dumps(orig, proto) + derived = unpickler.loads(green) + self.assertIsInstance(derived, tzinfo) + self.assertTrue(type(derived) is PicklableFixedOffset) + self.assertEqual(derived.utcoffset(None), offset) + self.assertEqual(derived.tzname(None), 'cookie') ############################################################################# # Base clase for testing a particular aspect of timedelta, time, date and # datetime comparisons. -class HarmlessMixedComparison(unittest.TestCase): +class HarmlessMixedComparison: # Test that __eq__ and __ne__ don't complain for mixed-type comparisons. # Subclasses must define 'theclass', and theclass(1, 1, 1) must be a @@ -135,16 +136,13 @@ def test_harmless_mixed_comparison(self): me = self.theclass(1, 1, 1) - self.failIf(me == ()) - self.failUnless(me != ()) - self.failIf(() == me) - self.failUnless(() != me) + self.assertFalse(me == ()) + self.assertTrue(me != ()) + self.assertFalse(() == me) + self.assertTrue(() != me) - self.failUnless(me in [1, 20L, [], me]) - self.failIf(me not in [1, 20L, [], me]) - - self.failUnless([] in [me, 1, 20L, []]) - self.failIf([] not in [me, 1, 20L, []]) + self.assertIn(me, [1, 20L, [], me]) + self.assertIn([], [me, 1, 20L, []]) def test_harmful_mixed_comparison(self): me = self.theclass(1, 1, 1) @@ -165,7 +163,7 @@ ############################################################################# # timedelta tests -class TestTimeDelta(HarmlessMixedComparison): +class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): theclass = timedelta @@ -252,7 +250,7 @@ self.assertRaises(TypeError, lambda: a // x) self.assertRaises(TypeError, lambda: x // a) - # Divison of int by timedelta doesn't make sense. + # Division of int by timedelta doesn't make sense. # Division by zero doesn't make sense. for zero in 0, 0L: self.assertRaises(TypeError, lambda: zero // a) @@ -265,6 +263,20 @@ self.assertEqual(td.seconds, seconds) self.assertEqual(td.microseconds, us) + def test_total_seconds(self): + td = timedelta(days=365) + self.assertEqual(td.total_seconds(), 31536000.0) + for total_seconds in [123456.789012, -123456.789012, 0.123456, 0, 1e6]: + td = timedelta(seconds=total_seconds) + self.assertEqual(td.total_seconds(), total_seconds) + # Issue8644: Test that td.total_seconds() has the same + # accuracy as td / timedelta(seconds=1). + for ms in [-1, -2, -123]: + td = timedelta(microseconds=ms) + self.assertEqual(td.total_seconds(), + ((24*3600*td.days + td.seconds)*10**6 + + td.microseconds)/10**6) + def test_carries(self): t1 = timedelta(days=100, weeks=-7, @@ -306,29 +318,29 @@ def test_compare(self): t1 = timedelta(2, 3, 4) t2 = timedelta(2, 3, 4) - self.failUnless(t1 == t2) - self.failUnless(t1 <= t2) - self.failUnless(t1 >= t2) - self.failUnless(not t1 != t2) - self.failUnless(not t1 < t2) - self.failUnless(not t1 > t2) + self.assertTrue(t1 == t2) + self.assertTrue(t1 <= t2) + self.assertTrue(t1 >= t2) + self.assertTrue(not t1 != t2) + self.assertTrue(not t1 < t2) + self.assertTrue(not t1 > t2) self.assertEqual(cmp(t1, t2), 0) self.assertEqual(cmp(t2, t1), 0) for args in (3, 3, 3), (2, 4, 4), (2, 3, 5): t2 = timedelta(*args) # this is larger than t1 - self.failUnless(t1 < t2) - self.failUnless(t2 > t1) - self.failUnless(t1 <= t2) - self.failUnless(t2 >= t1) - self.failUnless(t1 != t2) - self.failUnless(t2 != t1) - self.failUnless(not t1 == t2) - self.failUnless(not t2 == t1) - self.failUnless(not t1 > t2) - self.failUnless(not t2 < t1) - self.failUnless(not t1 >= t2) - self.failUnless(not t2 <= t1) + self.assertTrue(t1 < t2) + self.assertTrue(t2 > t1) + self.assertTrue(t1 <= t2) + self.assertTrue(t2 >= t1) + self.assertTrue(t1 != t2) + self.assertTrue(t2 != t1) + self.assertTrue(not t1 == t2) + self.assertTrue(not t2 == t1) + self.assertTrue(not t1 > t2) + self.assertTrue(not t2 < t1) + self.assertTrue(not t1 >= t2) + self.assertTrue(not t2 <= t1) self.assertEqual(cmp(t1, t2), -1) self.assertEqual(cmp(t2, t1), 1) @@ -376,7 +388,7 @@ # Verify td -> string -> td identity. s = repr(td) - self.failUnless(s.startswith('datetime.')) + self.assertTrue(s.startswith('datetime.')) s = s[9:] td2 = eval(s) self.assertEqual(td, td2) @@ -386,10 +398,10 @@ self.assertEqual(td, td2) def test_resolution_info(self): - self.assert_(isinstance(timedelta.min, timedelta)) - self.assert_(isinstance(timedelta.max, timedelta)) - self.assert_(isinstance(timedelta.resolution, timedelta)) - self.assert_(timedelta.max > timedelta.min) + self.assertIsInstance(timedelta.min, timedelta) + self.assertIsInstance(timedelta.max, timedelta) + self.assertIsInstance(timedelta.resolution, timedelta) + self.assertTrue(timedelta.max > timedelta.min) self.assertEqual(timedelta.min, timedelta(-999999999)) self.assertEqual(timedelta.max, timedelta(999999999, 24*3600-1, 1e6-1)) self.assertEqual(timedelta.resolution, timedelta(0, 0, 1)) @@ -436,11 +448,42 @@ (-1, 24*3600-1, 999999)) def test_bool(self): - self.failUnless(timedelta(1)) - self.failUnless(timedelta(0, 1)) - self.failUnless(timedelta(0, 0, 1)) - self.failUnless(timedelta(microseconds=1)) - self.failUnless(not timedelta(0)) + self.assertTrue(timedelta(1)) + self.assertTrue(timedelta(0, 1)) + self.assertTrue(timedelta(0, 0, 1)) + self.assertTrue(timedelta(microseconds=1)) + self.assertTrue(not timedelta(0)) + + def test_subclass_timedelta(self): + + class T(timedelta): + @staticmethod + def from_td(td): + return T(td.days, td.seconds, td.microseconds) + + def as_hours(self): + sum = (self.days * 24 + + self.seconds / 3600.0 + + self.microseconds / 3600e6) + return round(sum) + + t1 = T(days=1) + self.assertTrue(type(t1) is T) + self.assertEqual(t1.as_hours(), 24) + + t2 = T(days=-1, seconds=-3600) + self.assertTrue(type(t2) is T) + self.assertEqual(t2.as_hours(), -25) + + t3 = t1 + t2 + self.assertTrue(type(t3) is timedelta) + t4 = T.from_td(t3) + self.assertTrue(type(t4) is T) + self.assertEqual(t3.days, t4.days) + self.assertEqual(t3.seconds, t4.seconds) + self.assertEqual(t3.microseconds, t4.microseconds) + self.assertEqual(str(t3), str(t4)) + self.assertEqual(t4.as_hours(), -1) ############################################################################# # date tests @@ -478,7 +521,10 @@ dt2 = dt - delta self.assertEqual(dt2, dt - days) -class TestDate(HarmlessMixedComparison): +class SubclassDate(date): + sub_var = 1 + +class TestDate(HarmlessMixedComparison, unittest.TestCase): # Tests here should pass for both dates and datetimes, except for a # few tests that TestDateTime overrides. @@ -495,7 +541,7 @@ self.theclass.today()): # Verify dt -> string -> date identity. s = repr(dt) - self.failUnless(s.startswith('datetime.')) + self.assertTrue(s.startswith('datetime.')) s = s[9:] dt2 = eval(s) self.assertEqual(dt, dt2) @@ -516,8 +562,8 @@ fromord = self.theclass.fromordinal(n) self.assertEqual(d, fromord) if hasattr(fromord, "hour"): - # if we're checking something fancier than a date, verify - # the extra fields have been zeroed out + # if we're checking something fancier than a date, verify + # the extra fields have been zeroed out self.assertEqual(fromord.hour, 0) self.assertEqual(fromord.minute, 0) self.assertEqual(fromord.second, 0) @@ -674,15 +720,16 @@ def test_overflow(self): tiny = self.theclass.resolution - dt = self.theclass.min + tiny - dt -= tiny # no problem - self.assertRaises(OverflowError, dt.__sub__, tiny) - self.assertRaises(OverflowError, dt.__add__, -tiny) - - dt = self.theclass.max - tiny - dt += tiny # no problem - self.assertRaises(OverflowError, dt.__add__, tiny) - self.assertRaises(OverflowError, dt.__sub__, -tiny) + for delta in [tiny, timedelta(1), timedelta(2)]: + dt = self.theclass.min + delta + dt -= delta # no problem + self.assertRaises(OverflowError, dt.__sub__, delta) + self.assertRaises(OverflowError, dt.__add__, -delta) + + dt = self.theclass.max - delta + dt += delta # no problem + self.assertRaises(OverflowError, dt.__add__, delta) + self.assertRaises(OverflowError, dt.__sub__, -delta) def test_fromtimestamp(self): import time @@ -695,6 +742,15 @@ self.assertEqual(d.month, month) self.assertEqual(d.day, day) + def test_insane_fromtimestamp(self): + # It's possible that some platform maps time_t to double, + # and that this test will fail there. This test should + # exempt such platforms (provided they return reasonable + # results!). + for insane in -1e200, 1e200: + self.assertRaises(ValueError, self.theclass.fromtimestamp, + insane) + def test_today(self): import time @@ -720,7 +776,7 @@ # It worked or it didn't. If it didn't, assume it's reason #2, and # let the test pass if they're within half a second of each other. - self.failUnless(today == todayagain or + self.assertTrue(today == todayagain or abs(todayagain - today) < timedelta(seconds=0.5)) def test_weekday(self): @@ -799,19 +855,68 @@ def test_strftime(self): t = self.theclass(2005, 3, 2) self.assertEqual(t.strftime("m:%m d:%d y:%y"), "m:03 d:02 y:05") + self.assertEqual(t.strftime(""), "") # SF bug #761337 + self.assertEqual(t.strftime('x'*1000), 'x'*1000) # SF bug #1556784 self.assertRaises(TypeError, t.strftime) # needs an arg self.assertRaises(TypeError, t.strftime, "one", "two") # too many args self.assertRaises(TypeError, t.strftime, 42) # arg wrong type + # test that unicode input is allowed (issue 2782) + self.assertEqual(t.strftime(u"%m"), "03") + # A naive object replaces %z and %Z w/ empty strings. self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + #make sure that invalid format specifiers are handled correctly + #self.assertRaises(ValueError, t.strftime, "%e") + #self.assertRaises(ValueError, t.strftime, "%") + #self.assertRaises(ValueError, t.strftime, "%#") + + #oh well, some systems just ignore those invalid ones. + #at least, excercise them to make sure that no crashes + #are generated + for f in ["%e", "%", "%#"]: + try: + t.strftime(f) + except ValueError: + pass + + #check that this standard extension works + t.strftime("%f") + + + def test_format(self): + dt = self.theclass(2007, 9, 10) + self.assertEqual(dt.__format__(''), str(dt)) + + # check that a derived class's __str__() gets called + class A(self.theclass): + def __str__(self): + return 'A' + a = A(2007, 9, 10) + self.assertEqual(a.__format__(''), 'A') + + # check that a derived class's strftime gets called + class B(self.theclass): + def strftime(self, format_spec): + return 'B' + b = B(2007, 9, 10) + self.assertEqual(b.__format__(''), str(dt)) + + for fmt in ["m:%m d:%d y:%y", + "m:%m d:%d y:%y H:%H M:%M S:%S", + "%z %Z", + ]: + self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) + self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) + self.assertEqual(b.__format__(fmt), 'B') + def test_resolution_info(self): - self.assert_(isinstance(self.theclass.min, self.theclass)) - self.assert_(isinstance(self.theclass.max, self.theclass)) - self.assert_(isinstance(self.theclass.resolution, timedelta)) - self.assert_(self.theclass.max > self.theclass.min) + self.assertIsInstance(self.theclass.min, self.theclass) + self.assertIsInstance(self.theclass.max, self.theclass) + self.assertIsInstance(self.theclass.resolution, timedelta) + self.assertTrue(self.theclass.max > self.theclass.min) def test_extreme_timedelta(self): big = self.theclass.max - self.theclass.min @@ -859,29 +964,29 @@ def test_compare(self): t1 = self.theclass(2, 3, 4) t2 = self.theclass(2, 3, 4) - self.failUnless(t1 == t2) - self.failUnless(t1 <= t2) - self.failUnless(t1 >= t2) - self.failUnless(not t1 != t2) - self.failUnless(not t1 < t2) - self.failUnless(not t1 > t2) + self.assertTrue(t1 == t2) + self.assertTrue(t1 <= t2) + self.assertTrue(t1 >= t2) + self.assertTrue(not t1 != t2) + self.assertTrue(not t1 < t2) + self.assertTrue(not t1 > t2) self.assertEqual(cmp(t1, t2), 0) self.assertEqual(cmp(t2, t1), 0) for args in (3, 3, 3), (2, 4, 4), (2, 3, 5): t2 = self.theclass(*args) # this is larger than t1 - self.failUnless(t1 < t2) - self.failUnless(t2 > t1) - self.failUnless(t1 <= t2) - self.failUnless(t2 >= t1) - self.failUnless(t1 != t2) - self.failUnless(t2 != t1) - self.failUnless(not t1 == t2) - self.failUnless(not t2 == t1) - self.failUnless(not t1 > t2) - self.failUnless(not t2 < t1) - self.failUnless(not t1 >= t2) - self.failUnless(not t2 <= t1) + self.assertTrue(t1 < t2) + self.assertTrue(t2 > t1) + self.assertTrue(t1 <= t2) + self.assertTrue(t2 >= t1) + self.assertTrue(t1 != t2) + self.assertTrue(t2 != t1) + self.assertTrue(not t1 == t2) + self.assertTrue(not t2 == t1) + self.assertTrue(not t1 > t2) + self.assertTrue(not t2 < t1) + self.assertTrue(not t1 >= t2) + self.assertTrue(not t2 <= t1) self.assertEqual(cmp(t1, t2), -1) self.assertEqual(cmp(t2, t1), 1) @@ -910,6 +1015,7 @@ # compare-by-address (which never says "equal" for distinct # objects). return 0 + __hash__ = None # Silence Py3k warning # This still errors, because date and datetime comparison raise # TypeError instead of NotImplemented when they don't know what to @@ -934,15 +1040,15 @@ their = Comparable() self.assertEqual(cmp(our, their), 0) self.assertEqual(cmp(their, our), 0) - self.failUnless(our == their) - self.failUnless(their == our) + self.assertTrue(our == their) + self.assertTrue(their == our) def test_bool(self): # All dates are considered true. - self.failUnless(self.theclass.min) - self.failUnless(self.theclass.max) + self.assertTrue(self.theclass.min) + self.assertTrue(self.theclass.max) - def test_srftime_out_of_range(self): + def test_strftime_out_of_range(self): # For nasty technical reasons, we can't handle years before 1900. cls = self.theclass self.assertEqual(cls(1900, 1, 1).strftime("%Y"), "1900") @@ -970,9 +1076,68 @@ base = cls(2000, 2, 29) self.assertRaises(ValueError, base.replace, year=2001) + def test_subclass_date(self): + + class C(self.theclass): + theAnswer = 42 + + def __new__(cls, *args, **kws): + temp = kws.copy() + extra = temp.pop('extra') + result = self.theclass.__new__(cls, *args, **temp) + result.extra = extra + return result + + def newmeth(self, start): + return start + self.year + self.month + + args = 2003, 4, 14 + + dt1 = self.theclass(*args) + dt2 = C(*args, **{'extra': 7}) + + self.assertEqual(dt2.__class__, C) + self.assertEqual(dt2.theAnswer, 42) + self.assertEqual(dt2.extra, 7) + self.assertEqual(dt1.toordinal(), dt2.toordinal()) + self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month - 7) + + def test_pickling_subclass_date(self): + + args = 6, 7, 23 + orig = SubclassDate(*args) + for pickler, unpickler, proto in pickle_choices: + green = pickler.dumps(orig, proto) + derived = unpickler.loads(green) + self.assertEqual(orig, derived) + + def test_backdoor_resistance(self): + # For fast unpickling, the constructor accepts a pickle string. + # This is a low-overhead backdoor. A user can (by intent or + # mistake) pass a string directly, which (if it's the right length) + # will get treated like a pickle, and bypass the normal sanity + # checks in the constructor. This can create insane objects. + # The constructor doesn't want to burn the time to validate all + # fields, but does check the month field. This stops, e.g., + # datetime.datetime('1995-03-25') from yielding an insane object. + base = '1995-03-25' + if not issubclass(self.theclass, datetime): + base = base[:4] + for month_byte in '9', chr(0), chr(13), '\xff': + self.assertRaises(TypeError, self.theclass, + base[:2] + month_byte + base[3:]) + for ord_byte in range(1, 13): + # This shouldn't blow up because of the month byte alone. If + # the implementation changes to do more-careful checking, it may + # blow up because other fields are insane. + self.theclass(base[:2] + chr(ord_byte) + base[3:]) + ############################################################################# # datetime tests +class SubclassDatetime(datetime): + sub_var = 1 + class TestDateTime(TestDate): theclass = datetime @@ -1004,7 +1169,7 @@ self.theclass.now()): # Verify dt -> string -> datetime identity. s = repr(dt) - self.failUnless(s.startswith('datetime.')) + self.assertTrue(s.startswith('datetime.')) s = s[9:] dt2 = eval(s) self.assertEqual(dt, dt2) @@ -1020,6 +1185,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") @@ -1030,6 +1196,32 @@ # str is ISO format with the separator forced to a blank. self.assertEqual(str(t), "0002-03-02 00:00:00") + def test_format(self): + dt = self.theclass(2007, 9, 10, 4, 5, 1, 123) + self.assertEqual(dt.__format__(''), str(dt)) + + # check that a derived class's __str__() gets called + class A(self.theclass): + def __str__(self): + return 'A' + a = A(2007, 9, 10, 4, 5, 1, 123) + self.assertEqual(a.__format__(''), 'A') + + # check that a derived class's strftime gets called + class B(self.theclass): + def strftime(self, format_spec): + return 'B' + b = B(2007, 9, 10, 4, 5, 1, 123) + self.assertEqual(b.__format__(''), str(dt)) + + for fmt in ["m:%m d:%d y:%y", + "m:%m d:%d y:%y H:%H M:%M S:%S", + "%z %Z", + ]: + self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) + self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) + self.assertEqual(b.__format__(fmt), 'B') + def test_more_ctime(self): # Test fields that TestDate doesn't touch. import time @@ -1051,7 +1243,7 @@ dt2 = self.theclass(2002, 3, 1, 10, 0, 0) dt3 = self.theclass(2002, 3, 1, 9, 0, 0) self.assertEqual(dt1, dt3) - self.assert_(dt2 > dt3) + self.assertTrue(dt2 > dt3) # Make sure comparison doesn't forget microseconds, and isn't done # via comparing a float timestamp (an IEEE double doesn't have enough @@ -1062,7 +1254,18 @@ us = timedelta(microseconds=1) dt2 = dt1 + us self.assertEqual(dt2 - dt1, us) - self.assert_(dt1 < dt2) + self.assertTrue(dt1 < dt2) + + def test_strftime_with_bad_tzname_replace(self): + # verify ok if tzinfo.tzname().replace() returns a non-string + class MyTzInfo(FixedOffset): + def tzname(self, dt): + class MyStr(str): + def replace(self, *args): + return None + return MyStr('name') + t = self.theclass(2005, 3, 2, 0, 0, 0, 0, MyTzInfo(3, 'name')) + self.assertRaises(TypeError, t.strftime, '%Z') def test_bad_constructor_arguments(self): # bad years @@ -1216,6 +1419,14 @@ self.assertEqual(b.month, 2) self.assertEqual(b.day, 7) + def test_pickling_subclass_datetime(self): + args = 6, 7, 23, 20, 59, 1, 64**2 + orig = SubclassDatetime(*args) + for pickler, unpickler, proto in pickle_choices: + green = pickler.dumps(orig, proto) + derived = unpickler.loads(green) + self.assertEqual(orig, derived) + def test_more_compare(self): # The test_compare() inherited from TestDate covers the error cases. # We just want to test lexicographic ordering on the members datetime @@ -1223,12 +1434,12 @@ args = [2000, 11, 29, 20, 58, 16, 999998] t1 = self.theclass(*args) t2 = self.theclass(*args) - self.failUnless(t1 == t2) - self.failUnless(t1 <= t2) - self.failUnless(t1 >= t2) - self.failUnless(not t1 != t2) - self.failUnless(not t1 < t2) - self.failUnless(not t1 > t2) + self.assertTrue(t1 == t2) + self.assertTrue(t1 <= t2) + self.assertTrue(t1 >= t2) + self.assertTrue(not t1 != t2) + self.assertTrue(not t1 < t2) + self.assertTrue(not t1 > t2) self.assertEqual(cmp(t1, t2), 0) self.assertEqual(cmp(t2, t1), 0) @@ -1236,18 +1447,18 @@ newargs = args[:] newargs[i] = args[i] + 1 t2 = self.theclass(*newargs) # this is larger than t1 - self.failUnless(t1 < t2) - self.failUnless(t2 > t1) - self.failUnless(t1 <= t2) - self.failUnless(t2 >= t1) - self.failUnless(t1 != t2) - self.failUnless(t2 != t1) - self.failUnless(not t1 == t2) - self.failUnless(not t2 == t1) - self.failUnless(not t1 > t2) - self.failUnless(not t2 < t1) - self.failUnless(not t1 >= t2) - self.failUnless(not t2 <= t1) + self.assertTrue(t1 < t2) + self.assertTrue(t2 > t1) + self.assertTrue(t1 <= t2) + self.assertTrue(t2 >= t1) + self.assertTrue(t1 != t2) + self.assertTrue(t2 != t1) + self.assertTrue(not t1 == t2) + self.assertTrue(not t2 == t1) + self.assertTrue(not t1 > t2) + self.assertTrue(not t2 < t1) + self.assertTrue(not t1 >= t2) + self.assertTrue(not t2 <= t1) self.assertEqual(cmp(t1, t2), -1) self.assertEqual(cmp(t2, t1), 1) @@ -1277,6 +1488,40 @@ got = self.theclass.utcfromtimestamp(ts) self.verify_field_equality(expected, got) + def test_microsecond_rounding(self): + # Test whether fromtimestamp "rounds up" floats that are less + # than one microsecond smaller than an integer. + self.assertEquals(self.theclass.fromtimestamp(0.9999999), + self.theclass.fromtimestamp(1)) + + def test_insane_fromtimestamp(self): + # It's possible that some platform maps time_t to double, + # and that this test will fail there. This test should + # exempt such platforms (provided they return reasonable + # results!). + for insane in -1e200, 1e200: + self.assertRaises(ValueError, self.theclass.fromtimestamp, + insane) + + def test_insane_utcfromtimestamp(self): + # It's possible that some platform maps time_t to double, + # and that this test will fail there. This test should + # exempt such platforms (provided they return reasonable + # results!). + for insane in -1e200, 1e200: + self.assertRaises(ValueError, self.theclass.utcfromtimestamp, + insane) + @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") + def test_negative_float_fromtimestamp(self): + # The result is tz-dependent; at least test that this doesn't + # fail (like it did before bug 1646728 was fixed). + self.theclass.fromtimestamp(-1.05) + + @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") + def test_negative_float_utcfromtimestamp(self): + d = self.theclass.utcfromtimestamp(-1.05) + self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) + def test_utcnow(self): import time @@ -1289,7 +1534,17 @@ if abs(from_timestamp - from_now) <= tolerance: break # Else try again a few times. - self.failUnless(abs(from_timestamp - from_now) <= tolerance) + self.assertTrue(abs(from_timestamp - from_now) <= tolerance) + + def test_strptime(self): + import _strptime + + string = '2004-12-01 13:02:47.197' + format = '%Y-%m-%d %H:%M:%S.%f' + result, frac = _strptime._strptime(string, format) + expected = self.theclass(*(result[0:6]+(frac,))) + got = self.theclass.strptime(string, format) + self.assertEqual(expected, got) def test_more_timetuple(self): # This tests fields beyond those tested by the TestDate.test_timetuple. @@ -1315,9 +1570,9 @@ def test_more_strftime(self): # This tests fields beyond those tested by the TestDate.test_strftime. - t = self.theclass(2004, 12, 31, 6, 22, 33) - self.assertEqual(t.strftime("%m %d %y %S %M %H %j"), - "12 31 04 33 22 06 366") + t = self.theclass(2004, 12, 31, 6, 22, 33, 47) + self.assertEqual(t.strftime("%m %d %y %f %S %M %H %j"), + "12 31 04 000047 33 22 06 366") def test_extract(self): dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234) @@ -1393,7 +1648,37 @@ alsobog = AlsoBogus() self.assertRaises(ValueError, dt.astimezone, alsobog) # also naive -class TestTime(HarmlessMixedComparison): + def test_subclass_datetime(self): + + class C(self.theclass): + theAnswer = 42 + + def __new__(cls, *args, **kws): + temp = kws.copy() + extra = temp.pop('extra') + result = self.theclass.__new__(cls, *args, **temp) + result.extra = extra + return result + + def newmeth(self, start): + return start + self.year + self.month + self.second + + args = 2003, 4, 14, 12, 13, 41 + + dt1 = self.theclass(*args) + dt2 = C(*args, **{'extra': 7}) + + self.assertEqual(dt2.__class__, C) + self.assertEqual(dt2.theAnswer, 42) + self.assertEqual(dt2.extra, 7) + self.assertEqual(dt1.toordinal(), dt2.toordinal()) + self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month + + dt1.second - 7) + +class SubclassTime(time): + sub_var = 1 + +class TestTime(HarmlessMixedComparison, unittest.TestCase): theclass = time @@ -1418,7 +1703,7 @@ # Verify t -> string -> time identity. s = repr(t) - self.failUnless(s.startswith('datetime.')) + self.assertTrue(s.startswith('datetime.')) s = s[9:] t2 = eval(s) self.assertEqual(t, t2) @@ -1432,12 +1717,12 @@ args = [1, 2, 3, 4] t1 = self.theclass(*args) t2 = self.theclass(*args) - self.failUnless(t1 == t2) - self.failUnless(t1 <= t2) - self.failUnless(t1 >= t2) - self.failUnless(not t1 != t2) - self.failUnless(not t1 < t2) - self.failUnless(not t1 > t2) + self.assertTrue(t1 == t2) + self.assertTrue(t1 <= t2) + self.assertTrue(t1 >= t2) + self.assertTrue(not t1 != t2) + self.assertTrue(not t1 < t2) + self.assertTrue(not t1 > t2) self.assertEqual(cmp(t1, t2), 0) self.assertEqual(cmp(t2, t1), 0) @@ -1445,18 +1730,18 @@ newargs = args[:] newargs[i] = args[i] + 1 t2 = self.theclass(*newargs) # this is larger than t1 - self.failUnless(t1 < t2) - self.failUnless(t2 > t1) - self.failUnless(t1 <= t2) - self.failUnless(t2 >= t1) - self.failUnless(t1 != t2) - self.failUnless(t2 != t1) - self.failUnless(not t1 == t2) - self.failUnless(not t2 == t1) - self.failUnless(not t1 > t2) - self.failUnless(not t2 < t1) - self.failUnless(not t1 >= t2) - self.failUnless(not t2 <= t1) + self.assertTrue(t1 < t2) + self.assertTrue(t2 > t1) + self.assertTrue(t1 <= t2) + self.assertTrue(t2 >= t1) + self.assertTrue(t1 != t2) + self.assertTrue(t2 != t1) + self.assertTrue(not t1 == t2) + self.assertTrue(not t2 == t1) + self.assertTrue(not t1 > t2) + self.assertTrue(not t2 < t1) + self.assertTrue(not t1 >= t2) + self.assertTrue(not t2 <= t1) self.assertEqual(cmp(t1, t2), -1) self.assertEqual(cmp(t2, t1), 1) @@ -1553,12 +1838,41 @@ self.assertEqual(t.isoformat(), "00:00:00.100000") self.assertEqual(t.isoformat(), str(t)) + def test_1653736(self): + # verify it doesn't accept extra keyword arguments + t = self.theclass(second=1) + self.assertRaises(TypeError, t.isoformat, foo=3) + def test_strftime(self): t = self.theclass(1, 2, 3, 4) - self.assertEqual(t.strftime('%H %M %S'), "01 02 03") + self.assertEqual(t.strftime('%H %M %S %f'), "01 02 03 000004") # A naive object replaces %z and %Z with empty strings. self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + def test_format(self): + t = self.theclass(1, 2, 3, 4) + self.assertEqual(t.__format__(''), str(t)) + + # check that a derived class's __str__() gets called + class A(self.theclass): + def __str__(self): + return 'A' + a = A(1, 2, 3, 4) + self.assertEqual(a.__format__(''), 'A') + + # check that a derived class's strftime gets called + class B(self.theclass): + def strftime(self, format_spec): + return 'B' + b = B(1, 2, 3, 4) + self.assertEqual(b.__format__(''), str(t)) + + for fmt in ['%H %M %S', + ]: + self.assertEqual(t.__format__(fmt), t.strftime(fmt)) + self.assertEqual(a.__format__(fmt), t.strftime(fmt)) + self.assertEqual(b.__format__(fmt), 'B') + def test_str(self): self.assertEqual(str(self.theclass(1, 2, 3, 4)), "01:02:03.000004") self.assertEqual(str(self.theclass(10, 2, 3, 4000)), "10:02:03.004000") @@ -1580,10 +1894,10 @@ "%s(23, 15)" % name) def test_resolution_info(self): - self.assert_(isinstance(self.theclass.min, self.theclass)) - self.assert_(isinstance(self.theclass.max, self.theclass)) - self.assert_(isinstance(self.theclass.resolution, timedelta)) - self.assert_(self.theclass.max > self.theclass.min) + self.assertIsInstance(self.theclass.min, self.theclass) + self.assertIsInstance(self.theclass.max, self.theclass) + self.assertIsInstance(self.theclass.resolution, timedelta) + self.assertTrue(self.theclass.max > self.theclass.min) def test_pickling(self): args = 20, 59, 16, 64**2 @@ -1593,14 +1907,22 @@ derived = unpickler.loads(green) self.assertEqual(orig, derived) + def test_pickling_subclass_time(self): + args = 20, 59, 16, 64**2 + orig = SubclassTime(*args) + for pickler, unpickler, proto in pickle_choices: + green = pickler.dumps(orig, proto) + derived = unpickler.loads(green) + self.assertEqual(orig, derived) + def test_bool(self): cls = self.theclass - self.failUnless(cls(1)) - self.failUnless(cls(0, 1)) - self.failUnless(cls(0, 0, 1)) - self.failUnless(cls(0, 0, 0, 1)) - self.failUnless(not cls(0)) - self.failUnless(not cls()) + self.assertTrue(cls(1)) + self.assertTrue(cls(0, 1)) + self.assertTrue(cls(0, 0, 1)) + self.assertTrue(cls(0, 0, 0, 1)) + self.assertTrue(not cls(0)) + self.assertTrue(not cls()) def test_replace(self): cls = self.theclass @@ -1627,10 +1949,43 @@ self.assertRaises(ValueError, base.replace, second=100) self.assertRaises(ValueError, base.replace, microsecond=1000000) + def test_subclass_time(self): + + class C(self.theclass): + theAnswer = 42 + + def __new__(cls, *args, **kws): + temp = kws.copy() + extra = temp.pop('extra') + result = self.theclass.__new__(cls, *args, **temp) + result.extra = extra + return result + + def newmeth(self, start): + return start + self.hour + self.second + + args = 4, 5, 6 + + dt1 = self.theclass(*args) + dt2 = C(*args, **{'extra': 7}) + + self.assertEqual(dt2.__class__, C) + self.assertEqual(dt2.theAnswer, 42) + self.assertEqual(dt2.extra, 7) + self.assertEqual(dt1.isoformat(), dt2.isoformat()) + self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.second - 7) + + def test_backdoor_resistance(self): + # see TestDate.test_backdoor_resistance(). + base = '2:59.0' + for hour_byte in ' ', '9', chr(24), '\xff': + self.assertRaises(TypeError, self.theclass, + hour_byte + base[1:]) + # A mixin for classes with a tzinfo= argument. Subclasses must define # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) # must be legit (which is true for time and datetime). -class TZInfoBase(unittest.TestCase): +class TZInfoBase: def test_argument_passing(self): cls = self.theclass @@ -1664,7 +2019,7 @@ def utcoffset(self, dt): pass b = BetterTry() t = cls(1, 1, 1, tzinfo=b) - self.failUnless(t.tzinfo is b) + self.assertTrue(t.tzinfo is b) def test_utc_offset_out_of_bounds(self): class Edgy(tzinfo): @@ -1703,9 +2058,9 @@ for t in (cls(1, 1, 1), cls(1, 1, 1, tzinfo=None), cls(1, 1, 1, tzinfo=C1())): - self.failUnless(t.utcoffset() is None) - self.failUnless(t.dst() is None) - self.failUnless(t.tzname() is None) + self.assertTrue(t.utcoffset() is None) + self.assertTrue(t.dst() is None) + self.assertTrue(t.tzname() is None) class C3(tzinfo): def utcoffset(self, dt): return timedelta(minutes=-1439) @@ -1790,7 +2145,7 @@ # Testing time objects with a non-None tzinfo. -class TestTimeTZ(TestTime, TZInfoBase): +class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase): theclass = time def test_empty(self): @@ -1799,7 +2154,7 @@ self.assertEqual(t.minute, 0) self.assertEqual(t.second, 0) self.assertEqual(t.microsecond, 0) - self.failUnless(t.tzinfo is None) + self.assertTrue(t.tzinfo is None) def test_zones(self): est = FixedOffset(-300, "EST", 1) @@ -1814,25 +2169,25 @@ self.assertEqual(t1.tzinfo, est) self.assertEqual(t2.tzinfo, utc) self.assertEqual(t3.tzinfo, met) - self.failUnless(t4.tzinfo is None) + self.assertTrue(t4.tzinfo is None) self.assertEqual(t5.tzinfo, utc) self.assertEqual(t1.utcoffset(), timedelta(minutes=-300)) self.assertEqual(t2.utcoffset(), timedelta(minutes=0)) self.assertEqual(t3.utcoffset(), timedelta(minutes=60)) - self.failUnless(t4.utcoffset() is None) + self.assertTrue(t4.utcoffset() is None) self.assertRaises(TypeError, t1.utcoffset, "no args") self.assertEqual(t1.tzname(), "EST") self.assertEqual(t2.tzname(), "UTC") self.assertEqual(t3.tzname(), "MET") - self.failUnless(t4.tzname() is None) + self.assertTrue(t4.tzname() is None) self.assertRaises(TypeError, t1.tzname, "no args") self.assertEqual(t1.dst(), timedelta(minutes=1)) self.assertEqual(t2.dst(), timedelta(minutes=-2)) self.assertEqual(t3.dst(), timedelta(minutes=3)) - self.failUnless(t4.dst() is None) + self.assertTrue(t4.dst() is None) self.assertRaises(TypeError, t1.dst, "no args") self.assertEqual(hash(t1), hash(t2)) @@ -1908,7 +2263,7 @@ green = pickler.dumps(orig, proto) derived = unpickler.loads(green) self.assertEqual(orig, derived) - self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) + self.assertIsInstance(derived.tzinfo, PicklableFixedOffset) self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) self.assertEqual(derived.tzname(), 'cookie') @@ -1917,20 +2272,20 @@ cls = self.theclass t = cls(0, tzinfo=FixedOffset(-300, "")) - self.failUnless(t) + self.assertTrue(t) t = cls(5, tzinfo=FixedOffset(-300, "")) - self.failUnless(t) + self.assertTrue(t) t = cls(5, tzinfo=FixedOffset(300, "")) - self.failUnless(not t) + self.assertTrue(not t) t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, "")) - self.failUnless(not t) + self.assertTrue(not t) # Mostly ensuring this doesn't overflow internally. t = cls(0, tzinfo=FixedOffset(23*60 + 59, "")) - self.failUnless(t) + self.assertTrue(t) # But this should yield a value error -- the utcoffset is bogus. t = cls(0, tzinfo=FixedOffset(24*60, "")) @@ -1964,13 +2319,13 @@ # Ensure we can get rid of a tzinfo. self.assertEqual(base.tzname(), "+100") base2 = base.replace(tzinfo=None) - self.failUnless(base2.tzinfo is None) - self.failUnless(base2.tzname() is None) + self.assertTrue(base2.tzinfo is None) + self.assertTrue(base2.tzname() is None) # Ensure we can add one. base3 = base2.replace(tzinfo=z100) self.assertEqual(base, base3) - self.failUnless(base.tzinfo is base3.tzinfo) + self.assertTrue(base.tzinfo is base3.tzinfo) # Out of bounds. base = cls(1) @@ -2007,12 +2362,38 @@ # But if they're not identical, it isn't ignored. t2 = t2.replace(tzinfo=Varies()) - self.failUnless(t1 < t2) # t1's offset counter still going up + self.assertTrue(t1 < t2) # t1's offset counter still going up + + def test_subclass_timetz(self): + + class C(self.theclass): + theAnswer = 42 + + def __new__(cls, *args, **kws): + temp = kws.copy() + extra = temp.pop('extra') + result = self.theclass.__new__(cls, *args, **temp) + result.extra = extra + return result + + def newmeth(self, start): + return start + self.hour + self.second + + args = 4, 5, 6, 500, FixedOffset(-300, "EST", 1) + + dt1 = self.theclass(*args) + dt2 = C(*args, **{'extra': 7}) + + self.assertEqual(dt2.__class__, C) + self.assertEqual(dt2.theAnswer, 42) + self.assertEqual(dt2.extra, 7) + self.assertEqual(dt1.utcoffset(), dt2.utcoffset()) + self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.second - 7) # Testing datetime objects with a non-None tzinfo. -class TestDateTimeTZ(TestDateTime, TZInfoBase): +class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase): theclass = datetime def test_trivial(self): @@ -2037,12 +2418,12 @@ tzinfo=FixedOffset(-1439, "")) # Make sure those compare correctly, and w/o overflow. - self.failUnless(t1 < t2) - self.failUnless(t1 != t2) - self.failUnless(t2 > t1) + self.assertTrue(t1 < t2) + self.assertTrue(t1 != t2) + self.assertTrue(t2 > t1) - self.failUnless(t1 == t1) - self.failUnless(t2 == t2) + self.assertTrue(t1 == t1) + self.assertTrue(t2 == t2) # Equal afer adjustment. t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, "")) @@ -2051,21 +2432,21 @@ # Change t1 not to subtract a minute, and t1 should be larger. t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(0, "")) - self.failUnless(t1 > t2) + self.assertTrue(t1 > t2) # Change t1 to subtract 2 minutes, and t1 should be smaller. t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(2, "")) - self.failUnless(t1 < t2) + self.assertTrue(t1 < t2) # Back to the original t1, but make seconds resolve it. t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""), second=1) - self.failUnless(t1 > t2) + self.assertTrue(t1 > t2) # Likewise, but make microseconds resolve it. t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, ""), microsecond=1) - self.failUnless(t1 > t2) + self.assertTrue(t1 > t2) # Make t2 naive and it should fail. t2 = self.theclass.min @@ -2109,8 +2490,7 @@ green = pickler.dumps(orig, proto) derived = unpickler.loads(green) self.assertEqual(orig, derived) - self.failUnless(isinstance(derived.tzinfo, - PicklableFixedOffset)) + self.assertIsInstance(derived.tzinfo, PicklableFixedOffset) self.assertEqual(derived.utcoffset(), timedelta(minutes=-300)) self.assertEqual(derived.tzname(), 'cookie') @@ -2180,7 +2560,7 @@ tz55 = FixedOffset(-330, "west 5:30") timeaware = now.time().replace(tzinfo=tz55) nowaware = self.theclass.combine(now.date(), timeaware) - self.failUnless(nowaware.tzinfo is tz55) + self.assertTrue(nowaware.tzinfo is tz55) self.assertEqual(nowaware.timetz(), timeaware) # Can't mix aware and non-aware. @@ -2199,15 +2579,15 @@ # Adding a delta should preserve tzinfo. delta = timedelta(weeks=1, minutes=12, microseconds=5678) nowawareplus = nowaware + delta - self.failUnless(nowaware.tzinfo is tz55) + self.assertTrue(nowaware.tzinfo is tz55) nowawareplus2 = delta + nowaware - self.failUnless(nowawareplus2.tzinfo is tz55) + self.assertTrue(nowawareplus2.tzinfo is tz55) self.assertEqual(nowawareplus, nowawareplus2) # that - delta should be what we started with, and that - what we # started with should be delta. diff = nowawareplus - delta - self.failUnless(diff.tzinfo is tz55) + self.assertTrue(diff.tzinfo is tz55) self.assertEqual(nowaware, diff) self.assertRaises(TypeError, lambda: delta - nowawareplus) self.assertEqual(nowawareplus - nowaware, delta) @@ -2216,7 +2596,7 @@ tzr = FixedOffset(random.randrange(-1439, 1440), "randomtimezone") # Attach it to nowawareplus. nowawareplus = nowawareplus.replace(tzinfo=tzr) - self.failUnless(nowawareplus.tzinfo is tzr) + self.assertTrue(nowawareplus.tzinfo is tzr) # Make sure the difference takes the timezone adjustments into account. got = nowaware - nowawareplus # Expected: (nowaware base - nowaware offset) - @@ -2243,7 +2623,7 @@ off42 = FixedOffset(42, "42") another = meth(off42) again = meth(tz=off42) - self.failUnless(another.tzinfo is again.tzinfo) + self.assertTrue(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) # Bad argument with and w/o naming the keyword. self.assertRaises(TypeError, meth, 16) @@ -2260,7 +2640,7 @@ utc = FixedOffset(0, "utc", 0) for dummy in range(3): now = datetime.now(weirdtz) - self.failUnless(now.tzinfo is weirdtz) + self.assertTrue(now.tzinfo is weirdtz) utcnow = datetime.utcnow().replace(tzinfo=utc) now2 = utcnow.astimezone(weirdtz) if abs(now - now2) < timedelta(seconds=30): @@ -2281,7 +2661,7 @@ off42 = FixedOffset(42, "42") another = meth(ts, off42) again = meth(ts, tz=off42) - self.failUnless(another.tzinfo is again.tzinfo) + self.assertTrue(another.tzinfo is again.tzinfo) self.assertEqual(another.utcoffset(), timedelta(minutes=42)) # Bad argument with and w/o naming the keyword. self.assertRaises(TypeError, meth, ts, 16) @@ -2475,13 +2855,13 @@ # Ensure we can get rid of a tzinfo. self.assertEqual(base.tzname(), "+100") base2 = base.replace(tzinfo=None) - self.failUnless(base2.tzinfo is None) - self.failUnless(base2.tzname() is None) + self.assertTrue(base2.tzinfo is None) + self.assertTrue(base2.tzname() is None) # Ensure we can add one. base3 = base2.replace(tzinfo=z100) self.assertEqual(base, base3) - self.failUnless(base.tzinfo is base3.tzinfo) + self.assertTrue(base.tzinfo is base3.tzinfo) # Out of bounds. base = cls(2000, 2, 29) @@ -2494,20 +2874,20 @@ fm5h = FixedOffset(-timedelta(hours=5), "m300") dt = self.theclass.now(tz=f44m) - self.failUnless(dt.tzinfo is f44m) + self.assertTrue(dt.tzinfo is f44m) # Replacing with degenerate tzinfo raises an exception. self.assertRaises(ValueError, dt.astimezone, fnone) # Ditto with None tz. self.assertRaises(TypeError, dt.astimezone, None) # Replacing with same tzinfo makes no change. x = dt.astimezone(dt.tzinfo) - self.failUnless(x.tzinfo is f44m) + self.assertTrue(x.tzinfo is f44m) self.assertEqual(x.date(), dt.date()) self.assertEqual(x.time(), dt.time()) # Replacing with different tzinfo does adjust. got = dt.astimezone(fm5h) - self.failUnless(got.tzinfo is fm5h) + self.assertTrue(got.tzinfo is fm5h) self.assertEqual(got.utcoffset(), timedelta(hours=-5)) expected = dt - dt.utcoffset() # in effect, convert to UTC expected += fm5h.utcoffset(dt) # and from there to local time @@ -2515,7 +2895,7 @@ self.assertEqual(got.date(), expected.date()) self.assertEqual(got.time(), expected.time()) self.assertEqual(got.timetz(), expected.timetz()) - self.failUnless(got.tzinfo is expected.tzinfo) + self.assertTrue(got.tzinfo is expected.tzinfo) self.assertEqual(got, expected) def test_aware_subtract(self): @@ -2590,7 +2970,33 @@ # But if they're not identical, it isn't ignored. t2 = t2.replace(tzinfo=Varies()) - self.failUnless(t1 < t2) # t1's offset counter still going up + self.assertTrue(t1 < t2) # t1's offset counter still going up + + def test_subclass_datetimetz(self): + + class C(self.theclass): + theAnswer = 42 + + def __new__(cls, *args, **kws): + temp = kws.copy() + extra = temp.pop('extra') + result = self.theclass.__new__(cls, *args, **temp) + result.extra = extra + return result + + def newmeth(self, start): + return start + self.hour + self.year + + args = 2002, 12, 31, 4, 5, 6, 500, FixedOffset(-300, "EST", 1) + + dt1 = self.theclass(*args) + dt2 = C(*args, **{'extra': 7}) + + self.assertEqual(dt2.__class__, C) + self.assertEqual(dt2.theAnswer, 42) + self.assertEqual(dt2.extra, 7) + self.assertEqual(dt1.utcoffset(), dt2.utcoffset()) + self.assertEqual(dt2.newmeth(-7), dt1.hour + dt1.year - 7) # Pain to set up DST-aware tzinfo classes. @@ -2904,45 +3310,51 @@ start += HOUR fstart += HOUR -def test_suite(): - allsuites = [unittest.makeSuite(klass, 'test') - for klass in (TestModule, - TestTZInfo, - TestTimeDelta, - TestDateOnly, - TestDate, - TestDateTime, - TestTime, - TestTimeTZ, - TestDateTimeTZ, - TestTimezoneConversions, - ) - ] - return unittest.TestSuite(allsuites) -def test_main(): - import gc - import sys +############################################################################# +# oddballs - r = unittest.TextTestRunner(stream=sys.stdout, verbosity=2) - s = test_suite() - lastrc = None - while True: - r.run(s) - if 1: # change to 0, under a debug build, for some leak detection - break - gc.collect() - if gc.garbage: - raise SystemError("gc.garbage not empty after test run: %r" % - gc.garbage) - if hasattr(sys, 'gettotalrefcount'): - thisrc = sys.gettotalrefcount() - print >> sys.stderr, '*' * 10, 'total refs:', thisrc, - if lastrc: - print >> sys.stderr, 'delta:', thisrc - lastrc - else: - print >> sys.stderr - lastrc = thisrc +class Oddballs(unittest.TestCase): + + def test_bug_1028306(self): + # Trying to compare a date to a datetime should act like a mixed- + # type comparison, despite that datetime is a subclass of date. + as_date = date.today() + as_datetime = datetime.combine(as_date, time()) + self.assertTrue(as_date != as_datetime) + self.assertTrue(as_datetime != as_date) + self.assertTrue(not as_date == as_datetime) + self.assertTrue(not as_datetime == as_date) + self.assertRaises(TypeError, lambda: as_date < as_datetime) + self.assertRaises(TypeError, lambda: as_datetime < as_date) + self.assertRaises(TypeError, lambda: as_date <= as_datetime) + self.assertRaises(TypeError, lambda: as_datetime <= as_date) + self.assertRaises(TypeError, lambda: as_date > as_datetime) + self.assertRaises(TypeError, lambda: as_datetime > as_date) + self.assertRaises(TypeError, lambda: as_date >= as_datetime) + self.assertRaises(TypeError, lambda: as_datetime >= as_date) + + # Neverthelss, comparison should work with the base-class (date) + # projection if use of a date method is forced. + self.assertTrue(as_date.__eq__(as_datetime)) + different_day = (as_date.day + 1) % 20 + 1 + self.assertTrue(not as_date.__eq__(as_datetime.replace(day= + different_day))) + + # And date should compare with other subclasses of date. If a + # subclass wants to stop this, it's up to the subclass to do so. + date_sc = SubclassDate(as_date.year, as_date.month, as_date.day) + self.assertEqual(as_date, date_sc) + self.assertEqual(date_sc, as_date) + + # Ditto for datetimes. + datetime_sc = SubclassDatetime(as_datetime.year, as_datetime.month, + as_date.day, 0, 0, 0) + self.assertEqual(as_datetime, datetime_sc) + self.assertEqual(datetime_sc, as_datetime) + +def test_main(): + test_support.run_unittest(__name__) if __name__ == "__main__": test_main() From python-checkins at python.org Fri Jun 18 15:49:33 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 18 Jun 2010 15:49:33 +0200 (CEST) Subject: [Python-checkins] r82067 - sandbox/branches/py27-datetime Message-ID: <20100618134933.4DEDFC31B@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 18 15:49:33 2010 New Revision: 82067 Log: Saving 2.7 version before doing 3.x port Added: sandbox/branches/py27-datetime/ - copied from r82066, /sandbox/branches/py3k-datetime/ From python-checkins at python.org Fri Jun 18 17:08:18 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 18 Jun 2010 17:08:18 +0200 (CEST) Subject: [Python-checkins] r82068 - in python/branches/py3k: Lib/urllib/request.py Misc/NEWS Message-ID: <20100618150818.873D2EE9CF@mail.python.org> Author: senthil.kumaran Date: Fri Jun 18 17:08:18 2010 New Revision: 82068 Log: Fix Issue1368368 - prompt_user_passwd() in FancyURLopener masks 401 Unauthorized error page Modified: python/branches/py3k/Lib/urllib/request.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/urllib/request.py ============================================================================== --- python/branches/py3k/Lib/urllib/request.py (original) +++ python/branches/py3k/Lib/urllib/request.py Fri Jun 18 17:08:18 2010 @@ -1866,7 +1866,8 @@ else: return self.http_error_default(url, fp, errcode, errmsg, headers) - def http_error_401(self, url, fp, errcode, errmsg, headers, data=None): + def http_error_401(self, url, fp, errcode, errmsg, headers, data=None, + retry=False): """Error 401 -- authentication required. This function supports Basic authentication only.""" if not 'www-authenticate' in headers: @@ -1882,13 +1883,17 @@ if scheme.lower() != 'basic': URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) + if not retry: + URLopener.http_error_default(self, url, fp, errcode, errmsg, + headers) name = 'retry_' + self.type + '_basic_auth' if data is None: return getattr(self,name)(url, realm) else: return getattr(self,name)(url, realm, data) - def http_error_407(self, url, fp, errcode, errmsg, headers, data=None): + def http_error_407(self, url, fp, errcode, errmsg, headers, data=None, + retry=False): """Error 407 -- proxy authentication required. This function supports Basic authentication only.""" if not 'proxy-authenticate' in headers: @@ -1904,6 +1909,9 @@ if scheme.lower() != 'basic': URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) + if not retry: + URLopener.http_error_default(self, url, fp, errcode, errmsg, + headers) name = 'retry_proxy_' + self.type + '_basic_auth' if data is None: return getattr(self,name)(url, realm) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Jun 18 17:08:18 2010 @@ -446,6 +446,10 @@ Library ------- +- Issue #1368368: FancyURLOpener class changed to throw an Exception on wrong + password instead of presenting an interactive prompt. Older behavior can be + obtained by passing retry=True to http_error_xxx methods of FancyURLOpener. + - Issue #8720: fix regression caused by fix for #4050 by making getsourcefile smart enough to find source files in the linecache. From python-checkins at python.org Fri Jun 18 17:12:48 2010 From: python-checkins at python.org (senthil.kumaran) Date: Fri, 18 Jun 2010 17:12:48 +0200 (CEST) Subject: [Python-checkins] r82069 - in python/branches/release31-maint: Lib/urllib/request.py Misc/NEWS Message-ID: <20100618151248.A6AA5EE99B@mail.python.org> Author: senthil.kumaran Date: Fri Jun 18 17:12:48 2010 New Revision: 82069 Log: Merged revisions 82068 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r82068 | senthil.kumaran | 2010-06-18 20:38:18 +0530 (Fri, 18 Jun 2010) | 3 lines Fix Issue1368368 - prompt_user_passwd() in FancyURLopener masks 401 Unauthorized error page ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/urllib/request.py python/branches/release31-maint/Misc/NEWS 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 Fri Jun 18 17:12:48 2010 @@ -1870,7 +1870,8 @@ else: return self.http_error_default(url, fp, errcode, errmsg, headers) - def http_error_401(self, url, fp, errcode, errmsg, headers, data=None): + def http_error_401(self, url, fp, errcode, errmsg, headers, data=None, + retry=False): """Error 401 -- authentication required. This function supports Basic authentication only.""" if not 'www-authenticate' in headers: @@ -1886,13 +1887,17 @@ if scheme.lower() != 'basic': URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) + if not retry: + URLopener.http_error_default(self, url, fp, errcode, errmsg, + headers) name = 'retry_' + self.type + '_basic_auth' if data is None: return getattr(self,name)(url, realm) else: return getattr(self,name)(url, realm, data) - def http_error_407(self, url, fp, errcode, errmsg, headers, data=None): + def http_error_407(self, url, fp, errcode, errmsg, headers, data=None, + retry=False): """Error 407 -- proxy authentication required. This function supports Basic authentication only.""" if not 'proxy-authenticate' in headers: @@ -1908,6 +1913,9 @@ if scheme.lower() != 'basic': URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) + if not retry: + URLopener.http_error_default(self, url, fp, errcode, errmsg, + headers) name = 'retry_proxy_' + self.type + '_basic_auth' if data is None: return getattr(self,name)(url, realm) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Jun 18 17:12:48 2010 @@ -70,6 +70,10 @@ Library ------- +- Issue #1368368: FancyURLOpener class changed to throw an Exception on wrong + password instead of presenting an interactive prompt. Older behavior can be + obtained by passing retry=True to http_error_xxx methods of FancyURLOpener. + - Issue #8203: Fix IDLE Credits dialog: view_file() uses its encoding argument. - Issue #8720: fix regression caused by fix for #4050 by making getsourcefile From python-checkins at python.org Fri Jun 18 18:22:01 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 18 Jun 2010 18:22:01 +0200 (CEST) Subject: [Python-checkins] r82070 - python/branches/py3k/Modules/_time.c Message-ID: <20100618162201.10A06EE9D0@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 18 18:22:00 2010 New Revision: 82070 Log: Fixed a typo in a comment. Modified: python/branches/py3k/Modules/_time.c Modified: python/branches/py3k/Modules/_time.c ============================================================================== --- python/branches/py3k/Modules/_time.c (original) +++ python/branches/py3k/Modules/_time.c Fri Jun 18 18:22:00 2010 @@ -16,7 +16,7 @@ * unreasonable, or the input just doesn't fit in a time_t; * call it an error regardless. Note that the original cast to * time_t can cause a C error too, but nothing we can do to - * worm around that. + * work around that. */ diff = x - (double)result; if (diff <= -1.0 || diff >= 1.0) { From python-checkins at python.org Fri Jun 18 18:57:49 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 18 Jun 2010 18:57:49 +0200 (CEST) Subject: [Python-checkins] r82071 - python/branches/py3k/Doc/library/datetime.rst Message-ID: <20100618165749.9AA9FEE9AC@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 18 18:57:49 2010 New Revision: 82071 Log: Added a new line at the end of the file. Modified: python/branches/py3k/Doc/library/datetime.rst Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Fri Jun 18 18:57:49 2010 @@ -1766,4 +1766,4 @@ When the ``%z`` directive is provided to the :meth:`strptime` method, an aware :class:`datetime` object will be produced. The ``tzinfo`` of the result will be set to a :class:`timezone` - instance. \ No newline at end of file + instance. From python-checkins at python.org Fri Jun 18 18:59:25 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 18 Jun 2010 18:59:25 +0200 (CEST) Subject: [Python-checkins] r82072 - python/branches/release31-maint Message-ID: <20100618165925.F1111EE9C8@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 18 18:59:25 2010 New Revision: 82072 Log: Blocked revisions 82071 via svnmerge ........ r82071 | alexander.belopolsky | 2010-06-18 12:57:49 -0400 (Fri, 18 Jun 2010) | 1 line Added a new line at the end of the file. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Jun 18 20:44:37 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 18 Jun 2010 20:44:37 +0200 (CEST) Subject: [Python-checkins] r82073 - in python/branches/py3k: Lib/_strptime.py Lib/test/test_datetime.py Modules/datetimemodule.c Message-ID: <20100618184437.8F3C9F4E6@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 18 20:44:37 2010 New Revision: 82073 Log: Issue #6641: Original commit for this issue, r82053, introduced a regression making datetime subclass' strptime return datetime rather than subclass instances. Fixed this bug and a few typos. Modified: python/branches/py3k/Lib/_strptime.py python/branches/py3k/Lib/test/test_datetime.py python/branches/py3k/Modules/datetimemodule.c Modified: python/branches/py3k/Lib/_strptime.py ============================================================================== --- python/branches/py3k/Lib/_strptime.py (original) +++ python/branches/py3k/Lib/_strptime.py Fri Jun 18 20:44:37 2010 @@ -17,7 +17,6 @@ from re import IGNORECASE, ASCII from re import escape as re_escape from datetime import (date as datetime_date, - datetime as datetime_datetime, timedelta as datetime_timedelta, timezone as datetime_timezone) try: @@ -297,7 +296,7 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): - """Return a 2-tuple consisting of a time struct and an int containg + """Return a 2-tuple consisting of a time struct and an int containing the number of microseconds based on the input string and the format string.""" @@ -483,8 +482,8 @@ tt = _strptime(data_string, format)[0] return time.struct_time(tt[:9]) -def _strptime_datetime(data_string, format="%a %b %d %H:%M:%S %Y"): - """Return a datetime instace based on the input string and the +def _strptime_datetime(class_, data_string, format="%a %b %d %H:%M:%S %Y"): + """Return a class_ instance based on the input string and the format string.""" tt, fraction = _strptime(data_string, format) gmtoff, tzname = tt[-2:] @@ -497,4 +496,4 @@ tz = datetime_timezone(tzdelta) args += (tz,) - return datetime_datetime(*args) + return class_(*args) 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 Fri Jun 18 20:44:37 2010 @@ -1100,8 +1100,13 @@ self.assertEqual(b.__format__(fmt), 'B') def test_resolution_info(self): - self.assertIsInstance(self.theclass.min, self.theclass) - self.assertIsInstance(self.theclass.max, self.theclass) + # XXX: Should min and max respect subclassing? + if issubclass(self.theclass, datetime): + expected_class = datetime + else: + expected_class = date + self.assertIsInstance(self.theclass.min, expected_class) + self.assertIsInstance(self.theclass.max, expected_class) self.assertIsInstance(self.theclass.resolution, timedelta) self.assertTrue(self.theclass.max > self.theclass.min) @@ -1732,9 +1737,11 @@ string = '2004-12-01 13:02:47.197' format = '%Y-%m-%d %H:%M:%S.%f' - expected = _strptime._strptime_datetime(string, format) + expected = _strptime._strptime_datetime(self.theclass, string, format) got = self.theclass.strptime(string, format) self.assertEqual(expected, got) + self.assertIs(type(expected), self.theclass) + self.assertIs(type(got), self.theclass) strptime = self.theclass.strptime self.assertEqual(strptime("+0002", "%z").utcoffset(), 2 * MINUTE) @@ -1896,6 +1903,12 @@ self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month + dt1.second - 7) +class TestSubclassDateTime(TestDateTime): + theclass = SubclassDatetime + # Override tests not designed for subclass + def test_roundtrip(self): + pass + class SubclassTime(time): sub_var = 1 Modified: python/branches/py3k/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k/Modules/datetimemodule.c (original) +++ python/branches/py3k/Modules/datetimemodule.c Fri Jun 18 20:44:37 2010 @@ -4377,8 +4377,8 @@ if(module == NULL) return NULL; } - return PyObject_CallMethod(module, "_strptime_datetime", "uu", - string, format); + return PyObject_CallMethod(module, "_strptime_datetime", "Ouu", + cls, string, format); } /* Return new datetime from date/datetime and time arguments. */ From python-checkins at python.org Fri Jun 18 20:45:58 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 18 Jun 2010 20:45:58 +0200 (CEST) Subject: [Python-checkins] r82074 - python/branches/release31-maint Message-ID: <20100618184558.6D6F5F4E6@mail.python.org> Author: alexander.belopolsky Date: Fri Jun 18 20:45:58 2010 New Revision: 82074 Log: Blocked revisions 82073 via svnmerge ........ r82073 | alexander.belopolsky | 2010-06-18 14:44:37 -0400 (Fri, 18 Jun 2010) | 4 lines Issue #6641: Original commit for this issue, r82053, introduced a regression making datetime subclass' strptime return datetime rather than subclass instances. Fixed this bug and a few typos. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Jun 18 22:00:17 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Fri, 18 Jun 2010 22:00:17 +0200 (CEST) Subject: [Python-checkins] r82075 - in python/trunk/Lib: subprocess.py test/test_subprocess.py Message-ID: <20100618200017.34970EE988@mail.python.org> Author: jean-paul.calderone Date: Fri Jun 18 22:00:17 2010 New Revision: 82075 Log: Revert r60115 This revision introduced quoting for strings containing | based on a misunderstanding of the commonly used quoting rules used on Windows. | is interpreted by cmd.exe, not by the MS C runtime argv initializer. It only needs to be quoted if it is part of an argument passed through cmd.exe. See issue1300, issue7839, and issue8972. Modified: python/trunk/Lib/subprocess.py python/trunk/Lib/test/test_subprocess.py Modified: python/trunk/Lib/subprocess.py ============================================================================== --- python/trunk/Lib/subprocess.py (original) +++ python/trunk/Lib/subprocess.py Fri Jun 18 22:00:17 2010 @@ -548,8 +548,8 @@ 2) A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space - or pipe characters contained within. A quoted string can be - embedded in an argument. + contained within. A quoted string can be embedded in an + argument. 3) A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark. @@ -577,7 +577,7 @@ if result: result.append(' ') - needquote = (" " in arg) or ("\t" in arg) or ("|" in arg) or not arg + needquote = (" " in arg) or ("\t" in arg) or not arg if needquote: result.append('"') Modified: python/trunk/Lib/test/test_subprocess.py ============================================================================== --- python/trunk/Lib/test/test_subprocess.py (original) +++ python/trunk/Lib/test/test_subprocess.py Fri Jun 18 22:00:17 2010 @@ -486,8 +486,6 @@ '"a\\\\b\\ c" d e') self.assertEqual(subprocess.list2cmdline(['ab', '']), 'ab ""') - self.assertEqual(subprocess.list2cmdline(['echo', 'foo|bar']), - 'echo "foo|bar"') def test_poll(self): From python-checkins at python.org Fri Jun 18 22:03:54 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Fri, 18 Jun 2010 22:03:54 +0200 (CEST) Subject: [Python-checkins] r82076 - in python/branches/py3k: Lib/subprocess.py Lib/test/test_subprocess.py Message-ID: <20100618200354.CBD07EE988@mail.python.org> Author: jean-paul.calderone Date: Fri Jun 18 22:03:54 2010 New Revision: 82076 Log: Merged revisions 82075 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82075 | jean-paul.calderone | 2010-06-18 16:00:17 -0400 (Fri, 18 Jun 2010) | 12 lines Revert r60115 This revision introduced quoting for strings containing | based on a misunderstanding of the commonly used quoting rules used on Windows. | is interpreted by cmd.exe, not by the MS C runtime argv initializer. It only needs to be quoted if it is part of an argument passed through cmd.exe. See issue1300, issue7839, and issue8972. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/subprocess.py python/branches/py3k/Lib/test/test_subprocess.py Modified: python/branches/py3k/Lib/subprocess.py ============================================================================== --- python/branches/py3k/Lib/subprocess.py (original) +++ python/branches/py3k/Lib/subprocess.py Fri Jun 18 22:03:54 2010 @@ -500,8 +500,8 @@ 2) A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space - or pipe characters contained within. A quoted string can be - embedded in an argument. + contained within. A quoted string can be embedded in an + argument. 3) A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark. @@ -529,7 +529,7 @@ if result: result.append(' ') - needquote = (" " in arg) or ("\t" in arg) or ("|" in arg) or not arg + needquote = (" " in arg) or ("\t" in arg) or not arg if needquote: result.append('"') Modified: python/branches/py3k/Lib/test/test_subprocess.py ============================================================================== --- python/branches/py3k/Lib/test/test_subprocess.py (original) +++ python/branches/py3k/Lib/test/test_subprocess.py Fri Jun 18 22:03:54 2010 @@ -478,8 +478,6 @@ '"a\\\\b\\ c" d e') self.assertEqual(subprocess.list2cmdline(['ab', '']), 'ab ""') - self.assertEqual(subprocess.list2cmdline(['echo', 'foo|bar']), - 'echo "foo|bar"') def test_poll(self): From python-checkins at python.org Fri Jun 18 22:10:12 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Fri, 18 Jun 2010 22:10:12 +0200 (CEST) Subject: [Python-checkins] r82077 - in python/branches/release26-maint: Lib/subprocess.py Lib/test/test_subprocess.py Message-ID: <20100618201012.B125CEE9AD@mail.python.org> Author: jean-paul.calderone Date: Fri Jun 18 22:10:12 2010 New Revision: 82077 Log: Merged revisions 82075 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82075 | jean-paul.calderone | 2010-06-18 16:00:17 -0400 (Fri, 18 Jun 2010) | 12 lines Revert r60115 This revision introduced quoting for strings containing | based on a misunderstanding of the commonly used quoting rules used on Windows. | is interpreted by cmd.exe, not by the MS C runtime argv initializer. It only needs to be quoted if it is part of an argument passed through cmd.exe. See issue1300, issue7839, and issue8972. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/subprocess.py python/branches/release26-maint/Lib/test/test_subprocess.py Modified: python/branches/release26-maint/Lib/subprocess.py ============================================================================== --- python/branches/release26-maint/Lib/subprocess.py (original) +++ python/branches/release26-maint/Lib/subprocess.py Fri Jun 18 22:10:12 2010 @@ -499,8 +499,8 @@ 2) A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space - or pipe characters contained within. A quoted string can be - embedded in an argument. + contained within. A quoted string can be embedded in an + argument. 3) A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark. @@ -528,7 +528,7 @@ if result: result.append(' ') - needquote = (" " in arg) or ("\t" in arg) or ("|" in arg) or not arg + needquote = (" " in arg) or ("\t" in arg) or not arg if needquote: result.append('"') Modified: python/branches/release26-maint/Lib/test/test_subprocess.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_subprocess.py (original) +++ python/branches/release26-maint/Lib/test/test_subprocess.py Fri Jun 18 22:10:12 2010 @@ -449,8 +449,6 @@ '"a\\\\b\\ c" d e') self.assertEqual(subprocess.list2cmdline(['ab', '']), 'ab ""') - self.assertEqual(subprocess.list2cmdline(['echo', 'foo|bar']), - 'echo "foo|bar"') def test_poll(self): From python-checkins at python.org Fri Jun 18 22:11:43 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Fri, 18 Jun 2010 22:11:43 +0200 (CEST) Subject: [Python-checkins] r82078 - in python/branches/release31-maint: Lib/subprocess.py Lib/test/test_subprocess.py Message-ID: <20100618201143.6E69DEE9CA@mail.python.org> Author: jean-paul.calderone Date: Fri Jun 18 22:11:43 2010 New Revision: 82078 Log: Merged revisions 82076 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r82076 | jean-paul.calderone | 2010-06-18 16:03:54 -0400 (Fri, 18 Jun 2010) | 19 lines Merged revisions 82075 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82075 | jean-paul.calderone | 2010-06-18 16:00:17 -0400 (Fri, 18 Jun 2010) | 12 lines Revert r60115 This revision introduced quoting for strings containing | based on a misunderstanding of the commonly used quoting rules used on Windows. | is interpreted by cmd.exe, not by the MS C runtime argv initializer. It only needs to be quoted if it is part of an argument passed through cmd.exe. See issue1300, issue7839, and issue8972. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/subprocess.py python/branches/release31-maint/Lib/test/test_subprocess.py Modified: python/branches/release31-maint/Lib/subprocess.py ============================================================================== --- python/branches/release31-maint/Lib/subprocess.py (original) +++ python/branches/release31-maint/Lib/subprocess.py Fri Jun 18 22:11:43 2010 @@ -479,8 +479,8 @@ 2) A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space - or pipe characters contained within. A quoted string can be - embedded in an argument. + contained within. A quoted string can be embedded in an + argument. 3) A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark. @@ -508,7 +508,7 @@ if result: result.append(' ') - needquote = (" " in arg) or ("\t" in arg) or ("|" in arg) or not arg + needquote = (" " in arg) or ("\t" in arg) or not arg if needquote: result.append('"') Modified: python/branches/release31-maint/Lib/test/test_subprocess.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_subprocess.py (original) +++ python/branches/release31-maint/Lib/test/test_subprocess.py Fri Jun 18 22:11:43 2010 @@ -477,8 +477,6 @@ '"a\\\\b\\ c" d e') self.assertEqual(subprocess.list2cmdline(['ab', '']), 'ab ""') - self.assertEqual(subprocess.list2cmdline(['echo', 'foo|bar']), - 'echo "foo|bar"') def test_poll(self): From python-checkins at python.org Fri Jun 18 23:16:20 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 18 Jun 2010 23:16:20 +0200 (CEST) Subject: [Python-checkins] r82079 - python/branches/py3k-dtoa/Python/dtoa.c Message-ID: <20100618211620.912ACE95B@mail.python.org> Author: mark.dickinson Date: Fri Jun 18 23:16:20 2010 New Revision: 82079 Log: Pull out strtod parsing code into a separate function 'parse_numeric_string' Modified: python/branches/py3k-dtoa/Python/dtoa.c Modified: python/branches/py3k-dtoa/Python/dtoa.c ============================================================================== --- python/branches/py3k-dtoa/Python/dtoa.c (original) +++ python/branches/py3k-dtoa/Python/dtoa.c Fri Jun 18 23:16:20 2010 @@ -242,6 +242,8 @@ #define Frac_mask 0xfffff #define Frac_mask1 0xfffff #define Ten_pmax 22 +#define Big_10_exp 309 /* Values >= 10**Big_10_exp overflow. */ +#define Tiny_10_exp -324 /* Values < 10**Tiny_10_exp underflow to zero. */ #define Bletch 0x10 #define Bndry_mask 0xfffff #define Bndry_mask1 0xfffff @@ -270,7 +272,8 @@ typedef struct BCinfo BCinfo; struct BCinfo { - int e0, nd, nd0, scale; + Py_ssize_t nd, nd0; + int e0, scale; }; #define FFFFFFFF 0xffffffffUL @@ -479,13 +482,13 @@ failure. Assumes that nd >= 1 and that the first digit is nonzero. */ static Bigint * -s2b(const char *s0, int nd0, int nd) +s2b(const char *s0, Py_ssize_t nd0, Py_ssize_t nd) { Bigint *b; - int i, k; - Long x, y; + int k; + Py_ssize_t i, x, y; - x = (nd + 8) / 9; + x = 1 + (nd - 1) / 9; for (k = 0, y = 1; x > y; y <<= 1, k++) ; b = Balloc(k); if (b == NULL) @@ -1318,6 +1321,212 @@ } } +/* parse_numeric_string: Parse and validate a finite numeric string. + + Inputs: + + A NUL-terminated string s00 with an initial portion that represents a + finite decimal value. Valid numeric strings are described by the + following pseudo-grammar: + + sign = '+' | '-' + digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' + point = '.' + indicator = 'e' | 'E' + digits = digit [digits] + significand = digits [point [digits]] | point digits + exponent = indicator [sign] digits + numeric-string = [sign] significand [exponent] + + NaNs, infinities and hex literals are not accepted, and leading + whitespace is not permitted. + + Outputs: + + Any nonzero finite decimal value as above can be uniquely expressed in + the form + + (-1)**sign * 0. * 10**exp + + where sign is 0 or 1, exp is an integer, and is a string of one + ore more digits with both the first and last digit in the string nonzero. + The following return values from parse_numeric_string provide access to + these values: + + *sign gives the sign of the input: 1 for negative, 0 for positive. + + *pnd is the length of + + *ps0 is a pointer into the input string s00, and *pnd0 is an integer; + their values are such that for each i in the range 0 <= i < *pnd, the + ith digit [i] can be retrieved as: + + (*ps0)[i < *pnd0 ? i : i + 1] + + [ In the current implementation, *ps0 points just past the last + leading zero in the input string, so will either point to a nonzero + digit or to the decimal point. *pnd0 gives the position of the + decimal point, or of the end of the digit string if no decimal point + is present, relative to ps0. Note that *pnd0 may be larger than *pnd, + or smaller than 0. ] + + *exp is the exponent in the formula above, clipped to lie in the range + [INT_MIN, INT_MAX]. + + For an input representing zero, *pnd will be 0. + + *se points at the first character past the largest initial sequence + of s00 that gives a valid numeric string. If the entire string + s00 is a valid numeric string, *se will point to its terminating NUL + character. If no initial portion of s00 gives a valid numeric + string then *se will be equal to s00. + + Returns 0 for a successful parse, and a nonzero value on failure. +*/ + +static int +parse_numeric_string(const char *s00, char **se, char **ps0, + Py_ssize_t *pnd, Py_ssize_t *pnd0, + int *exp, int *sign) +{ + char c; + const char *s, *s0, *s1; + int esign, rv; + unsigned int dig; + Py_ssize_t e, nd, nd0, nz; + size_t abs_exp; + + s = s00; + c = *s; + + /* Parse optional sign, if present. */ + *sign = 0; + switch (c) { + case '-': + *sign = 1; + /* no break */ + case '+': + c = *++s; + } + + /* Skip (and count) leading zeros. */ + s0 = s; + while (c == '0') + c = *++s; + nz = s - s0; + + /* Parse any remaining digits before the point. */ + while ('0' <= c && c <= '9') + c = *++s; + nd0 = nd = s - s0; + + /* Parse decimal point and following digits. */ + if (c == '.') { + c = *++s; + s1 = s; + /* If all digits so far are zeros, continue to count leading zeros. */ + if (nd == nz) { + while (c == '0') + c = *++s; + nz += s - s1; + } + while ('0' <= c && c <= '9') + c = *++s; + nd += s - s1; + } + + if (!nd) { + /* No digits in the significand, so we've got an invalid numeric + string and a parse failure. */ + rv = 1; + *exp = 0; /* Silence a gcc 'may be used uninitialized' warning. */ + goto exit; + } + + /* We've got at least one digit, so the string up to this point is a + valid numeric string and the parse is successful. */ + rv = 0; + s00 = s; + + /* Adjust s0, nd, nd0 for leading zeros. */ + s0 += nz; + nd -= nz; + nd0 -= nz; + + /* The ith digit of the significand can now be retrieved as s0[i < nd0 ? i + : i + 1]. Discard any trailing zeros. */ + while (nd > 0 && s0[nd - 1 < nd0 ? nd - 1 : nd] == '0') + nd--; + + /* Parse exponent. */ + esign = 0; + abs_exp = 0U; + if (c == 'e' || c == 'E') { + c = *++s; + + /* Exponent sign. */ + esign = 0; + switch (c) { + case '-': + esign = 1; + /* no break */ + case '+': + c = *++s; + } + + /* Get absolute value abs_exp for the exponent; cap at SIZE_T_MAX. */ + s1 = s; + while ('0' <= c && c <= '9') { + dig = (unsigned int)(c - '0'); + /* Safe version of: if (10U * abs_exp + dig > SIZE_T_MAX) {...} */ + if (abs_exp >= SIZE_T_MAX / 10U && (abs_exp > SIZE_T_MAX / 10U || + dig > SIZE_T_MAX % 10U)) { + abs_exp = SIZE_T_MAX; + break; + } + abs_exp = 10U * abs_exp + dig; + c = *++s; + } + /* A valid exponent must have at least one digit. */ + if (s != s1) + s00 = s; + } + + /* Find e = nd0 + (-1)**esign * abs_exp, avoiding underflow/overflow and + clipping the result to the range [PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]. + Note that if the 'true' absolute exponent (i.e., without the SIZE_T_MAX + cap) is greater than SIZE_T_MAX then either e >= PY_SSIZE_T_MAX or e <= + PY_SSIZE_T_MIN, so we still end up doing the right thing here. */ + if (esign) { + if (nd0 - (size_t)PY_SSIZE_T_MIN < abs_exp) + e = PY_SSIZE_T_MIN; + else + e = nd0 - abs_exp; + } + else { + if ((size_t)PY_SSIZE_T_MAX - nd0 < abs_exp) + e = PY_SSIZE_T_MAX; + else + e = nd0 + abs_exp; + } + + /* Clip further to [INT_MIN, INT_MAX]. */ + if (e < INT_MIN) + *exp = INT_MIN; + else if (e > INT_MAX) + *exp = INT_MAX; + else + *exp = e; + + exit: + if (se) + *se = (char *)s00; + *pnd = nd; + *pnd0 = nd0; + *ps0 = (char *)s0; + return rv; +} + /* The bigcomp function handles some hard cases for strtod, for inputs with more than STRTOD_DIGLIM digits. It's called once an initial estimate for the double corresponding to the input string has @@ -1345,15 +1554,8 @@ bc is a struct containing information gathered during the parsing and estimation steps of _Py_dg_strtod. Description of fields follows: - bc->e0 gives the exponent of the input value, such that dv = (integer - given by the bd->nd digits of s0) * 10**e0 - - bc->nd gives the total number of significant digits of s0. It will - be at least 1. - - bc->nd0 gives the number of significant digits of s0 before the - decimal separator. If there's no decimal separator, bc->nd0 == - bc->nd. + bc->e0, bc->nd and bc->nd0 correspond to the values returned by + parse_numeric_string. bc->scale is the value used to scale rv to avoid doing arithmetic with subnormal values. It's either 0 or 2*P (=106). @@ -1368,7 +1570,8 @@ bigcomp(U *rv, const char *s0, BCinfo *bc) { Bigint *b, *d; - int b2, d2, dd, i, nd, nd0, odd, p2, p5; + int b2, d2, dd, i, odd, p2, p5; + Py_ssize_t nd, nd0; nd = bc->nd; nd0 = bc->nd0; @@ -1443,7 +1646,7 @@ /* b/d >= 1 */ dd = -1; else { - i = 0; + Py_ssize_t i = 0; for(;;) { b = multadd(b, 10, 0); if (b == NULL) { @@ -1477,165 +1680,31 @@ double _Py_dg_strtod(const char *s00, char **se) { - int bb2, bb5, bbe, bd2, bd5, bs2, c, dsign, e, e1, error; - int esign, i, j, k, lz, nd, nd0, odd, sign; - const char *s, *s0, *s1; + int bb2, bb5, bbe, bd2, bd5, bs2, dsign, e, e1, error, i, j, k, odd, sign; + Py_ssize_t nd, nd0, pos; + char *s0; double aadj, aadj1; U aadj2, adj, rv, rv0; - ULong y, z, abs_exp; + ULong y, z; Long L; BCinfo bc; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; dval(&rv) = 0.; - /* Start parsing. */ - c = *(s = s00); - - /* Parse optional sign, if present. */ - sign = 0; - switch (c) { - case '-': - sign = 1; - /* no break */ - case '+': - c = *++s; - } - - /* Skip leading zeros: lz is true iff there were leading zeros. */ - s1 = s; - while (c == '0') - c = *++s; - lz = s != s1; - - /* Point s0 at the first nonzero digit (if any). nd0 will be the position - of the point relative to s0. nd will be the total number of digits - ignoring leading zeros. */ - s0 = s1 = s; - while ('0' <= c && c <= '9') - c = *++s; - nd0 = nd = s - s1; - - /* Parse decimal point and following digits. */ - if (c == '.') { - c = *++s; - if (!nd) { - s1 = s; - while (c == '0') - c = *++s; - lz = lz || s != s1; - nd0 -= s - s1; - s0 = s; - } - s1 = s; - while ('0' <= c && c <= '9') - c = *++s; - nd += s - s1; - } - - /* Now lz is true if and only if there were leading zero digits, and nd - gives the total number of digits ignoring leading zeros. A valid input - must have at least one digit. */ - if (!nd && !lz) { - if (se) - *se = (char *)s00; + error = parse_numeric_string(s00, se, &s0, &nd, &nd0, &e, &sign); + if (error) goto parse_error; - } - - /* Parse exponent. */ - e = 0; - if (c == 'e' || c == 'E') { - s00 = s; - c = *++s; - /* Exponent sign. */ - esign = 0; - switch (c) { - case '-': - esign = 1; - /* no break */ - case '+': - c = *++s; - } - - /* Skip zeros. lz is true iff there are leading zeros. */ - s1 = s; - while (c == '0') - c = *++s; - lz = s != s1; - - /* Get absolute value of the exponent. */ - s1 = s; - abs_exp = 0; - while ('0' <= c && c <= '9') { - abs_exp = 10*abs_exp + (c - '0'); - c = *++s; - } - - /* abs_exp will be correct modulo 2**32. But 10**9 < 2**32, so if - there are at most 9 significant exponent digits then overflow is - impossible. */ - if (s - s1 > 9 || abs_exp > MAX_ABS_EXP) - e = (int)MAX_ABS_EXP; - else - e = (int)abs_exp; - if (esign) - e = -e; - - /* A valid exponent must have at least one digit. */ - if (s == s1 && !lz) - s = s00; - } - - /* Adjust exponent to take into account position of the point. */ - e += nd0; - if (nd0 <= 0) - nd0 = nd; - - /* Finished parsing. Set se to indicate how far we parsed */ - if (se) - *se = (char *)s; - - /* If all digits were zero, exit with return value +-0.0. Otherwise, - strip trailing zeros: scan back until we hit a nonzero digit. */ + /* If all digits were zero, exit with return value +-0.0. */ if (!nd) goto ret; - for (i = nd; i > 0; ) { - --i; - if (s0[i < nd0 ? i : i+1] != '0') { - ++i; - break; - } - } - nd = i; - if (nd0 > nd) - nd0 = nd; - /* Summary of parsing results. After parsing, and dealing with zero - * inputs, we have values s0, nd0, nd, e, sign, where: - * - * - s0 points to the first significant digit of the input string - * - * - nd is the total number of significant digits (here, and - * below, 'significant digits' means the set of digits of the - * significand of the input that remain after ignoring leading - * and trailing zeros). - * - * - nd0 indicates the position of the decimal point, if present; it - * satisfies 1 <= nd0 <= nd. The nd significant digits are in - * s0[0:nd0] and s0[nd0+1:nd+1] using the usual Python half-open slice - * notation. (If nd0 < nd, then s0[nd0] contains a '.' character; if - * nd0 == nd, then s0[nd0] could be any non-digit character.) - * - * - e is the adjusted exponent: the absolute value of the number - * represented by the original input string is n * 10**(e - nd), where - * n is the integer represented by the concatenation of - * s0[0:nd0] and s0[nd0+1:nd+1] - * - * - sign gives the sign of the input: 1 for negative, 0 for positive - * - * - the first and last significant digits are nonzero - */ + /* Overflow and underflow. */ + if (e > Big_10_exp) + goto ovfl; + else if (e <= Tiny_10_exp) + goto undfl; /* put first DBL_DIG+1 digits into integer y and z. * @@ -1649,11 +1718,11 @@ bc.e0 = e; y = z = 0; - for (i = 0; i < nd; i++) { - if (i < 9) - y = 10*y + s0[i < nd0 ? i : i+1] - '0'; - else if (i < DBL_DIG+1) - z = 10*z + s0[i < nd0 ? i : i+1] - '0'; + for (pos = 0; pos < nd; pos++) { + if (pos < 9) + y = 10*y + s0[pos < nd0 ? pos : pos+1] - '0'; + else if (pos < DBL_DIG+1) + z = 10*z + s0[pos < nd0 ? pos : pos+1] - '0'; else break; } @@ -1775,27 +1844,10 @@ /* in IEEE arithmetic. */ /* Truncate input to 18 significant digits, then discard any trailing - zeros on the result by updating nd, nd0, e and y suitably. (There's - no need to update z; it's not reused beyond this point.) */ - for (i = 18; i > 0; ) { - /* scan back until we hit a nonzero digit. significant digit 'i' - is s0[i] if i < nd0, s0[i+1] if i >= nd0. */ - --i; - if (s0[i < nd0 ? i : i+1] != '0') { - ++i; - break; - } - } - nd = i; - if (nd0 > nd) - nd0 = nd; - if (nd < 9) { /* must recompute y */ - y = 0; - for(i = 0; i < nd0; ++i) - y = 10*y + s0[i] - '0'; - for(; i < nd; ++i) - y = 10*y + s0[i+1] - '0'; - } + zeros on the result. */ + nd = 18; + while (nd > 0 && s0[nd - 1 < nd0 ? nd - 1 : nd] == '0') + nd--; } bd0 = s2b(s0, nd0, nd); if (bd0 == NULL) From python-checkins at python.org Fri Jun 18 23:21:25 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 18 Jun 2010 23:21:25 +0200 (CEST) Subject: [Python-checkins] r82080 - python/branches/py3k-dtoa/Python/dtoa.c Message-ID: <20100618212125.246DCEE9BE@mail.python.org> Author: mark.dickinson Date: Fri Jun 18 23:21:24 2010 New Revision: 82080 Log: Fix some whitespace issues. Modified: python/branches/py3k-dtoa/Python/dtoa.c Modified: python/branches/py3k-dtoa/Python/dtoa.c ============================================================================== --- python/branches/py3k-dtoa/Python/dtoa.c (original) +++ python/branches/py3k-dtoa/Python/dtoa.c Fri Jun 18 23:21:24 2010 @@ -1051,7 +1051,7 @@ b = Balloc(1); if (b == NULL) return NULL; - + /* First construct b and e assuming that scale == 0. */ b->wds = 2; b->x[0] = word1(d); @@ -1564,7 +1564,8 @@ On successful exit, rv/2^(bc->scale) is the closest double to dv. - Returns 0 on success, -1 on failure (e.g., due to a failed malloc call). */ + Returns 0 on success, -1 on failure (e.g., due to a failed malloc call). +*/ static int bigcomp(U *rv, const char *s0, BCinfo *bc) @@ -1923,20 +1924,20 @@ bd2++; /* At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1, - and bs == 1, so: + and bs == 1, so: tdv == bd * 10**e = bd * 2**(bbe - bb2 + bd2) * 5**(bd5 - bb5) srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2) - 0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2) + 0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2) - It follows that: + It follows that: M * tdv = bd * 2**bd2 * 5**bd5 M * srv = bb * 2**bb2 * 5**bb5 M * 0.5 ulp(srv) = bs * 2**bs2 * 5**bb5 - for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but - this fact is not needed below.) + for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but + this fact is not needed below.) */ /* Remove factor of 2**i, where i = min(bb2, bd2, bs2). */ From python-checkins at python.org Fri Jun 18 23:33:35 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 18 Jun 2010 23:33:35 +0200 (CEST) Subject: [Python-checkins] r82081 - python/branches/py3k-dtoa/Python/dtoa.c Message-ID: <20100618213335.752EDEE989@mail.python.org> Author: mark.dickinson Date: Fri Jun 18 23:33:35 2010 New Revision: 82081 Log: Simplify computation of initial approximation. Modified: python/branches/py3k-dtoa/Python/dtoa.c Modified: python/branches/py3k-dtoa/Python/dtoa.c ============================================================================== --- python/branches/py3k-dtoa/Python/dtoa.c (original) +++ python/branches/py3k-dtoa/Python/dtoa.c Fri Jun 18 23:33:35 2010 @@ -1707,37 +1707,16 @@ else if (e <= Tiny_10_exp) goto undfl; - /* put first DBL_DIG+1 digits into integer y and z. - * - * - y contains the value represented by the first min(9, nd) - * significant digits - * - * - if nd > 9, z contains the value represented by significant digits - * with indices in [9, min(16, nd)). So y * 10**(min(16, nd) - 9) + z - * gives the value represented by the first min(16, nd) sig. digits. - */ - - bc.e0 = e; - y = z = 0; - for (pos = 0; pos < nd; pos++) { - if (pos < 9) - y = 10*y + s0[pos < nd0 ? pos : pos+1] - '0'; - else if (pos < DBL_DIG+1) - z = 10*z + s0[pos < nd0 ? pos : pos+1] - '0'; - else - break; - } - + /* Initial approximation based on first DBL_DIG+1 digits of the input. */ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(&rv) = y; - if (k > 9) { - dval(&rv) = tens[k - 9] * dval(&rv) + z; - } - bd0 = 0; + for (pos = 0; pos < k; pos++) + dval(&rv) = 10.0 * dval(&rv) + (s0[pos < nd0 ? pos : pos + 1] - '0'); e1 = e - k; - if (nd <= DBL_DIG - && Flt_Rounds == 1 - ) { + + /* If there are at most Dbl_dig significant digits in the input, then rv + is exact and there's a chance to compute the exact result with a single + floating-point multiplication or division. */ + if (nd <= DBL_DIG) { if (!e1) goto ret; if (e1 > 0) { @@ -1835,6 +1814,7 @@ /* Put digits into bd: true value = bd * 10^e */ + bc.e0 = e; bc.nd = nd; bc.nd0 = nd0; /* Only needed if nd > STRTOD_DIGLIM, but done here */ /* to silence an erroneous warning about bc.nd0 */ From python-checkins at python.org Fri Jun 18 23:39:16 2010 From: python-checkins at python.org (mark.dickinson) Date: Fri, 18 Jun 2010 23:39:16 +0200 (CEST) Subject: [Python-checkins] r82082 - python/branches/py3k-dtoa/Python/dtoa.c Message-ID: <20100618213916.1FA53EE9BE@mail.python.org> Author: mark.dickinson Date: Fri Jun 18 23:39:15 2010 New Revision: 82082 Log: Fix typo. Modified: python/branches/py3k-dtoa/Python/dtoa.c Modified: python/branches/py3k-dtoa/Python/dtoa.c ============================================================================== --- python/branches/py3k-dtoa/Python/dtoa.c (original) +++ python/branches/py3k-dtoa/Python/dtoa.c Fri Jun 18 23:39:15 2010 @@ -1734,7 +1734,7 @@ goto ret; } } - else if (-e1 <= -Ten_pmax) { + else if (-e1 <= Ten_pmax) { dval(&rv) /= tens[-e1]; goto ret; } From solipsis at pitrou.net Sat Jun 19 01:23:46 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 19 Jun 2010 01:23:46 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r82076): sum=0 Message-ID: <20100618232346.B6E641770B@ns6635.ovh.net> py3k results for svn r82076 (hg cset 068b9b228aa3) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogM2j4kw', '-x'] From python-checkins at python.org Sat Jun 19 01:30:22 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Sat, 19 Jun 2010 01:30:22 +0200 (CEST) Subject: [Python-checkins] r82083 - in sandbox/branches/py3k-datetime: datetime.py test_datetime.py Message-ID: <20100618233022.74655EE9D6@mail.python.org> Author: alexander.belopolsky Date: Sat Jun 19 01:30:22 2010 New Revision: 82083 Log: Minimal changes to pass 3.2 unittests. Modified: sandbox/branches/py3k-datetime/datetime.py sandbox/branches/py3k-datetime/test_datetime.py Modified: sandbox/branches/py3k-datetime/datetime.py ============================================================================== --- sandbox/branches/py3k-datetime/datetime.py (original) +++ sandbox/branches/py3k-datetime/datetime.py Sat Jun 19 01:30:22 2010 @@ -19,6 +19,9 @@ import time as _time import math as _math +def cmp(x, y): + return 0 if x == y else 1 if x > y else -1 + MINYEAR = 1 MAXYEAR = 9999 @@ -467,21 +470,21 @@ daysecondsfrac, daysecondswhole = _math.modf(dayfrac * (24.*3600.)) assert daysecondswhole == int(daysecondswhole) # can't overflow s = int(daysecondswhole) - assert days == long(days) - d = long(days) + assert days == int(days) + d = int(days) else: daysecondsfrac = 0.0 d = days assert isinstance(daysecondsfrac, float) assert abs(daysecondsfrac) <= 1.0 - assert isinstance(d, (int, long)) + assert isinstance(d, int) assert abs(s) <= 24 * 3600 # days isn't referenced again before redefinition if isinstance(seconds, float): secondsfrac, seconds = _math.modf(seconds) - assert seconds == long(seconds) - seconds = long(seconds) + assert seconds == int(seconds) + seconds = int(seconds) secondsfrac += daysecondsfrac assert abs(secondsfrac) <= 2.0 else: @@ -490,7 +493,7 @@ assert isinstance(secondsfrac, float) assert abs(secondsfrac) <= 2.0 - assert isinstance(seconds, (int, long)) + assert isinstance(seconds, int) days, seconds = divmod(seconds, 24*3600) d += days s += int(seconds) # can't overflow @@ -504,14 +507,14 @@ if isinstance(microseconds, float): microseconds += usdouble - microseconds = round(microseconds) + microseconds = round(microseconds, 0) seconds, microseconds = divmod(microseconds, 1e6) assert microseconds == int(microseconds) - assert seconds == long(seconds) + assert seconds == int(seconds) days, seconds = divmod(seconds, 24.*3600.) - assert days == long(days) + assert days == int(days) assert seconds == int(seconds) - d += long(days) + d += int(days) s += int(seconds) # can't overflow assert isinstance(s, int) assert abs(s) <= 3 * 24 * 3600 @@ -524,7 +527,7 @@ assert abs(s) <= 3 * 24 * 3600 microseconds = float(microseconds) microseconds += usdouble - microseconds = round(microseconds) + microseconds = round(microseconds, 0) assert abs(s) <= 3 * 24 * 3600 assert abs(microseconds) < 3.1e6 @@ -538,7 +541,7 @@ days, s = divmod(s, 24*3600) d += days - assert isinstance(d, (int, long)) + assert isinstance(d, int) assert isinstance(s, int) and 0 <= s < 24*3600 assert isinstance(us, int) and 0 <= us < 1000000 @@ -622,25 +625,57 @@ return self def __mul__(self, other): - if isinstance(other, (int, long)): + if isinstance(other, int): # for CPython compatibility, we cannot use # our __class__ here, but need a real timedelta return timedelta(self.__days * other, self.__seconds * other, self.__microseconds * other) + if isinstance(other, float): + a, b = other.as_integer_ratio() + return self * a / b return NotImplemented __rmul__ = __mul__ - def __div__(self, other): - if isinstance(other, (int, long)): - usec = ((self.__days * (24*3600L) + self.__seconds) * 1000000 + - self.__microseconds) + def _to_microseconds(self): + return ((self.__days * (24*3600) + self.__seconds) * 1000000 + + self.__microseconds) + + def __floordiv__(self, other): + if not isinstance(other, (int, timedelta)): + return NotImplemented + usec = self._to_microseconds() + if isinstance(other, timedelta): + return usec // other._to_microseconds() + if isinstance(other, int): return timedelta(0, 0, usec // other) - return NotImplemented - __floordiv__ = __div__ + def __truediv__(self, other): + if not isinstance(other, (int, float, timedelta)): + return NotImplemented + usec = self._to_microseconds() + if isinstance(other, timedelta): + return usec / other._to_microseconds() + if isinstance(other, int): + return timedelta(0, 0, usec / other) + if isinstance(other, float): + a, b = other.as_integer_ratio() + return timedelta(0, 0, b * usec / a) + + def __mod__(self, other): + if isinstance(other, timedelta): + r = self._to_microseconds() % other._to_microseconds() + return timedelta(0, 0, r) + return NotImplemented + def __divmod__(self, other): + if isinstance(other, timedelta): + q, r = divmod(self._to_microseconds(), + other._to_microseconds()) + return q, timedelta(0, 0, r) + return NotImplemented + # Comparisons. def __eq__(self, other): @@ -686,7 +721,7 @@ def __hash__(self): return hash(self.__getstate()) - def __nonzero__(self): + def __bool__(self): return (self.__days != 0 or self.__seconds != 0 or self.__microseconds != 0) @@ -706,7 +741,7 @@ microseconds=999999) timedelta.resolution = timedelta(microseconds=1) -class date(object): +class date: """Concrete date type. Constructors: @@ -742,7 +777,7 @@ year, month, day (required, base 1) """ - if isinstance(year, str): + if isinstance(year, bytes): # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -878,26 +913,17 @@ def __lt__(self, other): if isinstance(other, date): return self.__cmp(other) < 0 - elif hasattr(other, "timetuple"): - return NotImplemented - else: - _cmperror(self, other) + return NotImplemented def __ge__(self, other): if isinstance(other, date): return self.__cmp(other) >= 0 - elif hasattr(other, "timetuple"): - return NotImplemented - else: - _cmperror(self, other) + return NotImplemented def __gt__(self, other): if isinstance(other, date): return self.__cmp(other) > 0 - elif hasattr(other, "timetuple"): - return NotImplemented - else: - _cmperror(self, other) + return NotImplemented def __cmp(self, other): assert isinstance(other, date) @@ -984,12 +1010,12 @@ def __getstate(self): yhi, ylo = divmod(self.__year, 256) - return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) + return bytes([yhi, ylo, self.__month, self.__day]), def __setstate(self, string): - if len(string) != 4 or not (1 <= ord(string[2]) <= 12): + if len(string) != 4 or not (1 <= string[2] <= 12): raise TypeError("not enough arguments") - yhi, ylo, self.__month, self.__day = map(ord, string) + yhi, ylo, self.__month, self.__day = string self.__year = yhi * 256 + ylo def __reduce__(self): @@ -1063,7 +1089,7 @@ args = getinitargs() else: args = () - getstate = getattr(self, "__getstate__", None) + getstate = getattr(self, "__getstate", None) if getstate: state = getstate() else: @@ -1334,9 +1360,9 @@ offset = _check_utc_offset("dst", offset) return offset - def __nonzero__(self): + def __bool__(self): if self.second or self.microsecond: - return 1 + return True offset = self._utcoffset() or 0 return self.hour * 60 + self.minute - offset != 0 @@ -1378,7 +1404,7 @@ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str): + if isinstance(year, bytes): # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) @@ -1543,7 +1569,7 @@ # Convert self to UTC, and attach the new time zone object. myoffset = self.utcoffset() if myoffset is None: - raise ValuError("astimezone() requires an aware datetime") + raise ValueError("astimezone() requires an aware datetime") utc = (self - myoffset).replace(tzinfo=tz) # Convert from UTC to tz's local time. @@ -1607,8 +1633,7 @@ def strptime(cls, date_string, format): 'string, format -> new datetime parsed from a string (like time.strptime()).' import _strptime - tt, us = _strptime._strptime(date_string, format) - return cls(*(tt[0:6] + (us,))) + return _strptime._strptime_datetime(cls, date_string, format) def utcoffset(self): """Return the timezone offset in minutes east of UTC (negative west of @@ -1662,7 +1687,7 @@ def __eq__(self, other): if isinstance(other, datetime): return self.__cmp(other) == 0 - elif hasattr(other, "timetuple") and not isinstance(other, date): + elif not isinstance(other, date): return NotImplemented else: return False @@ -1670,7 +1695,7 @@ def __ne__(self, other): if isinstance(other, datetime): return self.__cmp(other) != 0 - elif hasattr(other, "timetuple") and not isinstance(other, date): + elif not isinstance(other, date): return NotImplemented else: return True @@ -1678,7 +1703,7 @@ def __le__(self, other): if isinstance(other, datetime): return self.__cmp(other) <= 0 - elif hasattr(other, "timetuple") and not isinstance(other, date): + elif not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1686,7 +1711,7 @@ def __lt__(self, other): if isinstance(other, datetime): return self.__cmp(other) < 0 - elif hasattr(other, "timetuple") and not isinstance(other, date): + elif not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1694,7 +1719,7 @@ def __ge__(self, other): if isinstance(other, datetime): return self.__cmp(other) >= 0 - elif hasattr(other, "timetuple") and not isinstance(other, date): + elif not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1702,7 +1727,7 @@ def __gt__(self, other): if isinstance(other, datetime): return self.__cmp(other) > 0 - elif hasattr(other, "timetuple") and not isinstance(other, date): + elif not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1778,7 +1803,7 @@ if myoff == otoff: return base if myoff is None or otoff is None: - raise TypeError, "cannot mix naive and timezone-aware time" + raise TypeError("cannot mix naive and timezone-aware time") return base + timedelta(minutes = otoff-myoff) def __hash__(self): @@ -1797,9 +1822,9 @@ yhi, ylo = divmod(self.__year, 256) us2, us3 = divmod(self.__microsecond, 256) us1, us2 = divmod(us2, 256) - basestate = ("%c" * 10) % (yhi, ylo, self.__month, self.__day, - self.__hour, self.__minute, self.__second, - us1, us2, us3) + basestate = bytes([yhi, ylo, self.__month, self.__day, + self.__hour, self.__minute, self.__second, + us1, us2, us3]) if self._tzinfo is None: return (basestate,) else: @@ -1807,7 +1832,7 @@ def __setstate(self, string, tzinfo): (yhi, ylo, self.__month, self.__day, self.__hour, - self.__minute, self.__second, us1, us2, us3) = map(ord, string) + self.__minute, self.__second, us1, us2, us3) = string self.__year = yhi * 256 + ylo self.__microsecond = (((us1 << 8) | us2) << 8) | us3 self._tzinfo = tzinfo @@ -1832,6 +1857,89 @@ week1monday += 7 return week1monday +class timezone(tzinfo): + def __init__(self, offset, *args): + # Reproduce C behavior + n = len(args) + if n > 1: + raise TypeError("timezone() takes at most 2 arguments (%d given)" + % n) + if n == 0: + name = None + else: + name = args[0] + if not isinstance(name, str): + raise TypeError("name must be a string") + if isinstance(offset, timedelta): + if self._minoffset <= offset <= self._maxoffset: + if (offset.microseconds != 0 or + offset.seconds % 60 != 0): + raise ValueError("offset must be whole" + " number of minutes") + self.__offset = offset + else: + raise ValueError("offset out of range") + else: + raise TypeError("offset must be timedelta") + + self.__name = name + + def __eq__(self, other): + return self.__offset == other.__offset + + def __hash__(self): + return hash(self.__offset) + + def __str__(self): + return self.tzname(None) + + def utcoffset(self, dt): + if isinstance(dt, datetime) or dt is None: + return self.__offset + raise TypeError("utcoffset() argument must be a datetime instance" + " or None") + + def tzname(self, dt): + if isinstance(dt, datetime) or dt is None: + if self.__name is None: + return self._name_from_offset(self.__offset) + return self.__name + raise TypeError("tzname() argument must be a datetime instance" + " or None") + + def dst(self, dt): + if isinstance(dt, datetime) or dt is None: + return None + raise TypeError("dst() argument must be a datetime instance" + " or None") + + def fromutc(self, dt): + if isinstance(dt, datetime): + if dt.tzinfo is not self: + raise ValueError("fromutc: dt.tzinfo " + "is not self") + return dt + self.__offset + raise TypeError("fromutc() argument must be a datetime instance" + " or None") + + _maxoffset = timedelta(hours=23, minutes=59) + _minoffset = -_maxoffset + + @staticmethod + def _name_from_offset(delta): + if delta < timedelta(0): + sign = '-' + delta = -delta + else: + sign = '+' + hours, rest = divmod(delta, timedelta(hours=1)) + minutes = rest // timedelta(minutes=1) + return 'UTC{}{:02d}:{:02d}'.format(sign, hours, minutes) + +timezone.utc = timezone(timedelta(0)) +timezone.min = timezone(timezone._minoffset) +timezone.max = timezone(timezone._maxoffset) + """ Some time zone algebra. For a datetime x, let x.n = x stripped of its timezone -- its naive time. Modified: sandbox/branches/py3k-datetime/test_datetime.py ============================================================================== --- sandbox/branches/py3k-datetime/test_datetime.py (original) +++ sandbox/branches/py3k-datetime/test_datetime.py Sat Jun 19 01:30:22 2010 @@ -2,29 +2,39 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ -from __future__ import division + import sys import pickle -import cPickle import unittest -from test import test_support +from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod + +from test import support from datetime import MINYEAR, MAXYEAR from datetime import timedelta from datetime import tzinfo from datetime import time +from datetime import timezone from datetime import date, datetime +import time as _time -pickle_choices = [(pickler, unpickler, proto) - for pickler in pickle, cPickle - for unpickler in pickle, cPickle - for proto in range(3)] -assert len(pickle_choices) == 2*2*3 +pickle_choices = [(pickle, pickle, proto) for proto in range(3)] +assert len(pickle_choices) == 3 # An arbitrary collection of objects of non-datetime types, for testing # mixed-type comparisons. -OTHERSTUFF = (10, 10L, 34.5, "abc", {}, [], ()) +OTHERSTUFF = (10, 34.5, "abc", {}, [], ()) + + +# XXX Copied from test_float. +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") ############################################################################# @@ -41,6 +51,7 @@ # tzinfo tests class FixedOffset(tzinfo): + def __init__(self, offset, name, dstoffset=42): if isinstance(offset, int): offset = timedelta(minutes=offset) @@ -59,6 +70,7 @@ return self.__dstoffset class PicklableFixedOffset(FixedOffset): + def __init__(self, offset=None, name=None, dstoffset=None): FixedOffset.__init__(self, offset, name, dstoffset) @@ -123,6 +135,97 @@ self.assertEqual(derived.utcoffset(None), offset) self.assertEqual(derived.tzname(None), 'cookie') +class TestTimeZone(unittest.TestCase): + + def setUp(self): + self.ACDT = timezone(timedelta(hours=9.5), 'ACDT') + self.EST = timezone(-timedelta(hours=5), 'EST') + self.DT = datetime(2010, 1, 1) + + def test_str(self): + for tz in [self.ACDT, self.EST, timezone.utc, + timezone.min, timezone.max]: + self.assertEqual(str(tz), tz.tzname(None)) + + def test_class_members(self): + limit = timedelta(hours=23, minutes=59) + self.assertEqual(timezone.utc.utcoffset(None), ZERO) + self.assertEqual(timezone.min.utcoffset(None), -limit) + self.assertEqual(timezone.max.utcoffset(None), limit) + + + def test_constructor(self): + self.assertEqual(timezone.utc, timezone(timedelta(0))) + # invalid offsets + for invalid in [timedelta(microseconds=1), timedelta(1, 1), + timedelta(seconds=1), timedelta(1), -timedelta(1)]: + self.assertRaises(ValueError, timezone, invalid) + self.assertRaises(ValueError, timezone, -invalid) + + with self.assertRaises(TypeError): timezone(None) + with self.assertRaises(TypeError): timezone(42) + with self.assertRaises(TypeError): timezone(ZERO, None) + with self.assertRaises(TypeError): timezone(ZERO, 42) + + def test_inheritance(self): + self.assertIsInstance(timezone.utc, tzinfo) + self.assertIsInstance(self.EST, tzinfo) + + def test_utcoffset(self): + dummy = self.DT + for h in [0, 1.5, 12]: + offset = h * HOUR + self.assertEqual(offset, timezone(offset).utcoffset(dummy)) + self.assertEqual(-offset, timezone(-offset).utcoffset(dummy)) + + with self.assertRaises(TypeError): self.EST.utcoffset('') + with self.assertRaises(TypeError): self.EST.utcoffset(5) + + + def test_dst(self): + self.assertEqual(None, timezone.utc.dst(self.DT)) + + with self.assertRaises(TypeError): self.EST.dst('') + with self.assertRaises(TypeError): self.EST.dst(5) + + def test_tzname(self): + self.assertEqual('UTC+00:00', timezone(ZERO).tzname(None)) + self.assertEqual('UTC-05:00', timezone(-5 * HOUR).tzname(None)) + self.assertEqual('UTC+09:30', timezone(9.5 * HOUR).tzname(None)) + self.assertEqual('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None)) + self.assertEqual('XYZ', timezone(-5 * HOUR, 'XYZ').tzname(None)) + + with self.assertRaises(TypeError): self.EST.tzname('') + with self.assertRaises(TypeError): self.EST.tzname(5) + + def test_fromutc(self): + with self.assertRaises(ValueError): + timezone.utc.fromutc(self.DT) + for tz in [self.EST, self.ACDT, Eastern]: + utctime = self.DT.replace(tzinfo=tz) + local = tz.fromutc(utctime) + self.assertEqual(local - utctime, tz.utcoffset(local)) + self.assertEqual(local, + self.DT.replace(tzinfo=timezone.utc)) + + def test_comparison(self): + self.assertNotEqual(timezone(ZERO), timezone(HOUR)) + self.assertEqual(timezone(HOUR), timezone(HOUR)) + self.assertEqual(timezone(-5 * HOUR), timezone(-5 * HOUR, 'EST')) + with self.assertRaises(TypeError): timezone(ZERO) < timezone(ZERO) + self.assertIn(timezone(ZERO), {timezone(ZERO)}) + + def test_aware_datetime(self): + # test that timezone instances can be used by datetime + t = datetime(1, 1, 1) + for tz in [timezone.min, timezone.max, timezone.utc]: + self.assertEqual(tz.tzname(t), + t.replace(tzinfo=tz).tzname()) + self.assertEqual(tz.utcoffset(t), + t.replace(tzinfo=tz).utcoffset()) + self.assertEqual(tz.dst(t), + t.replace(tzinfo=tz).dst()) + ############################################################################# # Base clase for testing a particular aspect of timedelta, time, date and # datetime comparisons. @@ -141,8 +244,8 @@ self.assertFalse(() == me) self.assertTrue(() != me) - self.assertIn(me, [1, 20L, [], me]) - self.assertIn([], [me, 1, 20L, []]) + self.assertIn(me, [1, 20, [], me]) + self.assertIn([], [me, 1, 20, []]) def test_harmful_mixed_comparison(self): me = self.theclass(1, 1, 1) @@ -157,9 +260,6 @@ self.assertRaises(TypeError, lambda: () > me) self.assertRaises(TypeError, lambda: () >= me) - self.assertRaises(TypeError, cmp, (), me) - self.assertRaises(TypeError, cmp, me, ()) - ############################################################################# # timedelta tests @@ -211,13 +311,13 @@ eq(td(0, 0, 60*1000000), b) eq(a*10, td(70)) eq(a*10, 10*a) - eq(a*10L, 10*a) + eq(a*10, 10*a) eq(b*10, td(0, 600)) eq(10*b, td(0, 600)) - eq(b*10L, td(0, 600)) + eq(b*10, td(0, 600)) eq(c*10, td(0, 0, 10000)) eq(10*c, td(0, 0, 10000)) - eq(c*10L, td(0, 0, 10000)) + eq(c*10, td(0, 0, 10000)) eq(a*-1, -a) eq(b*-2, -b-b) eq(c*-2, -c+-c) @@ -230,31 +330,60 @@ eq(c//1000, td(0, 0, 1)) eq(a//10, td(0, 7*24*360)) eq(a//3600000, td(0, 0, 7*24*1000)) + eq(a/0.5, td(14)) + eq(b/0.5, td(0, 120)) + eq(a/7, td(1)) + eq(b/10, td(0, 6)) + eq(c/1000, td(0, 0, 1)) + eq(a/10, td(0, 7*24*360)) + eq(a/3600000, td(0, 0, 7*24*1000)) + + # Multiplication by float + us = td(microseconds=1) + eq((3*us) * 0.5, 2*us) + eq((5*us) * 0.5, 2*us) + eq(0.5 * (3*us), 2*us) + eq(0.5 * (5*us), 2*us) + eq((-3*us) * 0.5, -2*us) + eq((-5*us) * 0.5, -2*us) + + # Division by int and float + eq((3*us) / 2, 2*us) + eq((5*us) / 2, 2*us) + eq((-3*us) / 2.0, -2*us) + eq((-5*us) / 2.0, -2*us) + eq((3*us) / -2, -2*us) + eq((5*us) / -2, -2*us) + eq((3*us) / -2.0, -2*us) + eq((5*us) / -2.0, -2*us) + for i in range(-10, 10): + eq((i*us/3)//us, round(i/3)) + for i in range(-10, 10): + eq((i*us/-3)//us, round(i/-3)) def test_disallowed_computations(self): a = timedelta(42) - # Add/sub ints, longs, floats should be illegal - for i in 1, 1L, 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) self.assertRaises(TypeError, lambda: i-a) - # Mul/div by float isn't supported. - x = 2.3 - self.assertRaises(TypeError, lambda: a*x) - self.assertRaises(TypeError, lambda: x*a) - self.assertRaises(TypeError, lambda: a/x) - self.assertRaises(TypeError, lambda: x/a) - self.assertRaises(TypeError, lambda: a // x) - self.assertRaises(TypeError, lambda: x // a) - # Division of int by timedelta doesn't make sense. # Division by zero doesn't make sense. - for zero in 0, 0L: - 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) + self.assertRaises(ZeroDivisionError, lambda: a / zero) + self.assertRaises(ZeroDivisionError, lambda: a / 0.0) + + @requires_IEEE_754 + def test_disallowed_special(self): + a = timedelta(42) + self.assertRaises(ValueError, a.__mul__, NAN) + self.assertRaises(ValueError, a.__truediv__, NAN) def test_basic_attributes(self): days, seconds, us = 1, 7, 31 @@ -273,9 +402,7 @@ # accuracy as td / timedelta(seconds=1). for ms in [-1, -2, -123]: td = timedelta(microseconds=ms) - self.assertEqual(td.total_seconds(), - ((24*3600*td.days + td.seconds)*10**6 - + td.microseconds)/10**6) + self.assertEqual(td.total_seconds(), td / timedelta(seconds=1)) def test_carries(self): t1 = timedelta(days=100, @@ -318,14 +445,12 @@ def test_compare(self): t1 = timedelta(2, 3, 4) t2 = timedelta(2, 3, 4) - self.assertTrue(t1 == t2) + self.assertEqual(t1, t2) self.assertTrue(t1 <= t2) self.assertTrue(t1 >= t2) self.assertTrue(not t1 != t2) self.assertTrue(not t1 < t2) self.assertTrue(not t1 > t2) - self.assertEqual(cmp(t1, t2), 0) - self.assertEqual(cmp(t2, t1), 0) for args in (3, 3, 3), (2, 4, 4), (2, 3, 5): t2 = timedelta(*args) # this is larger than t1 @@ -341,8 +466,6 @@ self.assertTrue(not t2 < t1) self.assertTrue(not t1 >= t2) self.assertTrue(not t2 <= t1) - self.assertEqual(cmp(t1, t2), -1) - self.assertEqual(cmp(t2, t1), 1) for badarg in OTHERSTUFF: self.assertEqual(t1 == badarg, False) @@ -421,6 +544,19 @@ self.assertRaises(OverflowError, lambda: -timedelta.max) + day = timedelta(1) + self.assertRaises(OverflowError, day.__mul__, 10**9) + self.assertRaises(OverflowError, day.__mul__, 1e9) + self.assertRaises(OverflowError, day.__truediv__, 1e-20) + self.assertRaises(OverflowError, day.__truediv__, 1e-10) + self.assertRaises(OverflowError, day.__truediv__, 9e-10) + + @requires_IEEE_754 + def _test_overflow_special(self): + day = timedelta(1) + self.assertRaises(OverflowError, day.__mul__, INF) + self.assertRaises(OverflowError, day.__mul__, -INF) + def test_microsecond_rounding(self): td = timedelta eq = self.assertEqual @@ -485,6 +621,58 @@ self.assertEqual(str(t3), str(t4)) self.assertEqual(t4.as_hours(), -1) + def test_division(self): + t = timedelta(hours=1, minutes=24, seconds=19) + second = timedelta(seconds=1) + self.assertEqual(t / second, 5059.0) + self.assertEqual(t // second, 5059) + + t = timedelta(minutes=2, seconds=30) + minute = timedelta(minutes=1) + self.assertEqual(t / minute, 2.5) + self.assertEqual(t // minute, 2) + + zerotd = timedelta(0) + self.assertRaises(ZeroDivisionError, truediv, t, zerotd) + self.assertRaises(ZeroDivisionError, floordiv, t, zerotd) + + # self.assertRaises(TypeError, truediv, t, 2) + # note: floor division of a timedelta by an integer *is* + # currently permitted. + + def test_remainder(self): + t = timedelta(minutes=2, seconds=30) + minute = timedelta(minutes=1) + r = t % minute + self.assertEqual(r, timedelta(seconds=30)) + + t = timedelta(minutes=-2, seconds=30) + r = t % minute + self.assertEqual(r, timedelta(seconds=30)) + + zerotd = timedelta(0) + self.assertRaises(ZeroDivisionError, mod, t, zerotd) + + self.assertRaises(TypeError, mod, t, 10) + + def test_divmod(self): + t = timedelta(minutes=2, seconds=30) + minute = timedelta(minutes=1) + q, r = divmod(t, minute) + self.assertEqual(q, 2) + self.assertEqual(r, timedelta(seconds=30)) + + t = timedelta(minutes=-2, seconds=30) + q, r = divmod(t, minute) + self.assertEqual(q, -2) + self.assertEqual(r, timedelta(seconds=30)) + + zerotd = timedelta(0) + self.assertRaises(ZeroDivisionError, divmod, t, zerotd) + + self.assertRaises(TypeError, divmod, t, 10) + + ############################################################################# # date tests @@ -571,7 +759,7 @@ # Check first and last days of year spottily across the whole # range of years supported. - for year in xrange(MINYEAR, MAXYEAR+1, 7): + for year in range(MINYEAR, MAXYEAR+1, 7): # Verify (year, 1, 1) -> ordinal -> y, m, d is identity. d = self.theclass(year, 1, 1) n = d.toordinal() @@ -698,8 +886,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, 1L, 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) @@ -833,8 +1021,7 @@ 320 348 376 325 353 381 """ - iso_long_years = map(int, ISO_LONG_YEARS_TABLE.split()) - iso_long_years.sort() + iso_long_years = sorted(map(int, ISO_LONG_YEARS_TABLE.split())) L = [] for i in range(400): d = self.theclass(2000+i, 12, 31) @@ -863,7 +1050,7 @@ self.assertRaises(TypeError, t.strftime, 42) # arg wrong type # test that unicode input is allowed (issue 2782) - self.assertEqual(t.strftime(u"%m"), "03") + self.assertEqual(t.strftime("%m"), "03") # A naive object replaces %z and %Z w/ empty strings. self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") @@ -913,8 +1100,13 @@ self.assertEqual(b.__format__(fmt), 'B') def test_resolution_info(self): - self.assertIsInstance(self.theclass.min, self.theclass) - self.assertIsInstance(self.theclass.max, self.theclass) + # XXX: Should min and max respect subclassing? + if issubclass(self.theclass, datetime): + expected_class = datetime + else: + expected_class = date + self.assertIsInstance(self.theclass.min, expected_class) + self.assertIsInstance(self.theclass.max, expected_class) self.assertIsInstance(self.theclass.resolution, timedelta) self.assertTrue(self.theclass.max > self.theclass.min) @@ -964,14 +1156,12 @@ def test_compare(self): t1 = self.theclass(2, 3, 4) t2 = self.theclass(2, 3, 4) - self.assertTrue(t1 == t2) + self.assertEqual(t1, t2) self.assertTrue(t1 <= t2) self.assertTrue(t1 >= t2) self.assertTrue(not t1 != t2) self.assertTrue(not t1 < t2) self.assertTrue(not t1 > t2) - self.assertEqual(cmp(t1, t2), 0) - self.assertEqual(cmp(t2, t1), 0) for args in (3, 3, 3), (2, 4, 4), (2, 3, 5): t2 = self.theclass(*args) # this is larger than t1 @@ -987,8 +1177,6 @@ self.assertTrue(not t2 < t1) self.assertTrue(not t1 >= t2) self.assertTrue(not t2 <= t1) - self.assertEqual(cmp(t1, t2), -1) - self.assertEqual(cmp(t2, t1), 1) for badarg in OTHERSTUFF: self.assertEqual(t1 == badarg, False) @@ -1006,42 +1194,54 @@ def test_mixed_compare(self): our = self.theclass(2000, 4, 5) - self.assertRaises(TypeError, cmp, our, 1) - self.assertRaises(TypeError, cmp, 1, our) - class AnotherDateTimeClass(object): - def __cmp__(self, other): - # Return "equal" so calling this can't be confused with - # compare-by-address (which never says "equal" for distinct - # objects). - return 0 - __hash__ = None # Silence Py3k warning - - # This still errors, because date and datetime comparison raise - # TypeError instead of NotImplemented when they don't know what to - # do, in order to stop comparison from falling back to the default - # compare-by-address. - their = AnotherDateTimeClass() - self.assertRaises(TypeError, cmp, our, their) - # Oops: The next stab raises TypeError in the C implementation, - # but not in the Python implementation of datetime. The difference - # is due to that the Python implementation defines __cmp__ but - # the C implementation defines tp_richcompare. This is more pain - # to fix than it's worth, so commenting out the test. - # self.assertEqual(cmp(their, our), 0) - - # But date and datetime comparison return NotImplemented instead if the - # other object has a timetuple attr. This gives the other object a - # chance to do the comparison. - class Comparable(AnotherDateTimeClass): - def timetuple(self): - return () - - their = Comparable() - self.assertEqual(cmp(our, their), 0) - self.assertEqual(cmp(their, our), 0) - self.assertTrue(our == their) - self.assertTrue(their == our) + # Our class can be compared for equality to other classes + self.assertEqual(our == 1, False) + self.assertEqual(1 == our, False) + self.assertEqual(our != 1, True) + self.assertEqual(1 != our, True) + + # But the ordering is undefined + self.assertRaises(TypeError, lambda: our < 1) + self.assertRaises(TypeError, lambda: 1 < our) + + # Repeat those tests with a different class + + class SomeClass: + pass + + their = SomeClass() + self.assertEqual(our == their, False) + self.assertEqual(their == our, False) + self.assertEqual(our != their, True) + self.assertEqual(their != our, True) + self.assertRaises(TypeError, lambda: our < their) + self.assertRaises(TypeError, lambda: their < our) + + # However, if the other class explicitly defines ordering + # relative to our class, it is allowed to do so + + class LargerThanAnything: + def __lt__(self, other): + return False + def __le__(self, other): + return isinstance(other, LargerThanAnything) + def __eq__(self, other): + return isinstance(other, LargerThanAnything) + def __ne__(self, other): + return not isinstance(other, LargerThanAnything) + def __gt__(self, other): + return not isinstance(other, LargerThanAnything) + def __ge__(self, other): + return True + + their = LargerThanAnything() + self.assertEqual(our == their, False) + self.assertEqual(their == our, False) + self.assertEqual(our != their, True) + self.assertEqual(their != our, True) + self.assertEqual(our < their, True) + self.assertEqual(their < our, False) def test_bool(self): # All dates are considered true. @@ -1112,7 +1312,7 @@ self.assertEqual(orig, derived) def test_backdoor_resistance(self): - # For fast unpickling, the constructor accepts a pickle string. + # For fast unpickling, the constructor accepts a pickle byte string. # This is a low-overhead backdoor. A user can (by intent or # mistake) pass a string directly, which (if it's the right length) # will get treated like a pickle, and bypass the normal sanity @@ -1120,17 +1320,17 @@ # The constructor doesn't want to burn the time to validate all # fields, but does check the month field. This stops, e.g., # datetime.datetime('1995-03-25') from yielding an insane object. - base = '1995-03-25' + base = b'1995-03-25' if not issubclass(self.theclass, datetime): base = base[:4] - for month_byte in '9', chr(0), chr(13), '\xff': + for month_byte in b'9', b'\0', b'\r', b'\xff': self.assertRaises(TypeError, self.theclass, base[:2] + month_byte + base[3:]) for ord_byte in range(1, 13): # This shouldn't blow up because of the month byte alone. If # the implementation changes to do more-careful checking, it may # blow up because other fields are insane. - self.theclass(base[:2] + chr(ord_byte) + base[3:]) + self.theclass(base[:2] + bytes([ord_byte]) + base[3:]) ############################################################################# # datetime tests @@ -1384,8 +1584,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, 1L, 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) @@ -1434,14 +1634,12 @@ args = [2000, 11, 29, 20, 58, 16, 999998] t1 = self.theclass(*args) t2 = self.theclass(*args) - self.assertTrue(t1 == t2) + self.assertEqual(t1, t2) self.assertTrue(t1 <= t2) self.assertTrue(t1 >= t2) self.assertTrue(not t1 != t2) self.assertTrue(not t1 < t2) self.assertTrue(not t1 > t2) - self.assertEqual(cmp(t1, t2), 0) - self.assertEqual(cmp(t2, t1), 0) for i in range(len(args)): newargs = args[:] @@ -1459,8 +1657,6 @@ self.assertTrue(not t2 < t1) self.assertTrue(not t1 >= t2) self.assertTrue(not t2 <= t1) - self.assertEqual(cmp(t1, t2), -1) - self.assertEqual(cmp(t2, t1), 1) # A helper for timestamp constructor tests. @@ -1491,8 +1687,8 @@ def test_microsecond_rounding(self): # Test whether fromtimestamp "rounds up" floats that are less # than one microsecond smaller than an integer. - self.assertEquals(self.theclass.fromtimestamp(0.9999999), - self.theclass.fromtimestamp(1)) + self.assertEqual(self.theclass.fromtimestamp(0.9999999), + self.theclass.fromtimestamp(1)) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, @@ -1520,7 +1716,7 @@ @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_utcfromtimestamp(self): d = self.theclass.utcfromtimestamp(-1.05) - self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) + self.assertEqual(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) def test_utcnow(self): import time @@ -1541,10 +1737,42 @@ string = '2004-12-01 13:02:47.197' format = '%Y-%m-%d %H:%M:%S.%f' - result, frac = _strptime._strptime(string, format) - expected = self.theclass(*(result[0:6]+(frac,))) + expected = _strptime._strptime_datetime(self.theclass, string, format) got = self.theclass.strptime(string, format) self.assertEqual(expected, got) + self.assertIs(type(expected), self.theclass) + self.assertIs(type(got), self.theclass) + + strptime = self.theclass.strptime + self.assertEqual(strptime("+0002", "%z").utcoffset(), 2 * MINUTE) + self.assertEqual(strptime("-0002", "%z").utcoffset(), -2 * MINUTE) + # Only local timezone and UTC are supported + for tzseconds, tzname in ((0, 'UTC'), (0, 'GMT'), + (-_time.timezone, _time.tzname[0])): + if tzseconds < 0: + sign = '-' + seconds = -tzseconds + else: + sign ='+' + seconds = tzseconds + hours, minutes = divmod(seconds//60, 60) + dtstr = "{}{:02d}{:02d} {}".format(sign, hours, minutes, tzname) + dt = strptime(dtstr, "%z %Z") + self.assertEqual(dt.utcoffset(), timedelta(seconds=tzseconds)) + self.assertEqual(dt.tzname(), tzname) + # Can produce inconsistent datetime + dtstr, fmt = "+1234 UTC", "%z %Z" + dt = strptime(dtstr, fmt) + self.assertEqual(dt.utcoffset(), 12 * HOUR + 34 * MINUTE) + self.assertEqual(dt.tzname(), 'UTC') + # yet will roundtrip + self.assertEqual(dt.strftime(fmt), dtstr) + + # Produce naive datetime if no %z is provided + self.assertEqual(strptime("UTC", "%Z").tzinfo, None) + + with self.assertRaises(ValueError): strptime("-2400", "%z") + with self.assertRaises(ValueError): strptime("-000", "%z") def test_more_timetuple(self): # This tests fields beyond those tested by the TestDate.test_timetuple. @@ -1675,6 +1903,12 @@ self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month + dt1.second - 7) +class TestSubclassDateTime(TestDateTime): + theclass = SubclassDatetime + # Override tests not designed for subclass + def test_roundtrip(self): + pass + class SubclassTime(time): sub_var = 1 @@ -1717,14 +1951,12 @@ args = [1, 2, 3, 4] t1 = self.theclass(*args) t2 = self.theclass(*args) - self.assertTrue(t1 == t2) + self.assertEqual(t1, t2) self.assertTrue(t1 <= t2) self.assertTrue(t1 >= t2) self.assertTrue(not t1 != t2) self.assertTrue(not t1 < t2) self.assertTrue(not t1 > t2) - self.assertEqual(cmp(t1, t2), 0) - self.assertEqual(cmp(t2, t1), 0) for i in range(len(args)): newargs = args[:] @@ -1742,8 +1974,6 @@ self.assertTrue(not t2 < t1) self.assertTrue(not t1 >= t2) self.assertTrue(not t2 <= t1) - self.assertEqual(cmp(t1, t2), -1) - self.assertEqual(cmp(t2, t1), 1) for badarg in OTHERSTUFF: self.assertEqual(t1 == badarg, False) @@ -2117,9 +2347,10 @@ d2 = base.replace(minute=11) for x in d0, d1, d2: for y in d0, d1, d2: - got = cmp(x, y) - expected = cmp(x.minute, y.minute) - self.assertEqual(got, expected) + for op in lt, le, gt, ge, eq, ne: + got = op(x, y) + expected = op(x.minute, y.minute) + self.assertEqual(got, expected) # However, if they're different members, uctoffset is not ignored. # Note that a time can't actually have an operand-depedent offset, @@ -2131,7 +2362,7 @@ d2 = base.replace(minute=11, tzinfo=OperandDependentOffset()) for x in d0, d1, d2: for y in d0, d1, d2: - got = cmp(x, y) + got = (x > y) - (x < y) if (x is d0 or x is d1) and (y is d0 or y is d1): expected = 0 elif x is y is d2: @@ -2422,8 +2653,8 @@ self.assertTrue(t1 != t2) self.assertTrue(t2 > t1) - self.assertTrue(t1 == t1) - self.assertTrue(t2 == t2) + self.assertEqual(t1, t1) + self.assertEqual(t2, t2) # Equal afer adjustment. t1 = self.theclass(1, 12, 31, 23, 59, tzinfo=FixedOffset(1, "")) @@ -2636,20 +2867,21 @@ # We don't know which time zone we're in, and don't have a tzinfo # class to represent it, so seeing whether a tz argument actually # does a conversion is tricky. - weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0) utc = FixedOffset(0, "utc", 0) - for dummy in range(3): - now = datetime.now(weirdtz) - self.assertTrue(now.tzinfo is weirdtz) - utcnow = datetime.utcnow().replace(tzinfo=utc) - now2 = utcnow.astimezone(weirdtz) - if abs(now - now2) < timedelta(seconds=30): - break - # Else the code is broken, or more than 30 seconds passed between - # calls; assuming the latter, just try again. - else: - # Three strikes and we're out. - self.fail("utcnow(), now(tz), or astimezone() may be broken") + for weirdtz in [FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0), + timezone(timedelta(hours=15, minutes=58), "weirdtz"),]: + for dummy in range(3): + now = datetime.now(weirdtz) + self.assertTrue(now.tzinfo is weirdtz) + utcnow = datetime.utcnow().replace(tzinfo=utc) + now2 = utcnow.astimezone(weirdtz) + if abs(now - now2) < timedelta(seconds=30): + break + # Else the code is broken, or more than 30 seconds passed between + # calls; assuming the latter, just try again. + else: + # Three strikes and we're out. + self.fail("utcnow(), now(tz), or astimezone() may be broken") def test_tzinfo_fromtimestamp(self): import time @@ -2826,6 +3058,7 @@ self.assertEqual(iso, datestr + 'T' + tailstr) self.assertEqual(iso, d.isoformat('T')) self.assertEqual(d.isoformat('k'), datestr + 'k' + tailstr) + self.assertEqual(d.isoformat('\u1234'), datestr + '\u1234' + tailstr) self.assertEqual(str(d), datestr + ' ' + tailstr) def test_replace(self): @@ -3007,6 +3240,7 @@ return dt ZERO = timedelta(0) +MINUTE = timedelta(minutes=1) HOUR = timedelta(hours=1) DAY = timedelta(days=1) # In the US, DST starts at 2am (standard time) on the first Sunday in April. @@ -3336,10 +3570,10 @@ # Neverthelss, comparison should work with the base-class (date) # projection if use of a date method is forced. - self.assertTrue(as_date.__eq__(as_datetime)) + self.assertEqual(as_date.__eq__(as_datetime), True) different_day = (as_date.day + 1) % 20 + 1 - self.assertTrue(not as_date.__eq__(as_datetime.replace(day= - different_day))) + as_different = as_datetime.replace(day= different_day) + self.assertEqual(as_date.__eq__(as_different), False) # And date should compare with other subclasses of date. If a # subclass wants to stop this, it's up to the subclass to do so. @@ -3354,7 +3588,7 @@ self.assertEqual(datetime_sc, as_datetime) def test_main(): - test_support.run_unittest(__name__) + support.run_unittest(__name__) if __name__ == "__main__": test_main() From python-checkins at python.org Sat Jun 19 01:59:46 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 19 Jun 2010 01:59:46 +0200 (CEST) Subject: [Python-checkins] r82084 - python/branches/py3k/Doc/c-api/arg.rst Message-ID: <20100618235946.23EF0D588@mail.python.org> Author: victor.stinner Date: Sat Jun 19 01:59:45 2010 New Revision: 82084 Log: Issue #8939: Improve arg.rst * Add :ctype: to Py_BEGIN_ALLOW_THREADS and int * "s" and "s#" formats of Py_BuildValue(): specify that the Python object type is str in the description Modified: python/branches/py3k/Doc/c-api/arg.rst Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Sat Jun 19 01:59:45 2010 @@ -36,7 +36,7 @@ However, when a :ctype:`Py_buffer` structure gets filled, the underlying buffer is locked so that the caller can subsequently use the buffer even -inside a ``Py_BEGIN_ALLOW_THREADS`` block without the risk of mutable data +inside a :ctype:`Py_BEGIN_ALLOW_THREADS` block without the risk of mutable data being resized or destroyed. As a result, **you have to call** :cfunc:`PyBuffer_Release` after you have finished processing the data (or in any early abort case). @@ -48,9 +48,9 @@ the length argument (int or :ctype:`Py_ssize_t`) is controlled by defining the macro :cmacro:`PY_SSIZE_T_CLEAN` before including :file:`Python.h`. If the macro was defined, length is a - :ctype:`Py_ssize_t` rather than an int. This behavior will change + :ctype:`Py_ssize_t` rather than an :ctype:`int`. This behavior will change in a future Python version to only support :ctype:`Py_ssize_t` and - drop int support. It is best to always define :cmacro:`PY_SSIZE_T_CLEAN`. + drop :ctype:`int` support. It is best to always define :cmacro:`PY_SSIZE_T_CLEAN`. ``s`` (:class:`str`) [const char \*] @@ -492,11 +492,11 @@ strings a tad more readable. ``s`` (:class:`str` or ``None``) [char \*] - Convert a null-terminated C string to a Python object using ``'utf-8'`` + Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is *NULL*, ``None`` is used. ``s#`` (:class:`str` or ``None``) [char \*, int] - Convert a C string and its length to a Python object using ``'utf-8'`` + Convert a C string and its length to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is *NULL*, the length is ignored and ``None`` is returned. From python-checkins at python.org Sat Jun 19 02:05:54 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 19 Jun 2010 02:05:54 +0200 (CEST) Subject: [Python-checkins] r82085 - in python/branches/release31-maint: Doc/c-api/arg.rst Message-ID: <20100619000554.8A4A3EE996@mail.python.org> Author: victor.stinner Date: Sat Jun 19 02:05:54 2010 New Revision: 82085 Log: Merged revisions 82084 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r82084 | victor.stinner | 2010-06-19 01:59:45 +0200 (sam., 19 juin 2010) | 6 lines Issue #8939: Improve arg.rst * Add :ctype: to Py_BEGIN_ALLOW_THREADS and int * "s" and "s#" formats of Py_BuildValue(): specify that the Python object type is str in the description ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/c-api/arg.rst Modified: python/branches/release31-maint/Doc/c-api/arg.rst ============================================================================== --- python/branches/release31-maint/Doc/c-api/arg.rst (original) +++ python/branches/release31-maint/Doc/c-api/arg.rst Sat Jun 19 02:05:54 2010 @@ -36,7 +36,7 @@ However, when a :ctype:`Py_buffer` structure gets filled, the underlying buffer is locked so that the caller can subsequently use the buffer even -inside a ``Py_BEGIN_ALLOW_THREADS`` block without the risk of mutable data +inside a :ctype:`Py_BEGIN_ALLOW_THREADS` block without the risk of mutable data being resized or destroyed. As a result, **you have to call** :cfunc:`PyBuffer_Release` after you have finished processing the data (or in any early abort case). @@ -48,9 +48,9 @@ the length argument (int or :ctype:`Py_ssize_t`) is controlled by defining the macro :cmacro:`PY_SSIZE_T_CLEAN` before including :file:`Python.h`. If the macro was defined, length is a - :ctype:`Py_ssize_t` rather than an int. This behavior will change + :ctype:`Py_ssize_t` rather than an :ctype:`int`. This behavior will change in a future Python version to only support :ctype:`Py_ssize_t` and - drop int support. It is best to always define :cmacro:`PY_SSIZE_T_CLEAN`. + drop :ctype:`int` support. It is best to always define :cmacro:`PY_SSIZE_T_CLEAN`. ``s`` (:class:`str`) [const char \*] @@ -488,11 +488,11 @@ strings a tad more readable. ``s`` (:class:`str` or ``None``) [char \*] - Convert a null-terminated C string to a Python object using ``'utf-8'`` + Convert a null-terminated C string to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is *NULL*, ``None`` is used. ``s#`` (:class:`str` or ``None``) [char \*, int] - Convert a C string and its length to a Python object using ``'utf-8'`` + Convert a C string and its length to a Python :class:`str` object using ``'utf-8'`` encoding. If the C string pointer is *NULL*, the length is ignored and ``None`` is returned. From python-checkins at python.org Sat Jun 19 12:05:06 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 19 Jun 2010 12:05:06 +0200 (CEST) Subject: [Python-checkins] r82086 - python/branches/py3k-dtoa/Lib/test/test_strtod.py Message-ID: <20100619100506.1BF45EE9FC@mail.python.org> Author: mark.dickinson Date: Sat Jun 19 12:05:05 2010 New Revision: 82086 Log: Increase testing level while we're working on this code. Modified: python/branches/py3k-dtoa/Lib/test/test_strtod.py Modified: python/branches/py3k-dtoa/Lib/test/test_strtod.py ============================================================================== --- python/branches/py3k-dtoa/Lib/test/test_strtod.py (original) +++ python/branches/py3k-dtoa/Lib/test/test_strtod.py Sat Jun 19 12:05:05 2010 @@ -80,7 +80,7 @@ hexdigs, e + 4*hexdigs) -TEST_SIZE = 10 +TEST_SIZE = 1000 class StrtodTests(unittest.TestCase): def check_strtod(self, s): From python-checkins at python.org Sat Jun 19 12:15:27 2010 From: python-checkins at python.org (mark.dickinson) Date: Sat, 19 Jun 2010 12:15:27 +0200 (CEST) Subject: [Python-checkins] r82087 - python/branches/py3k-dtoa/Python/dtoa.c Message-ID: <20100619101527.43118EE985@mail.python.org> Author: mark.dickinson Date: Sat Jun 19 12:15:27 2010 New Revision: 82087 Log: Simplify ratio function, and allow the numerator of the ratio function to be zero. Modified: python/branches/py3k-dtoa/Python/dtoa.c Modified: python/branches/py3k-dtoa/Python/dtoa.c ============================================================================== --- python/branches/py3k-dtoa/Python/dtoa.c (original) +++ python/branches/py3k-dtoa/Python/dtoa.c Sat Jun 19 12:15:27 2010 @@ -985,41 +985,19 @@ return dval(&u); } -/* Convert a Bigint to a double plus an exponent */ +/* Convert a Bigint a to a double giving the value a / 2**(32 * a->wds). + Error < 0.75 ulps. This function is currently used only by ratio. */ static double -b2d(Bigint *a, int *e) +b2d(Bigint *a) { - ULong *xa, *xa0, w, y, z; - int k; - U d; - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; - if (k < Ebits) { - word0(&d) = Exp_1 | y >> (Ebits - k); - w = xa > xa0 ? *--xa : 0; - word1(&d) = y << ((32-Ebits) + k) | w >> (Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - word0(&d) = Exp_1 | y << k | z >> (32 - k); - y = xa > xa0 ? *--xa : 0; - word1(&d) = z << k | y >> (32 - k); - } - else { - word0(&d) = Exp_1 | y; - word1(&d) = z; - } - ret_d: - return dval(&d); + int i, wds; + double d; + wds = a->wds; + d = 0.0; + for (i = wds > 3 ? wds - 3 : 0; i < wds; i++) + d = (d + a->x[i]) * (1.0 / 4294967296.0); + return d; } /* Convert a scaled double to a Bigint plus an exponent. Similar to d2b, @@ -1147,23 +1125,26 @@ } /* Compute the ratio of two Bigints, as a double. The result may have an - error of up to 2.5 ulps. */ + error of up to 3.5 ulps. */ static double ratio(Bigint *a, Bigint *b) { U da, db; - int k, ka, kb; + int k; - dval(&da) = b2d(a, &ka); - dval(&db) = b2d(b, &kb); - k = ka - kb + 32*(a->wds - b->wds); - if (k > 0) - word0(&da) += k*Exp_msk1; - else { - k = -k; - word0(&db) += k*Exp_msk1; - } +#ifdef DEBUG + if (!b->x[0] && b->wds == 1) + Bug("zero divisor in ratio"); +#endif + + dval(&da) = b2d(a); + dval(&db) = b2d(b); + k = a->wds - b->wds; + if (k >= 0) + word0(&da) += 32*Exp_msk1*k; + else + word0(&db) += 32*Exp_msk1*-k; return dval(&da) / dval(&db); } From python-checkins at python.org Sat Jun 19 21:48:39 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 21:48:39 +0200 (CEST) Subject: [Python-checkins] r82088 - python/branches/py3k-signalfd-issue8407 Message-ID: <20100619194839.67B89EE998@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 21:48:39 2010 New Revision: 82088 Log: Create a branch for adding signalfd support to py3k Added: python/branches/py3k-signalfd-issue8407/ - copied from r82087, /python/branches/py3k/ From python-checkins at python.org Sat Jun 19 21:54:49 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 21:54:49 +0200 (CEST) Subject: [Python-checkins] r82089 - in python/branches/py3k: Doc/library/signal.rst Lib/test/test_signal.py Misc/NEWS Modules/signalmodule.c configure configure.in pyconfig.h.in Message-ID: <20100619195449.24D5EEE998@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 21:54:48 2010 New Revision: 82089 Log: merge forward from the python 2.x branch Modified: python/branches/py3k/Doc/library/signal.rst python/branches/py3k/Lib/test/test_signal.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/signalmodule.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/Doc/library/signal.rst ============================================================================== --- python/branches/py3k/Doc/library/signal.rst (original) +++ python/branches/py3k/Doc/library/signal.rst Sat Jun 19 21:54:48 2010 @@ -13,9 +13,6 @@ underlying implementation), with the exception of the handler for :const:`SIGCHLD`, which follows the underlying implementation. -* There is no way to "block" signals temporarily from critical sections (since - this is not supported by all Unix flavors). - * Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the "atomic" instructions of the Python interpreter. This means that signals arriving during long calculations @@ -115,6 +112,46 @@ in user and kernel space. SIGPROF is delivered upon expiration. +.. data:: SIG_BLOCK + + A possible value for the *how* parameter to :func:`sigprocmask` + indicating that signals are to be blocked. + + .. versionadded:: 2.7 + + +.. data:: SIG_UNBLOCK + + A possible value for the *how* parameter to :func:`sigprocmask` + indicating that signals are to be unblocked. + + .. versionadded:: 2.7 + + +.. data:: SIG_SETMASK + + A possible value for the *how* parameter to :func:`sigprocmask` + indicating that the signal mask is to be replaced. + + .. versionadded:: 2.7 + + +.. data:: SFD_CLOEXEC + + A possible flag in the *flags* parameter to :func:`signalfd` which causes + the new file descriptor to be marked as close-on-exec. + + .. versionadded:: 2.7 + + +.. data:: SFD_NONBLOCK + + A possible flag in the *flags* parameter to :func:`signalfd` which causes + the new file description to be set non-blocking. + + .. versionadded:: 2.7 + + The :mod:`signal` module defines one exception: .. exception:: ItimerError @@ -227,6 +264,44 @@ attribute descriptions in the :mod:`inspect` module). +.. function:: signalfd(fd, mask[, flags]) + + Create a new file descriptor on which to receive signals or modify the + mask of such a file descriptor previously created by this function. + Availability: Linux (See the manpage :manpage:`signalfd(2)` for further + information). + + If *fd* is ``-1``, a new file descriptor will be created. Otherwise, + *fd* must be a file descriptor previously returned by this function. + + *mask* is a list of signal numbers which will trigger data on this file + descriptor. + + *flags* is a bit mask which may include any :const:`signal.SFD_*` flag. + + .. versionadded:: 2.7 + + +.. function:: sigprocmask(how, mask) + + Set the signal mask for the process. The old signal mask is returned. + Availability: Unix (See the Unix man page :manpage:`sigprocmask(2)` and + :manpage:`pthread_sigmask(2)`.) + + If *how* is :const:`signal.SIG_BLOCK`, the signals in the mask are added + to the set of blocked signals. + + If *how* is :const:`signal.SIG_UNBLOCK`, the signals in the mask are + removed from the set of blocked signals. + + If *how* is :const:`signal.SIG_SETMASK`, the signals in the mask are set + as blocked and the signals not in the mask are set as unblocked. + + *mask* is a list of signal numbers (eg :const:`signal.SIGUSR1`). + + .. versionadded:: 2.7 + + .. _signal-example: Example Modified: python/branches/py3k/Lib/test/test_signal.py ============================================================================== --- python/branches/py3k/Lib/test/test_signal.py (original) +++ python/branches/py3k/Lib/test/test_signal.py Sat Jun 19 21:54:48 2010 @@ -462,9 +462,210 @@ # and the handler should have been called self.assertEqual(self.hndl_called, True) + + +class SomeException(Exception): + """ + A unique exception class to be raised by a signal handler to verify that the + signal handler was invoked. + """ + + + +def raiser(*args): + """A signal handler which raises SomeException.""" + raise SomeException() + + + +class SigprocmaskTests(unittest.TestCase): + """Tests for sigprocmask.""" + def _handle_sigusr1(self): + old_handler = signal.signal(signal.SIGUSR1, raiser) + self.addCleanup(signal.signal, signal.SIGUSR1, old_handler) + + + def test_signature(self): + """When invoked with other than two arguments, sigprocmask raises + TypeError. + """ + self.assertRaises(TypeError, signal.sigprocmask) + self.assertRaises(TypeError, signal.sigprocmask, 1) + self.assertRaises(TypeError, signal.sigprocmask, 1, 2, 3) + + + def test_invalid_how(self): + """If a value other than SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK is + passed for the how argument to sigprocmask, ValueError is raised. + """ + message = "value specified for how \(1700\) invalid" + with self.assertRaisesRegexp(ValueError, message): + signal.sigprocmask(1700, []) + + + def test_invalid_signal_iterable(self): + """If iterating over the value passed for the signals parameter to + sigprocmask raises an exception, sigprocmask raises that exception. + """ + class BrokenIter(object): + def __iter__(self): + raise RuntimeError("my __iter__ is broken") + with self.assertRaisesRegexp(RuntimeError, "my __iter__ is broken"): + signal.sigprocmask(signal.SIG_BLOCK, BrokenIter()) + + + def test_invalid_signal(self): + """If an object in the iterable passed for the signals parameter to + sigprocmask isn't an integer, TypeError is raised.""" + with self.assertRaisesRegexp(TypeError, "an integer is required"): + signal.sigprocmask(signal.SIG_BLOCK, [object()]) + + + def test_return_previous_mask(self): + """sigprocmask returns a list of the signals previously masked. + """ + previous = signal.sigprocmask(signal.SIG_BLOCK, [1, 3, 5]) + result = signal.sigprocmask(signal.SIG_BLOCK, previous) + self.assertEquals(result, [1, 3, 5]) + + + def test_block(self): + """When invoked with SIG_BLOCK, sigprocmask blocks the signals in the + sigmask list. + """ + self._handle_sigusr1() + previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1]) + os.kill(os.getpid(), signal.SIGUSR1) + with self.assertRaises(SomeException): + # Expect to receive SIGUSR1 after unblocking it. + signal.sigprocmask(signal.SIG_SETMASK, previous) + + + def test_unblock(self): + """When invoked with SIG_UNBLOCK, sigprocmask unblocks the signals in + the sigmask list. + """ + self._handle_sigusr1() + previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1]) + self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, previous) + signal.sigprocmask(signal.SIG_UNBLOCK, [signal.SIGUSR1]) + + with self.assertRaises(SomeException): + os.kill(os.getpid(), signal.SIGUSR1) + + + def test_long_signals(self): + """sigprocmask accepts signal numbers as instances of long.""" + previous = signal.sigprocmask( + signal.SIG_SETMASK, [long(signal.SIGUSR1), long(signal.SIGUSR2)]) + masked = signal.sigprocmask(signal.SIG_SETMASK, previous) + self.assertEquals(masked, [signal.SIGUSR1, signal.SIGUSR2]) + + + +class SignalfdTests(unittest.TestCase): + """ + Tests for signal.signalfd. + """ + def test_signature(self): + """When invoked with fewer than two arguments or more than three, + signalfd raises TypeError. + """ + self.assertRaises(TypeError, signal.signalfd) + self.assertRaises(TypeError, signal.signalfd, 1) + self.assertRaises(TypeError, signal.signalfd, 1, 2, 3, 4) + + + def test_create_signalfd(self): + """When invoked with a file descriptor of -1, signalfd allocates a new + file descriptor for signal information delivery and returns it. + """ + fd = signal.signalfd(-1, []) + self.assertTrue(isinstance(fd, int)) + os.close(fd) + + + def test_non_iterable_signals(self): + """If an object which is not iterable is passed for the sigmask list + argument to signalfd, the exception raised by trying to iterate over + that object is raised. + """ + self.assertRaises(TypeError, signal.signalfd, -1, object()) + + + def test_non_integer_signals(self): + """If any non-integer values are included in the sigmask list argument + to signalfd, the exception raised by the attempt to convert them to an + integer is raised. + """ + self.assertRaises(TypeError, signal.signalfd, -1, [object()]) + + + def test_out_of_range_signal(self): + """If a signal number that is out of the valid range is included in the + sigmask list argument to signalfd, ValueError is raised. + """ + message = "signal number -2 out of range" + with self.assertRaisesRegexp(ValueError, message): + signal.signalfd(-1, [-2]) + + + def test_handle_signals(self): + """After signalfd is called, if a signal is received which was in the + sigmask list passed to that call, information about the signal can be + read from the fd returned by that call. + """ + fd = signal.signalfd(-1, [signal.SIGUSR2]) + self.addCleanup(os.close, fd) + previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR2]) + self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, previous) + os.kill(os.getpid(), signal.SIGUSR2) + bytes = os.read(fd, 128) + self.assertTrue(bytes) + + + def test_close_on_exec(self): + """If the bit mask passed as the 3rd argument to signalfd includes + SFD_CLOEXEC, the returned file descriptor has FD_CLOEXEC set on it. + """ + import fcntl + fd = signal.signalfd(-1, [], signal.SFD_CLOEXEC) + self.addCleanup(os.close, fd) + flags = fcntl.fcntl(fd, fcntl.F_GETFD) + self.assertTrue(flags & fcntl.FD_CLOEXEC) + + + def test_nonblocking(self): + """If the bit mask passed as the 3rd argument to signalfd includes + SFD_NOBLOCK, the file description referenced by the returned file + descriptor has O_NONBLOCK set on it. + """ + import fcntl + fd = signal.signalfd(-1, [], signal.SFD_NONBLOCK) + self.addCleanup(os.close, fd) + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + self.assertTrue(flags & os.O_NONBLOCK) + + + def test_default_flags(self): + """If an empty bit mask is passed as the 3rd argument to signalfd, + neither FD_CLOEXEC nor O_NONBLOCK is set on the resulting file + descriptor/description. + """ + import fcntl + fd = signal.signalfd(-1, []) + self.addCleanup(os.close, fd) + flags = fcntl.fcntl(fd, fcntl.F_GETFD) + self.assertFalse(flags & fcntl.FD_CLOEXEC) + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + self.assertFalse(flags & os.O_NONBLOCK) + + def test_main(): - support.run_unittest(BasicSignalTests, InterProcessSignalTests, - WakeupSignalTests, SiginterruptTest, ItimerTest) + support.run_unittest( + BasicSignalTests, InterProcessSignalTests, + WakeupSignalTests, SiginterruptTest, ItimerTest, SignalfdTests, + SigprocmaskTests) if __name__ == "__main__": Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jun 19 21:54:48 2010 @@ -1025,6 +1025,11 @@ - Issue #5949: added check for correct lineends in input from IMAP server in imaplib. +- Issue #8407: The signal module gains the ``signalfd()`` and + ``sigprocmask(2)`` functions providing access to the signalfd(2) and + sigprocmask(2) system calls respectively on Linux systems which implement + them. + - Add count() and reverse() methods to collections.deque(). - Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d Modified: python/branches/py3k/Modules/signalmodule.c ============================================================================== --- python/branches/py3k/Modules/signalmodule.c (original) +++ python/branches/py3k/Modules/signalmodule.c Sat Jun 19 21:54:48 2010 @@ -22,6 +22,10 @@ #ifdef HAVE_SYS_TIME_H #include #endif +#ifdef HAVE_SIGNALFD +#include +#endif + #ifndef SIG_ERR #define SIG_ERR ((PyOS_sighandler_t)(-1)) @@ -464,6 +468,144 @@ #endif +static int +_iterable_to_mask(PyObject *iterable, sigset_t *mask) +{ + static const char* range_format = "signal number %d out of range"; + char range_buffer[1024]; + int result = 0; + + PyObject *item, *iterator = NULL; + + sigemptyset(mask); + + iterator = PyObject_GetIter(iterable); + if (iterator == NULL) { + result = -1; + goto error; + } + + while ((item = PyIter_Next(iterator))) { + int signum = PyInt_AsLong(item); + Py_DECREF(item); + if (signum == -1 && PyErr_Occurred()) { + result = -1; + goto error; + } + if (sigaddset(mask, signum) == -1) { + PyOS_snprintf(range_buffer, sizeof(range_buffer), range_format, signum); + PyErr_SetString(PyExc_ValueError, range_buffer); + result = -1; + goto error; + } + } + +error: + Py_XDECREF(iterator); + return result; +} + +#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) +# define PY_SIGMASK pthread_sigmask +#elif defined(HAVE_SIGPROCMASK) +# define PY_SIGMASK sigprocmask +#endif + +#ifdef PY_SIGMASK +static PyObject * +signal_sigprocmask(PyObject *self, PyObject *args) +{ + static const char* how_format = "value specified for how (%d) invalid"; + char how_buffer[1024]; + + int how, sig; + PyObject *signals, *result, *signum; + sigset_t mask, previous; + + if (!PyArg_ParseTuple(args, "iO:sigprocmask", &how, &signals)) { + return NULL; + } + + if (_iterable_to_mask(signals, &mask) == -1) { + return NULL; + } + + if (PY_SIGMASK(how, &mask, &previous) != 0) { + PyOS_snprintf(how_buffer, sizeof(how_buffer), how_format, how); + PyErr_SetString(PyExc_ValueError, how_buffer); + return NULL; + } + + result = PyList_New(0); + if (result == NULL) { + return NULL; + } + + for (sig = 1; sig < NSIG; ++sig) { + if (sigismember(&previous, sig) == 1) { + /* Handle the case where it is a member by adding the signal to + the result list. Ignore the other cases because they mean the + signal isn't a member of the mask or the signal was invalid, + and an invalid signal must have been our fault in constructing + the loop boundaries. */ + signum = PyInt_FromLong(sig); + if (signum == NULL) { + Py_DECREF(result); + return NULL; + } + if (PyList_Append(result, signum) == -1) { + Py_DECREF(signum); + Py_DECREF(result); + return NULL; + } + Py_DECREF(signum); + } + } + return result; +} + +PyDoc_STRVAR(sigprocmask_doc, +"sigprocmask(how, mask) -> old mask\n\ +\n\ +Examine and change blocked signals."); +#endif + +#ifdef HAVE_SIGNALFD +static PyObject * +signal_signalfd(PyObject *self, PyObject *args) +{ + int result, flags = 0; + sigset_t mask; + + int fd; + PyObject *signals; + + if (!PyArg_ParseTuple(args, "iO|i:signalfd", &fd, &signals, &flags)) { + return NULL; + } + + if (_iterable_to_mask(signals, &mask) == -1) { + return NULL; + } + + result = signalfd(-1, &mask, flags); + + if (result == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + return PyInt_FromLong(result); +} + +PyDoc_STRVAR(signalfd_doc, +"signalfd(fd, mask, flags)\n\ +\n\ +Create a file descriptor for accepting signals."); + +#endif + + /* List of functions defined in the module */ static PyMethodDef signal_methods[] = { #ifdef HAVE_ALARM @@ -478,6 +620,14 @@ {"signal", signal_signal, METH_VARARGS, signal_doc}, {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, +#ifdef PY_SIGMASK + {"sigprocmask", signal_sigprocmask, METH_VARARGS, sigprocmask_doc}, +/* It's no longer needed, so clean up the namespace. */ +#undef PY_SIGMASK +#endif +#ifdef HAVE_SIGNALFD + {"signalfd", signal_signalfd, METH_VARARGS, signalfd_doc}, +#endif #ifdef HAVE_SIGINTERRUPT {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc}, #endif @@ -811,6 +961,36 @@ PyDict_SetItemString(d, "ItimerError", ItimerError); #endif +#ifdef SIG_BLOCK + x = PyLong_FromLong(SIG_BLOCK); + PyDict_SetItemString(d, "SIG_BLOCK", x); + Py_DECREF(x); +#endif + +#ifdef SIG_UNBLOCK + x = PyLong_FromLong(SIG_UNBLOCK); + PyDict_SetItemString(d, "SIG_UNBLOCK", x); + Py_DECREF(x); +#endif + +#ifdef SIG_SETMASK + x = PyLong_FromLong(SIG_SETMASK); + PyDict_SetItemString(d, "SIG_SETMASK", x); + Py_DECREF(x); +#endif + +#ifdef SFD_CLOEXEC + x = PyLong_FromLong(SFD_CLOEXEC); + PyDict_SetItemString(d, "SFD_CLOEXEC", x); + Py_DECREF(x); +#endif + +#ifdef SFD_NONBLOCK + x = PyLong_FromLong(SFD_NONBLOCK); + PyDict_SetItemString(d, "SFD_NONBLOCK", x); + Py_DECREF(x); +#endif + #ifdef CTRL_C_EVENT x = PyLong_FromLong(CTRL_C_EVENT); PyDict_SetItemString(d, "CTRL_C_EVENT", x); Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sat Jun 19 21:54:48 2010 @@ -9297,7 +9297,7 @@ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ - sigaction siginterrupt sigrelse snprintf strftime strlcpy \ + sigaction siginterrupt signalfd sigprocmask sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm _getpty Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sat Jun 19 21:54:48 2010 @@ -2580,7 +2580,7 @@ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ - sigaction siginterrupt sigrelse snprintf strftime strlcpy \ + sigaction siginterrupt signalfd sigprocmask sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm _getpty) Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Sat Jun 19 21:54:48 2010 @@ -620,6 +620,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H +/* Define to 1 if you have the `signalfd' function. */ +#undef HAVE_SIGNALFD + +/* Define to 1 if you have the `sigprocmask' function. */ +#undef HAVE_SIGPROCMASK + /* Define to 1 if you have the `sigrelse' function. */ #undef HAVE_SIGRELSE From python-checkins at python.org Sat Jun 19 21:58:37 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 21:58:37 +0200 (CEST) Subject: [Python-checkins] r82090 - in python/branches/py3k: Doc/library/signal.rst Lib/test/test_signal.py Misc/NEWS Modules/signalmodule.c configure configure.in pyconfig.h.in Message-ID: <20100619195837.97C0BEE9A0@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 21:58:37 2010 New Revision: 82090 Log: Revert r82089. Commit was intended for a branch. Modified: python/branches/py3k/Doc/library/signal.rst python/branches/py3k/Lib/test/test_signal.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/signalmodule.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/Doc/library/signal.rst ============================================================================== --- python/branches/py3k/Doc/library/signal.rst (original) +++ python/branches/py3k/Doc/library/signal.rst Sat Jun 19 21:58:37 2010 @@ -13,6 +13,9 @@ underlying implementation), with the exception of the handler for :const:`SIGCHLD`, which follows the underlying implementation. +* There is no way to "block" signals temporarily from critical sections (since + this is not supported by all Unix flavors). + * Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the "atomic" instructions of the Python interpreter. This means that signals arriving during long calculations @@ -112,46 +115,6 @@ in user and kernel space. SIGPROF is delivered upon expiration. -.. data:: SIG_BLOCK - - A possible value for the *how* parameter to :func:`sigprocmask` - indicating that signals are to be blocked. - - .. versionadded:: 2.7 - - -.. data:: SIG_UNBLOCK - - A possible value for the *how* parameter to :func:`sigprocmask` - indicating that signals are to be unblocked. - - .. versionadded:: 2.7 - - -.. data:: SIG_SETMASK - - A possible value for the *how* parameter to :func:`sigprocmask` - indicating that the signal mask is to be replaced. - - .. versionadded:: 2.7 - - -.. data:: SFD_CLOEXEC - - A possible flag in the *flags* parameter to :func:`signalfd` which causes - the new file descriptor to be marked as close-on-exec. - - .. versionadded:: 2.7 - - -.. data:: SFD_NONBLOCK - - A possible flag in the *flags* parameter to :func:`signalfd` which causes - the new file description to be set non-blocking. - - .. versionadded:: 2.7 - - The :mod:`signal` module defines one exception: .. exception:: ItimerError @@ -264,44 +227,6 @@ attribute descriptions in the :mod:`inspect` module). -.. function:: signalfd(fd, mask[, flags]) - - Create a new file descriptor on which to receive signals or modify the - mask of such a file descriptor previously created by this function. - Availability: Linux (See the manpage :manpage:`signalfd(2)` for further - information). - - If *fd* is ``-1``, a new file descriptor will be created. Otherwise, - *fd* must be a file descriptor previously returned by this function. - - *mask* is a list of signal numbers which will trigger data on this file - descriptor. - - *flags* is a bit mask which may include any :const:`signal.SFD_*` flag. - - .. versionadded:: 2.7 - - -.. function:: sigprocmask(how, mask) - - Set the signal mask for the process. The old signal mask is returned. - Availability: Unix (See the Unix man page :manpage:`sigprocmask(2)` and - :manpage:`pthread_sigmask(2)`.) - - If *how* is :const:`signal.SIG_BLOCK`, the signals in the mask are added - to the set of blocked signals. - - If *how* is :const:`signal.SIG_UNBLOCK`, the signals in the mask are - removed from the set of blocked signals. - - If *how* is :const:`signal.SIG_SETMASK`, the signals in the mask are set - as blocked and the signals not in the mask are set as unblocked. - - *mask* is a list of signal numbers (eg :const:`signal.SIGUSR1`). - - .. versionadded:: 2.7 - - .. _signal-example: Example Modified: python/branches/py3k/Lib/test/test_signal.py ============================================================================== --- python/branches/py3k/Lib/test/test_signal.py (original) +++ python/branches/py3k/Lib/test/test_signal.py Sat Jun 19 21:58:37 2010 @@ -462,210 +462,9 @@ # and the handler should have been called self.assertEqual(self.hndl_called, True) - - -class SomeException(Exception): - """ - A unique exception class to be raised by a signal handler to verify that the - signal handler was invoked. - """ - - - -def raiser(*args): - """A signal handler which raises SomeException.""" - raise SomeException() - - - -class SigprocmaskTests(unittest.TestCase): - """Tests for sigprocmask.""" - def _handle_sigusr1(self): - old_handler = signal.signal(signal.SIGUSR1, raiser) - self.addCleanup(signal.signal, signal.SIGUSR1, old_handler) - - - def test_signature(self): - """When invoked with other than two arguments, sigprocmask raises - TypeError. - """ - self.assertRaises(TypeError, signal.sigprocmask) - self.assertRaises(TypeError, signal.sigprocmask, 1) - self.assertRaises(TypeError, signal.sigprocmask, 1, 2, 3) - - - def test_invalid_how(self): - """If a value other than SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK is - passed for the how argument to sigprocmask, ValueError is raised. - """ - message = "value specified for how \(1700\) invalid" - with self.assertRaisesRegexp(ValueError, message): - signal.sigprocmask(1700, []) - - - def test_invalid_signal_iterable(self): - """If iterating over the value passed for the signals parameter to - sigprocmask raises an exception, sigprocmask raises that exception. - """ - class BrokenIter(object): - def __iter__(self): - raise RuntimeError("my __iter__ is broken") - with self.assertRaisesRegexp(RuntimeError, "my __iter__ is broken"): - signal.sigprocmask(signal.SIG_BLOCK, BrokenIter()) - - - def test_invalid_signal(self): - """If an object in the iterable passed for the signals parameter to - sigprocmask isn't an integer, TypeError is raised.""" - with self.assertRaisesRegexp(TypeError, "an integer is required"): - signal.sigprocmask(signal.SIG_BLOCK, [object()]) - - - def test_return_previous_mask(self): - """sigprocmask returns a list of the signals previously masked. - """ - previous = signal.sigprocmask(signal.SIG_BLOCK, [1, 3, 5]) - result = signal.sigprocmask(signal.SIG_BLOCK, previous) - self.assertEquals(result, [1, 3, 5]) - - - def test_block(self): - """When invoked with SIG_BLOCK, sigprocmask blocks the signals in the - sigmask list. - """ - self._handle_sigusr1() - previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1]) - os.kill(os.getpid(), signal.SIGUSR1) - with self.assertRaises(SomeException): - # Expect to receive SIGUSR1 after unblocking it. - signal.sigprocmask(signal.SIG_SETMASK, previous) - - - def test_unblock(self): - """When invoked with SIG_UNBLOCK, sigprocmask unblocks the signals in - the sigmask list. - """ - self._handle_sigusr1() - previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1]) - self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, previous) - signal.sigprocmask(signal.SIG_UNBLOCK, [signal.SIGUSR1]) - - with self.assertRaises(SomeException): - os.kill(os.getpid(), signal.SIGUSR1) - - - def test_long_signals(self): - """sigprocmask accepts signal numbers as instances of long.""" - previous = signal.sigprocmask( - signal.SIG_SETMASK, [long(signal.SIGUSR1), long(signal.SIGUSR2)]) - masked = signal.sigprocmask(signal.SIG_SETMASK, previous) - self.assertEquals(masked, [signal.SIGUSR1, signal.SIGUSR2]) - - - -class SignalfdTests(unittest.TestCase): - """ - Tests for signal.signalfd. - """ - def test_signature(self): - """When invoked with fewer than two arguments or more than three, - signalfd raises TypeError. - """ - self.assertRaises(TypeError, signal.signalfd) - self.assertRaises(TypeError, signal.signalfd, 1) - self.assertRaises(TypeError, signal.signalfd, 1, 2, 3, 4) - - - def test_create_signalfd(self): - """When invoked with a file descriptor of -1, signalfd allocates a new - file descriptor for signal information delivery and returns it. - """ - fd = signal.signalfd(-1, []) - self.assertTrue(isinstance(fd, int)) - os.close(fd) - - - def test_non_iterable_signals(self): - """If an object which is not iterable is passed for the sigmask list - argument to signalfd, the exception raised by trying to iterate over - that object is raised. - """ - self.assertRaises(TypeError, signal.signalfd, -1, object()) - - - def test_non_integer_signals(self): - """If any non-integer values are included in the sigmask list argument - to signalfd, the exception raised by the attempt to convert them to an - integer is raised. - """ - self.assertRaises(TypeError, signal.signalfd, -1, [object()]) - - - def test_out_of_range_signal(self): - """If a signal number that is out of the valid range is included in the - sigmask list argument to signalfd, ValueError is raised. - """ - message = "signal number -2 out of range" - with self.assertRaisesRegexp(ValueError, message): - signal.signalfd(-1, [-2]) - - - def test_handle_signals(self): - """After signalfd is called, if a signal is received which was in the - sigmask list passed to that call, information about the signal can be - read from the fd returned by that call. - """ - fd = signal.signalfd(-1, [signal.SIGUSR2]) - self.addCleanup(os.close, fd) - previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR2]) - self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, previous) - os.kill(os.getpid(), signal.SIGUSR2) - bytes = os.read(fd, 128) - self.assertTrue(bytes) - - - def test_close_on_exec(self): - """If the bit mask passed as the 3rd argument to signalfd includes - SFD_CLOEXEC, the returned file descriptor has FD_CLOEXEC set on it. - """ - import fcntl - fd = signal.signalfd(-1, [], signal.SFD_CLOEXEC) - self.addCleanup(os.close, fd) - flags = fcntl.fcntl(fd, fcntl.F_GETFD) - self.assertTrue(flags & fcntl.FD_CLOEXEC) - - - def test_nonblocking(self): - """If the bit mask passed as the 3rd argument to signalfd includes - SFD_NOBLOCK, the file description referenced by the returned file - descriptor has O_NONBLOCK set on it. - """ - import fcntl - fd = signal.signalfd(-1, [], signal.SFD_NONBLOCK) - self.addCleanup(os.close, fd) - flags = fcntl.fcntl(fd, fcntl.F_GETFL) - self.assertTrue(flags & os.O_NONBLOCK) - - - def test_default_flags(self): - """If an empty bit mask is passed as the 3rd argument to signalfd, - neither FD_CLOEXEC nor O_NONBLOCK is set on the resulting file - descriptor/description. - """ - import fcntl - fd = signal.signalfd(-1, []) - self.addCleanup(os.close, fd) - flags = fcntl.fcntl(fd, fcntl.F_GETFD) - self.assertFalse(flags & fcntl.FD_CLOEXEC) - flags = fcntl.fcntl(fd, fcntl.F_GETFL) - self.assertFalse(flags & os.O_NONBLOCK) - - def test_main(): - support.run_unittest( - BasicSignalTests, InterProcessSignalTests, - WakeupSignalTests, SiginterruptTest, ItimerTest, SignalfdTests, - SigprocmaskTests) + support.run_unittest(BasicSignalTests, InterProcessSignalTests, + WakeupSignalTests, SiginterruptTest, ItimerTest) if __name__ == "__main__": Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Jun 19 21:58:37 2010 @@ -1025,11 +1025,6 @@ - Issue #5949: added check for correct lineends in input from IMAP server in imaplib. -- Issue #8407: The signal module gains the ``signalfd()`` and - ``sigprocmask(2)`` functions providing access to the signalfd(2) and - sigprocmask(2) system calls respectively on Linux systems which implement - them. - - Add count() and reverse() methods to collections.deque(). - Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d Modified: python/branches/py3k/Modules/signalmodule.c ============================================================================== --- python/branches/py3k/Modules/signalmodule.c (original) +++ python/branches/py3k/Modules/signalmodule.c Sat Jun 19 21:58:37 2010 @@ -22,10 +22,6 @@ #ifdef HAVE_SYS_TIME_H #include #endif -#ifdef HAVE_SIGNALFD -#include -#endif - #ifndef SIG_ERR #define SIG_ERR ((PyOS_sighandler_t)(-1)) @@ -468,144 +464,6 @@ #endif -static int -_iterable_to_mask(PyObject *iterable, sigset_t *mask) -{ - static const char* range_format = "signal number %d out of range"; - char range_buffer[1024]; - int result = 0; - - PyObject *item, *iterator = NULL; - - sigemptyset(mask); - - iterator = PyObject_GetIter(iterable); - if (iterator == NULL) { - result = -1; - goto error; - } - - while ((item = PyIter_Next(iterator))) { - int signum = PyInt_AsLong(item); - Py_DECREF(item); - if (signum == -1 && PyErr_Occurred()) { - result = -1; - goto error; - } - if (sigaddset(mask, signum) == -1) { - PyOS_snprintf(range_buffer, sizeof(range_buffer), range_format, signum); - PyErr_SetString(PyExc_ValueError, range_buffer); - result = -1; - goto error; - } - } - -error: - Py_XDECREF(iterator); - return result; -} - -#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) -# define PY_SIGMASK pthread_sigmask -#elif defined(HAVE_SIGPROCMASK) -# define PY_SIGMASK sigprocmask -#endif - -#ifdef PY_SIGMASK -static PyObject * -signal_sigprocmask(PyObject *self, PyObject *args) -{ - static const char* how_format = "value specified for how (%d) invalid"; - char how_buffer[1024]; - - int how, sig; - PyObject *signals, *result, *signum; - sigset_t mask, previous; - - if (!PyArg_ParseTuple(args, "iO:sigprocmask", &how, &signals)) { - return NULL; - } - - if (_iterable_to_mask(signals, &mask) == -1) { - return NULL; - } - - if (PY_SIGMASK(how, &mask, &previous) != 0) { - PyOS_snprintf(how_buffer, sizeof(how_buffer), how_format, how); - PyErr_SetString(PyExc_ValueError, how_buffer); - return NULL; - } - - result = PyList_New(0); - if (result == NULL) { - return NULL; - } - - for (sig = 1; sig < NSIG; ++sig) { - if (sigismember(&previous, sig) == 1) { - /* Handle the case where it is a member by adding the signal to - the result list. Ignore the other cases because they mean the - signal isn't a member of the mask or the signal was invalid, - and an invalid signal must have been our fault in constructing - the loop boundaries. */ - signum = PyInt_FromLong(sig); - if (signum == NULL) { - Py_DECREF(result); - return NULL; - } - if (PyList_Append(result, signum) == -1) { - Py_DECREF(signum); - Py_DECREF(result); - return NULL; - } - Py_DECREF(signum); - } - } - return result; -} - -PyDoc_STRVAR(sigprocmask_doc, -"sigprocmask(how, mask) -> old mask\n\ -\n\ -Examine and change blocked signals."); -#endif - -#ifdef HAVE_SIGNALFD -static PyObject * -signal_signalfd(PyObject *self, PyObject *args) -{ - int result, flags = 0; - sigset_t mask; - - int fd; - PyObject *signals; - - if (!PyArg_ParseTuple(args, "iO|i:signalfd", &fd, &signals, &flags)) { - return NULL; - } - - if (_iterable_to_mask(signals, &mask) == -1) { - return NULL; - } - - result = signalfd(-1, &mask, flags); - - if (result == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - return PyInt_FromLong(result); -} - -PyDoc_STRVAR(signalfd_doc, -"signalfd(fd, mask, flags)\n\ -\n\ -Create a file descriptor for accepting signals."); - -#endif - - /* List of functions defined in the module */ static PyMethodDef signal_methods[] = { #ifdef HAVE_ALARM @@ -620,14 +478,6 @@ {"signal", signal_signal, METH_VARARGS, signal_doc}, {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, -#ifdef PY_SIGMASK - {"sigprocmask", signal_sigprocmask, METH_VARARGS, sigprocmask_doc}, -/* It's no longer needed, so clean up the namespace. */ -#undef PY_SIGMASK -#endif -#ifdef HAVE_SIGNALFD - {"signalfd", signal_signalfd, METH_VARARGS, signalfd_doc}, -#endif #ifdef HAVE_SIGINTERRUPT {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc}, #endif @@ -961,36 +811,6 @@ PyDict_SetItemString(d, "ItimerError", ItimerError); #endif -#ifdef SIG_BLOCK - x = PyLong_FromLong(SIG_BLOCK); - PyDict_SetItemString(d, "SIG_BLOCK", x); - Py_DECREF(x); -#endif - -#ifdef SIG_UNBLOCK - x = PyLong_FromLong(SIG_UNBLOCK); - PyDict_SetItemString(d, "SIG_UNBLOCK", x); - Py_DECREF(x); -#endif - -#ifdef SIG_SETMASK - x = PyLong_FromLong(SIG_SETMASK); - PyDict_SetItemString(d, "SIG_SETMASK", x); - Py_DECREF(x); -#endif - -#ifdef SFD_CLOEXEC - x = PyLong_FromLong(SFD_CLOEXEC); - PyDict_SetItemString(d, "SFD_CLOEXEC", x); - Py_DECREF(x); -#endif - -#ifdef SFD_NONBLOCK - x = PyLong_FromLong(SFD_NONBLOCK); - PyDict_SetItemString(d, "SFD_NONBLOCK", x); - Py_DECREF(x); -#endif - #ifdef CTRL_C_EVENT x = PyLong_FromLong(CTRL_C_EVENT); PyDict_SetItemString(d, "CTRL_C_EVENT", x); Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sat Jun 19 21:58:37 2010 @@ -9297,7 +9297,7 @@ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ - sigaction siginterrupt signalfd sigprocmask sigrelse snprintf strftime strlcpy \ + sigaction siginterrupt sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm _getpty Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sat Jun 19 21:58:37 2010 @@ -2580,7 +2580,7 @@ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ - sigaction siginterrupt signalfd sigprocmask sigrelse snprintf strftime strlcpy \ + sigaction siginterrupt sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm _getpty) Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Sat Jun 19 21:58:37 2010 @@ -620,12 +620,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H -/* Define to 1 if you have the `signalfd' function. */ -#undef HAVE_SIGNALFD - -/* Define to 1 if you have the `sigprocmask' function. */ -#undef HAVE_SIGPROCMASK - /* Define to 1 if you have the `sigrelse' function. */ #undef HAVE_SIGRELSE From python-checkins at python.org Sat Jun 19 21:59:45 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 21:59:45 +0200 (CEST) Subject: [Python-checkins] r82091 - in python/branches/py3k-signalfd-issue8407: Doc/library/signal.rst Lib/test/test_signal.py Misc/NEWS Modules/signalmodule.c configure configure.in pyconfig.h.in Message-ID: <20100619195945.02A64EE986@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 21:59:44 2010 New Revision: 82091 Log: merge forward from the python 2.x branch Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py python/branches/py3k-signalfd-issue8407/Misc/NEWS python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c python/branches/py3k-signalfd-issue8407/configure python/branches/py3k-signalfd-issue8407/configure.in python/branches/py3k-signalfd-issue8407/pyconfig.h.in Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Sat Jun 19 21:59:44 2010 @@ -13,9 +13,6 @@ underlying implementation), with the exception of the handler for :const:`SIGCHLD`, which follows the underlying implementation. -* There is no way to "block" signals temporarily from critical sections (since - this is not supported by all Unix flavors). - * Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the "atomic" instructions of the Python interpreter. This means that signals arriving during long calculations @@ -115,6 +112,46 @@ in user and kernel space. SIGPROF is delivered upon expiration. +.. data:: SIG_BLOCK + + A possible value for the *how* parameter to :func:`sigprocmask` + indicating that signals are to be blocked. + + .. versionadded:: 2.7 + + +.. data:: SIG_UNBLOCK + + A possible value for the *how* parameter to :func:`sigprocmask` + indicating that signals are to be unblocked. + + .. versionadded:: 2.7 + + +.. data:: SIG_SETMASK + + A possible value for the *how* parameter to :func:`sigprocmask` + indicating that the signal mask is to be replaced. + + .. versionadded:: 2.7 + + +.. data:: SFD_CLOEXEC + + A possible flag in the *flags* parameter to :func:`signalfd` which causes + the new file descriptor to be marked as close-on-exec. + + .. versionadded:: 2.7 + + +.. data:: SFD_NONBLOCK + + A possible flag in the *flags* parameter to :func:`signalfd` which causes + the new file description to be set non-blocking. + + .. versionadded:: 2.7 + + The :mod:`signal` module defines one exception: .. exception:: ItimerError @@ -227,6 +264,44 @@ attribute descriptions in the :mod:`inspect` module). +.. function:: signalfd(fd, mask[, flags]) + + Create a new file descriptor on which to receive signals or modify the + mask of such a file descriptor previously created by this function. + Availability: Linux (See the manpage :manpage:`signalfd(2)` for further + information). + + If *fd* is ``-1``, a new file descriptor will be created. Otherwise, + *fd* must be a file descriptor previously returned by this function. + + *mask* is a list of signal numbers which will trigger data on this file + descriptor. + + *flags* is a bit mask which may include any :const:`signal.SFD_*` flag. + + .. versionadded:: 2.7 + + +.. function:: sigprocmask(how, mask) + + Set the signal mask for the process. The old signal mask is returned. + Availability: Unix (See the Unix man page :manpage:`sigprocmask(2)` and + :manpage:`pthread_sigmask(2)`.) + + If *how* is :const:`signal.SIG_BLOCK`, the signals in the mask are added + to the set of blocked signals. + + If *how* is :const:`signal.SIG_UNBLOCK`, the signals in the mask are + removed from the set of blocked signals. + + If *how* is :const:`signal.SIG_SETMASK`, the signals in the mask are set + as blocked and the signals not in the mask are set as unblocked. + + *mask* is a list of signal numbers (eg :const:`signal.SIGUSR1`). + + .. versionadded:: 2.7 + + .. _signal-example: Example Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py ============================================================================== --- python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py (original) +++ python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Sat Jun 19 21:59:44 2010 @@ -462,9 +462,210 @@ # and the handler should have been called self.assertEqual(self.hndl_called, True) + + +class SomeException(Exception): + """ + A unique exception class to be raised by a signal handler to verify that the + signal handler was invoked. + """ + + + +def raiser(*args): + """A signal handler which raises SomeException.""" + raise SomeException() + + + +class SigprocmaskTests(unittest.TestCase): + """Tests for sigprocmask.""" + def _handle_sigusr1(self): + old_handler = signal.signal(signal.SIGUSR1, raiser) + self.addCleanup(signal.signal, signal.SIGUSR1, old_handler) + + + def test_signature(self): + """When invoked with other than two arguments, sigprocmask raises + TypeError. + """ + self.assertRaises(TypeError, signal.sigprocmask) + self.assertRaises(TypeError, signal.sigprocmask, 1) + self.assertRaises(TypeError, signal.sigprocmask, 1, 2, 3) + + + def test_invalid_how(self): + """If a value other than SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK is + passed for the how argument to sigprocmask, ValueError is raised. + """ + message = "value specified for how \(1700\) invalid" + with self.assertRaisesRegexp(ValueError, message): + signal.sigprocmask(1700, []) + + + def test_invalid_signal_iterable(self): + """If iterating over the value passed for the signals parameter to + sigprocmask raises an exception, sigprocmask raises that exception. + """ + class BrokenIter(object): + def __iter__(self): + raise RuntimeError("my __iter__ is broken") + with self.assertRaisesRegexp(RuntimeError, "my __iter__ is broken"): + signal.sigprocmask(signal.SIG_BLOCK, BrokenIter()) + + + def test_invalid_signal(self): + """If an object in the iterable passed for the signals parameter to + sigprocmask isn't an integer, TypeError is raised.""" + with self.assertRaisesRegexp(TypeError, "an integer is required"): + signal.sigprocmask(signal.SIG_BLOCK, [object()]) + + + def test_return_previous_mask(self): + """sigprocmask returns a list of the signals previously masked. + """ + previous = signal.sigprocmask(signal.SIG_BLOCK, [1, 3, 5]) + result = signal.sigprocmask(signal.SIG_BLOCK, previous) + self.assertEquals(result, [1, 3, 5]) + + + def test_block(self): + """When invoked with SIG_BLOCK, sigprocmask blocks the signals in the + sigmask list. + """ + self._handle_sigusr1() + previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1]) + os.kill(os.getpid(), signal.SIGUSR1) + with self.assertRaises(SomeException): + # Expect to receive SIGUSR1 after unblocking it. + signal.sigprocmask(signal.SIG_SETMASK, previous) + + + def test_unblock(self): + """When invoked with SIG_UNBLOCK, sigprocmask unblocks the signals in + the sigmask list. + """ + self._handle_sigusr1() + previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1]) + self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, previous) + signal.sigprocmask(signal.SIG_UNBLOCK, [signal.SIGUSR1]) + + with self.assertRaises(SomeException): + os.kill(os.getpid(), signal.SIGUSR1) + + + def test_long_signals(self): + """sigprocmask accepts signal numbers as instances of long.""" + previous = signal.sigprocmask( + signal.SIG_SETMASK, [long(signal.SIGUSR1), long(signal.SIGUSR2)]) + masked = signal.sigprocmask(signal.SIG_SETMASK, previous) + self.assertEquals(masked, [signal.SIGUSR1, signal.SIGUSR2]) + + + +class SignalfdTests(unittest.TestCase): + """ + Tests for signal.signalfd. + """ + def test_signature(self): + """When invoked with fewer than two arguments or more than three, + signalfd raises TypeError. + """ + self.assertRaises(TypeError, signal.signalfd) + self.assertRaises(TypeError, signal.signalfd, 1) + self.assertRaises(TypeError, signal.signalfd, 1, 2, 3, 4) + + + def test_create_signalfd(self): + """When invoked with a file descriptor of -1, signalfd allocates a new + file descriptor for signal information delivery and returns it. + """ + fd = signal.signalfd(-1, []) + self.assertTrue(isinstance(fd, int)) + os.close(fd) + + + def test_non_iterable_signals(self): + """If an object which is not iterable is passed for the sigmask list + argument to signalfd, the exception raised by trying to iterate over + that object is raised. + """ + self.assertRaises(TypeError, signal.signalfd, -1, object()) + + + def test_non_integer_signals(self): + """If any non-integer values are included in the sigmask list argument + to signalfd, the exception raised by the attempt to convert them to an + integer is raised. + """ + self.assertRaises(TypeError, signal.signalfd, -1, [object()]) + + + def test_out_of_range_signal(self): + """If a signal number that is out of the valid range is included in the + sigmask list argument to signalfd, ValueError is raised. + """ + message = "signal number -2 out of range" + with self.assertRaisesRegexp(ValueError, message): + signal.signalfd(-1, [-2]) + + + def test_handle_signals(self): + """After signalfd is called, if a signal is received which was in the + sigmask list passed to that call, information about the signal can be + read from the fd returned by that call. + """ + fd = signal.signalfd(-1, [signal.SIGUSR2]) + self.addCleanup(os.close, fd) + previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR2]) + self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, previous) + os.kill(os.getpid(), signal.SIGUSR2) + bytes = os.read(fd, 128) + self.assertTrue(bytes) + + + def test_close_on_exec(self): + """If the bit mask passed as the 3rd argument to signalfd includes + SFD_CLOEXEC, the returned file descriptor has FD_CLOEXEC set on it. + """ + import fcntl + fd = signal.signalfd(-1, [], signal.SFD_CLOEXEC) + self.addCleanup(os.close, fd) + flags = fcntl.fcntl(fd, fcntl.F_GETFD) + self.assertTrue(flags & fcntl.FD_CLOEXEC) + + + def test_nonblocking(self): + """If the bit mask passed as the 3rd argument to signalfd includes + SFD_NOBLOCK, the file description referenced by the returned file + descriptor has O_NONBLOCK set on it. + """ + import fcntl + fd = signal.signalfd(-1, [], signal.SFD_NONBLOCK) + self.addCleanup(os.close, fd) + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + self.assertTrue(flags & os.O_NONBLOCK) + + + def test_default_flags(self): + """If an empty bit mask is passed as the 3rd argument to signalfd, + neither FD_CLOEXEC nor O_NONBLOCK is set on the resulting file + descriptor/description. + """ + import fcntl + fd = signal.signalfd(-1, []) + self.addCleanup(os.close, fd) + flags = fcntl.fcntl(fd, fcntl.F_GETFD) + self.assertFalse(flags & fcntl.FD_CLOEXEC) + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + self.assertFalse(flags & os.O_NONBLOCK) + + def test_main(): - support.run_unittest(BasicSignalTests, InterProcessSignalTests, - WakeupSignalTests, SiginterruptTest, ItimerTest) + support.run_unittest( + BasicSignalTests, InterProcessSignalTests, + WakeupSignalTests, SiginterruptTest, ItimerTest, SignalfdTests, + SigprocmaskTests) if __name__ == "__main__": Modified: python/branches/py3k-signalfd-issue8407/Misc/NEWS ============================================================================== --- python/branches/py3k-signalfd-issue8407/Misc/NEWS (original) +++ python/branches/py3k-signalfd-issue8407/Misc/NEWS Sat Jun 19 21:59:44 2010 @@ -1025,6 +1025,11 @@ - Issue #5949: added check for correct lineends in input from IMAP server in imaplib. +- Issue #8407: The signal module gains the ``signalfd()`` and + ``sigprocmask(2)`` functions providing access to the signalfd(2) and + sigprocmask(2) system calls respectively on Linux systems which implement + them. + - Add count() and reverse() methods to collections.deque(). - Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d Modified: python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c ============================================================================== --- python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c (original) +++ python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Sat Jun 19 21:59:44 2010 @@ -22,6 +22,10 @@ #ifdef HAVE_SYS_TIME_H #include #endif +#ifdef HAVE_SIGNALFD +#include +#endif + #ifndef SIG_ERR #define SIG_ERR ((PyOS_sighandler_t)(-1)) @@ -464,6 +468,144 @@ #endif +static int +_iterable_to_mask(PyObject *iterable, sigset_t *mask) +{ + static const char* range_format = "signal number %d out of range"; + char range_buffer[1024]; + int result = 0; + + PyObject *item, *iterator = NULL; + + sigemptyset(mask); + + iterator = PyObject_GetIter(iterable); + if (iterator == NULL) { + result = -1; + goto error; + } + + while ((item = PyIter_Next(iterator))) { + int signum = PyInt_AsLong(item); + Py_DECREF(item); + if (signum == -1 && PyErr_Occurred()) { + result = -1; + goto error; + } + if (sigaddset(mask, signum) == -1) { + PyOS_snprintf(range_buffer, sizeof(range_buffer), range_format, signum); + PyErr_SetString(PyExc_ValueError, range_buffer); + result = -1; + goto error; + } + } + +error: + Py_XDECREF(iterator); + return result; +} + +#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) +# define PY_SIGMASK pthread_sigmask +#elif defined(HAVE_SIGPROCMASK) +# define PY_SIGMASK sigprocmask +#endif + +#ifdef PY_SIGMASK +static PyObject * +signal_sigprocmask(PyObject *self, PyObject *args) +{ + static const char* how_format = "value specified for how (%d) invalid"; + char how_buffer[1024]; + + int how, sig; + PyObject *signals, *result, *signum; + sigset_t mask, previous; + + if (!PyArg_ParseTuple(args, "iO:sigprocmask", &how, &signals)) { + return NULL; + } + + if (_iterable_to_mask(signals, &mask) == -1) { + return NULL; + } + + if (PY_SIGMASK(how, &mask, &previous) != 0) { + PyOS_snprintf(how_buffer, sizeof(how_buffer), how_format, how); + PyErr_SetString(PyExc_ValueError, how_buffer); + return NULL; + } + + result = PyList_New(0); + if (result == NULL) { + return NULL; + } + + for (sig = 1; sig < NSIG; ++sig) { + if (sigismember(&previous, sig) == 1) { + /* Handle the case where it is a member by adding the signal to + the result list. Ignore the other cases because they mean the + signal isn't a member of the mask or the signal was invalid, + and an invalid signal must have been our fault in constructing + the loop boundaries. */ + signum = PyInt_FromLong(sig); + if (signum == NULL) { + Py_DECREF(result); + return NULL; + } + if (PyList_Append(result, signum) == -1) { + Py_DECREF(signum); + Py_DECREF(result); + return NULL; + } + Py_DECREF(signum); + } + } + return result; +} + +PyDoc_STRVAR(sigprocmask_doc, +"sigprocmask(how, mask) -> old mask\n\ +\n\ +Examine and change blocked signals."); +#endif + +#ifdef HAVE_SIGNALFD +static PyObject * +signal_signalfd(PyObject *self, PyObject *args) +{ + int result, flags = 0; + sigset_t mask; + + int fd; + PyObject *signals; + + if (!PyArg_ParseTuple(args, "iO|i:signalfd", &fd, &signals, &flags)) { + return NULL; + } + + if (_iterable_to_mask(signals, &mask) == -1) { + return NULL; + } + + result = signalfd(-1, &mask, flags); + + if (result == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + return PyInt_FromLong(result); +} + +PyDoc_STRVAR(signalfd_doc, +"signalfd(fd, mask, flags)\n\ +\n\ +Create a file descriptor for accepting signals."); + +#endif + + /* List of functions defined in the module */ static PyMethodDef signal_methods[] = { #ifdef HAVE_ALARM @@ -478,6 +620,14 @@ {"signal", signal_signal, METH_VARARGS, signal_doc}, {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, +#ifdef PY_SIGMASK + {"sigprocmask", signal_sigprocmask, METH_VARARGS, sigprocmask_doc}, +/* It's no longer needed, so clean up the namespace. */ +#undef PY_SIGMASK +#endif +#ifdef HAVE_SIGNALFD + {"signalfd", signal_signalfd, METH_VARARGS, signalfd_doc}, +#endif #ifdef HAVE_SIGINTERRUPT {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc}, #endif @@ -811,6 +961,36 @@ PyDict_SetItemString(d, "ItimerError", ItimerError); #endif +#ifdef SIG_BLOCK + x = PyLong_FromLong(SIG_BLOCK); + PyDict_SetItemString(d, "SIG_BLOCK", x); + Py_DECREF(x); +#endif + +#ifdef SIG_UNBLOCK + x = PyLong_FromLong(SIG_UNBLOCK); + PyDict_SetItemString(d, "SIG_UNBLOCK", x); + Py_DECREF(x); +#endif + +#ifdef SIG_SETMASK + x = PyLong_FromLong(SIG_SETMASK); + PyDict_SetItemString(d, "SIG_SETMASK", x); + Py_DECREF(x); +#endif + +#ifdef SFD_CLOEXEC + x = PyLong_FromLong(SFD_CLOEXEC); + PyDict_SetItemString(d, "SFD_CLOEXEC", x); + Py_DECREF(x); +#endif + +#ifdef SFD_NONBLOCK + x = PyLong_FromLong(SFD_NONBLOCK); + PyDict_SetItemString(d, "SFD_NONBLOCK", x); + Py_DECREF(x); +#endif + #ifdef CTRL_C_EVENT x = PyLong_FromLong(CTRL_C_EVENT); PyDict_SetItemString(d, "CTRL_C_EVENT", x); Modified: python/branches/py3k-signalfd-issue8407/configure ============================================================================== --- python/branches/py3k-signalfd-issue8407/configure (original) +++ python/branches/py3k-signalfd-issue8407/configure Sat Jun 19 21:59:44 2010 @@ -9297,7 +9297,7 @@ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ - sigaction siginterrupt sigrelse snprintf strftime strlcpy \ + sigaction siginterrupt signalfd sigprocmask sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm _getpty Modified: python/branches/py3k-signalfd-issue8407/configure.in ============================================================================== --- python/branches/py3k-signalfd-issue8407/configure.in (original) +++ python/branches/py3k-signalfd-issue8407/configure.in Sat Jun 19 21:59:44 2010 @@ -2580,7 +2580,7 @@ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ - sigaction siginterrupt sigrelse snprintf strftime strlcpy \ + sigaction siginterrupt signalfd sigprocmask sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm _getpty) Modified: python/branches/py3k-signalfd-issue8407/pyconfig.h.in ============================================================================== --- python/branches/py3k-signalfd-issue8407/pyconfig.h.in (original) +++ python/branches/py3k-signalfd-issue8407/pyconfig.h.in Sat Jun 19 21:59:44 2010 @@ -620,6 +620,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H +/* Define to 1 if you have the `signalfd' function. */ +#undef HAVE_SIGNALFD + +/* Define to 1 if you have the `sigprocmask' function. */ +#undef HAVE_SIGPROCMASK + /* Define to 1 if you have the `sigrelse' function. */ #undef HAVE_SIGRELSE From python-checkins at python.org Sat Jun 19 22:01:16 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:01:16 +0200 (CEST) Subject: [Python-checkins] r82092 - python/branches/py3k-signalfd-issue8407/Misc/NEWS Message-ID: <20100619200116.635C9EEA28@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:01:16 2010 New Revision: 82092 Log: remove manual section from one of these Modified: python/branches/py3k-signalfd-issue8407/Misc/NEWS Modified: python/branches/py3k-signalfd-issue8407/Misc/NEWS ============================================================================== --- python/branches/py3k-signalfd-issue8407/Misc/NEWS (original) +++ python/branches/py3k-signalfd-issue8407/Misc/NEWS Sat Jun 19 22:01:16 2010 @@ -1026,7 +1026,7 @@ in imaplib. - Issue #8407: The signal module gains the ``signalfd()`` and - ``sigprocmask(2)`` functions providing access to the signalfd(2) and + ``sigprocmask()`` functions providing access to the signalfd(2) and sigprocmask(2) system calls respectively on Linux systems which implement them. From python-checkins at python.org Sat Jun 19 22:05:29 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:05:29 +0200 (CEST) Subject: [Python-checkins] r82093 - python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Message-ID: <20100619200529.CD771F3CC@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:05:29 2010 New Revision: 82093 Log: It's 3.2 now, not 2.7 Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Sat Jun 19 22:05:29 2010 @@ -117,7 +117,7 @@ A possible value for the *how* parameter to :func:`sigprocmask` indicating that signals are to be blocked. - .. versionadded:: 2.7 + .. versionadded:: 3.2 .. data:: SIG_UNBLOCK @@ -125,7 +125,7 @@ A possible value for the *how* parameter to :func:`sigprocmask` indicating that signals are to be unblocked. - .. versionadded:: 2.7 + .. versionadded:: 3.2 .. data:: SIG_SETMASK @@ -133,7 +133,7 @@ A possible value for the *how* parameter to :func:`sigprocmask` indicating that the signal mask is to be replaced. - .. versionadded:: 2.7 + .. versionadded:: 3.2 .. data:: SFD_CLOEXEC @@ -141,7 +141,7 @@ A possible flag in the *flags* parameter to :func:`signalfd` which causes the new file descriptor to be marked as close-on-exec. - .. versionadded:: 2.7 + .. versionadded:: 3.2 .. data:: SFD_NONBLOCK @@ -149,7 +149,7 @@ A possible flag in the *flags* parameter to :func:`signalfd` which causes the new file description to be set non-blocking. - .. versionadded:: 2.7 + .. versionadded:: 3.2 The :mod:`signal` module defines one exception: From python-checkins at python.org Sat Jun 19 22:06:04 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:06:04 +0200 (CEST) Subject: [Python-checkins] r82094 - python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Message-ID: <20100619200604.11AAEF3CC@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:06:03 2010 New Revision: 82094 Log: And likewise for the functions Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Sat Jun 19 22:06:03 2010 @@ -279,7 +279,7 @@ *flags* is a bit mask which may include any :const:`signal.SFD_*` flag. - .. versionadded:: 2.7 + .. versionadded:: 3.2 .. function:: sigprocmask(how, mask) @@ -299,7 +299,7 @@ *mask* is a list of signal numbers (eg :const:`signal.SIGUSR1`). - .. versionadded:: 2.7 + .. versionadded:: 3.2 .. _signal-example: From python-checkins at python.org Sat Jun 19 22:08:54 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:08:54 +0200 (CEST) Subject: [Python-checkins] r82095 - python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Message-ID: <20100619200854.70458EE9A0@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:08:54 2010 New Revision: 82095 Log: Try this emphasis on SFD_NONBLOCK; also see what :platform: does Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Sat Jun 19 22:08:54 2010 @@ -147,7 +147,7 @@ .. data:: SFD_NONBLOCK A possible flag in the *flags* parameter to :func:`signalfd` which causes - the new file description to be set non-blocking. + the new file *description* (**not** *descriptor*) to be set non-blocking. .. versionadded:: 3.2 @@ -268,8 +268,8 @@ Create a new file descriptor on which to receive signals or modify the mask of such a file descriptor previously created by this function. - Availability: Linux (See the manpage :manpage:`signalfd(2)` for further - information). + Availability: :platform: Linux (See the manpage :manpage:`signalfd(2)` + for further information). If *fd* is ``-1``, a new file descriptor will be created. Otherwise, *fd* must be a file descriptor previously returned by this function. From python-checkins at python.org Sat Jun 19 22:21:42 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:21:42 +0200 (CEST) Subject: [Python-checkins] r82096 - python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Message-ID: <20100619202142.95F49EE9A0@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:21:42 2010 New Revision: 82096 Log: Indent a versionadded tag properly Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Sat Jun 19 22:21:42 2010 @@ -299,7 +299,7 @@ *mask* is a list of signal numbers (eg :const:`signal.SIGUSR1`). - .. versionadded:: 3.2 + .. versionadded:: 3.2 .. _signal-example: From python-checkins at python.org Sat Jun 19 22:22:14 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:22:14 +0200 (CEST) Subject: [Python-checkins] r82097 - python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Message-ID: <20100619202214.69B4AEE9A0@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:22:14 2010 New Revision: 82097 Log: :platform: does not seem to be rendered in any particular way Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Sat Jun 19 22:22:14 2010 @@ -268,8 +268,8 @@ Create a new file descriptor on which to receive signals or modify the mask of such a file descriptor previously created by this function. - Availability: :platform: Linux (See the manpage :manpage:`signalfd(2)` - for further information). + Availability: Linux (See the manpage :manpage:`signalfd(2)` for further + information). If *fd* is ``-1``, a new file descriptor will be created. Otherwise, *fd* must be a file descriptor previously returned by this function. From python-checkins at python.org Sat Jun 19 22:26:31 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:26:31 +0200 (CEST) Subject: [Python-checkins] r82098 - python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Message-ID: <20100619202631.ED5B9EE9D8@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:26:31 2010 New Revision: 82098 Log: Use :platform: like this Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Sat Jun 19 22:26:31 2010 @@ -266,6 +266,7 @@ .. function:: signalfd(fd, mask[, flags]) + :platform: Linux Create a new file descriptor on which to receive signals or modify the mask of such a file descriptor previously created by this function. Availability: Linux (See the manpage :manpage:`signalfd(2)` for further From python-checkins at python.org Sat Jun 19 22:33:43 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:33:43 +0200 (CEST) Subject: [Python-checkins] r82099 - python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Message-ID: <20100619203343.5AC92F3DF@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:33:43 2010 New Revision: 82099 Log: Do not use :platform:, it is a module directive. Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Sat Jun 19 22:33:43 2010 @@ -266,11 +266,10 @@ .. function:: signalfd(fd, mask[, flags]) - :platform: Linux Create a new file descriptor on which to receive signals or modify the mask of such a file descriptor previously created by this function. - Availability: Linux (See the manpage :manpage:`signalfd(2)` for further - information). + Availability: Linux. See the manpage :manpage:`signalfd(2)` for further + information. If *fd* is ``-1``, a new file descriptor will be created. Otherwise, *fd* must be a file descriptor previously returned by this function. @@ -286,8 +285,8 @@ .. function:: sigprocmask(how, mask) Set the signal mask for the process. The old signal mask is returned. - Availability: Unix (See the Unix man page :manpage:`sigprocmask(2)` and - :manpage:`pthread_sigmask(2)`.) + Availability: Unix. See the man page :manpage:`sigprocmask(2)` and + :manpage:`pthread_sigmask(2)`. If *how* is :const:`signal.SIG_BLOCK`, the signals in the mask are added to the set of blocked signals. From python-checkins at python.org Sat Jun 19 22:49:50 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:49:50 +0200 (CEST) Subject: [Python-checkins] r82100 - in python/branches/py3k-signalfd-issue8407/Doc: glossary.rst library/signal.rst Message-ID: <20100619204950.8D9A3EE998@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:49:50 2010 New Revision: 82100 Log: add file descriptors and descriptions to the glossary Modified: python/branches/py3k-signalfd-issue8407/Doc/glossary.rst python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Modified: python/branches/py3k-signalfd-issue8407/Doc/glossary.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/glossary.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/glossary.rst Sat Jun 19 22:49:50 2010 @@ -179,6 +179,16 @@ A module written in C or C++, using Python's C API to interact with the core and with user code. + file description + The data structure (usually in the kernel) containing the details of + an open file. A file description is referred to by one or more + :term:`file descriptors `. + + file descriptor + An abstract reference to a file, socket, or other file-like entity. + For example, the integer returned by :func:`os.open`, :func:`os.dup`, + or :meth:`io.IOBase.fileno`. + finder An object that tries to find the :term:`loader` for a module. It must implement a method named :meth:`find_module`. See :pep:`302` for Modified: python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst ============================================================================== --- python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst (original) +++ python/branches/py3k-signalfd-issue8407/Doc/library/signal.rst Sat Jun 19 22:49:50 2010 @@ -147,7 +147,7 @@ .. data:: SFD_NONBLOCK A possible flag in the *flags* parameter to :func:`signalfd` which causes - the new file *description* (**not** *descriptor*) to be set non-blocking. + the new :term:`file description` to be set non-blocking. .. versionadded:: 3.2 From python-checkins at python.org Sat Jun 19 22:57:07 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 22:57:07 +0200 (CEST) Subject: [Python-checkins] r82101 - python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Message-ID: <20100619205707.4F50BEE9C7@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 22:57:07 2010 New Revision: 82101 Log: PyInt_* becomes PyLong_* Modified: python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Modified: python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c ============================================================================== --- python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c (original) +++ python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Sat Jun 19 22:57:07 2010 @@ -486,7 +486,7 @@ } while ((item = PyIter_Next(iterator))) { - int signum = PyInt_AsLong(item); + int signum = PyLong_AsLong(item); Py_DECREF(item); if (signum == -1 && PyErr_Occurred()) { result = -1; @@ -548,7 +548,7 @@ signal isn't a member of the mask or the signal was invalid, and an invalid signal must have been our fault in constructing the loop boundaries. */ - signum = PyInt_FromLong(sig); + signum = PyLong_FromLong(sig); if (signum == NULL) { Py_DECREF(result); return NULL; @@ -595,7 +595,7 @@ return NULL; } - return PyInt_FromLong(result); + return PyLong_FromLong(result); } PyDoc_STRVAR(signalfd_doc, From python-checkins at python.org Sat Jun 19 23:04:17 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 23:04:17 +0200 (CEST) Subject: [Python-checkins] r82102 - python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Message-ID: <20100619210417.CB66CF2BB@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 23:04:17 2010 New Revision: 82102 Log: Drop the test for `long` signals, as there is no longer any such thing. Skip the signalfd tests on non-linux platforms Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py ============================================================================== --- python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py (original) +++ python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Sat Jun 19 23:04:17 2010 @@ -554,15 +554,10 @@ os.kill(os.getpid(), signal.SIGUSR1) - def test_long_signals(self): - """sigprocmask accepts signal numbers as instances of long.""" - previous = signal.sigprocmask( - signal.SIG_SETMASK, [long(signal.SIGUSR1), long(signal.SIGUSR2)]) - masked = signal.sigprocmask(signal.SIG_SETMASK, previous) - self.assertEquals(masked, [signal.SIGUSR1, signal.SIGUSR2]) - - + at unittest.skipIf(sys.platform != 'linux2' + or os.uname()[2].split('.') < ['2', '6', '22'], + 'signalfd(2) only available on Linux >=2.6.22') class SignalfdTests(unittest.TestCase): """ Tests for signal.signalfd. From python-checkins at python.org Sat Jun 19 23:08:58 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 23:08:58 +0200 (CEST) Subject: [Python-checkins] r82103 - python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Message-ID: <20100619210858.BC58CEE9A0@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 23:08:58 2010 New Revision: 82103 Log: Use PyErr_Format instead of PyOS_snprintf Modified: python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Modified: python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c ============================================================================== --- python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c (original) +++ python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Sat Jun 19 23:08:58 2010 @@ -472,7 +472,6 @@ _iterable_to_mask(PyObject *iterable, sigset_t *mask) { static const char* range_format = "signal number %d out of range"; - char range_buffer[1024]; int result = 0; PyObject *item, *iterator = NULL; @@ -493,8 +492,7 @@ goto error; } if (sigaddset(mask, signum) == -1) { - PyOS_snprintf(range_buffer, sizeof(range_buffer), range_format, signum); - PyErr_SetString(PyExc_ValueError, range_buffer); + PyErr_Format(PyExc_ValueError, range_format, signum); result = -1; goto error; } @@ -516,7 +514,6 @@ signal_sigprocmask(PyObject *self, PyObject *args) { static const char* how_format = "value specified for how (%d) invalid"; - char how_buffer[1024]; int how, sig; PyObject *signals, *result, *signum; @@ -531,8 +528,7 @@ } if (PY_SIGMASK(how, &mask, &previous) != 0) { - PyOS_snprintf(how_buffer, sizeof(how_buffer), how_format, how); - PyErr_SetString(PyExc_ValueError, how_buffer); + PyErr_Format(PyExc_ValueError, how_format, how); return NULL; } From python-checkins at python.org Sat Jun 19 23:44:59 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sat, 19 Jun 2010 23:44:59 +0200 (CEST) Subject: [Python-checkins] r82104 - python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Message-ID: <20100619214459.47644F168@mail.python.org> Author: jean-paul.calderone Date: Sat Jun 19 23:44:59 2010 New Revision: 82104 Log: Skip _iterable_to_mask if there's no sigprocmask Modified: python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Modified: python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c ============================================================================== --- python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c (original) +++ python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Sat Jun 19 23:44:59 2010 @@ -468,6 +468,7 @@ #endif +#ifdef HAVE_SIGPROCMASK static int _iterable_to_mask(PyObject *iterable, sigset_t *mask) { @@ -502,6 +503,7 @@ Py_XDECREF(iterator); return result; } +#endif #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) # define PY_SIGMASK pthread_sigmask From python-checkins at python.org Sun Jun 20 01:00:34 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sun, 20 Jun 2010 01:00:34 +0200 (CEST) Subject: [Python-checkins] r82105 - python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Message-ID: <20100619230034.DF2DDEE998@mail.python.org> Author: jean-paul.calderone Date: Sun Jun 20 01:00:34 2010 New Revision: 82105 Log: Clean up the environment a little This seems only to be necessary to support Linux systems with LinuxThreads instead of NPTL Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py ============================================================================== --- python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py (original) +++ python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Sun Jun 20 01:00:34 2010 @@ -484,6 +484,16 @@ old_handler = signal.signal(signal.SIGUSR1, raiser) self.addCleanup(signal.signal, signal.SIGUSR1, old_handler) + # This depends on sigprocmask working a bit. If it doesn't, then + # this won't succeed in keeping the signal mask state sane. But + # there's nothing else we can do in that case. This is necessary at + # all because some environments start off with certain signals + # masked for obscure reasons. The intent is to provide the tests + # with a consistent, predictable starting state and then restore the + # environment's expectations after the test. + old_mask = signal.sigprocmask(signal.SIG_SETMASK, []) + self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, old_mask) + def test_signature(self): """When invoked with other than two arguments, sigprocmask raises From python-checkins at python.org Sun Jun 20 01:10:53 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sun, 20 Jun 2010 01:10:53 +0200 (CEST) Subject: [Python-checkins] r82106 - in python/branches/py3k-signalfd-issue8407: Modules/signalmodule.c pyconfig.h.in Message-ID: <20100619231053.CFC46EE998@mail.python.org> Author: jean-paul.calderone Date: Sun Jun 20 01:10:53 2010 New Revision: 82106 Log: Do this HAVE_SYS_SIGNALFD_H thing It's probably wrong. I don't know about this stuff. Some systems appear to HAVE_SIGNALFD while not having though. Modified: python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c python/branches/py3k-signalfd-issue8407/pyconfig.h.in Modified: python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c ============================================================================== --- python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c (original) +++ python/branches/py3k-signalfd-issue8407/Modules/signalmodule.c Sun Jun 20 01:10:53 2010 @@ -22,7 +22,7 @@ #ifdef HAVE_SYS_TIME_H #include #endif -#ifdef HAVE_SIGNALFD +#ifdef HAVE_SYS_SIGNALFD_H #include #endif Modified: python/branches/py3k-signalfd-issue8407/pyconfig.h.in ============================================================================== --- python/branches/py3k-signalfd-issue8407/pyconfig.h.in (original) +++ python/branches/py3k-signalfd-issue8407/pyconfig.h.in Sun Jun 20 01:10:53 2010 @@ -765,6 +765,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SIGNALFD_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H From python-checkins at python.org Sun Jun 20 01:13:24 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sun, 20 Jun 2010 01:13:24 +0200 (CEST) Subject: [Python-checkins] r82107 - python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Message-ID: <20100619231324.6F593F225@mail.python.org> Author: jean-paul.calderone Date: Sun Jun 20 01:13:24 2010 New Revision: 82107 Log: Skip like this Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py ============================================================================== --- python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py (original) +++ python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Sun Jun 20 01:13:24 2010 @@ -565,8 +565,7 @@ - at unittest.skipIf(sys.platform != 'linux2' - or os.uname()[2].split('.') < ['2', '6', '22'], + at unittest.skipIf(getattr(signal, 'signalfd', None) is None, 'signalfd(2) only available on Linux >=2.6.22') class SignalfdTests(unittest.TestCase): """ From solipsis at pitrou.net Sun Jun 20 01:25:13 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 20 Jun 2010 01:25:13 +0200 (CEST) Subject: [Python-checkins] Daily py3k reference leaks (r82090): sum=1 Message-ID: <20100619232513.947921770A@ns6635.ovh.net> py3k results for svn r82090 (hg cset a9a38b274b8a) -------------------------------------------------- test_multiprocessing leaked [0, 0, 1] references, sum=1 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogZYszn0', '-x'] From python-checkins at python.org Sun Jun 20 06:08:55 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sun, 20 Jun 2010 06:08:55 +0200 (CEST) Subject: [Python-checkins] r82108 - python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Message-ID: <20100620040855.ABFEEE71E@mail.python.org> Author: jean-paul.calderone Date: Sun Jun 20 06:08:55 2010 New Revision: 82108 Log: Skip on middle-ish versions of Linux Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py ============================================================================== --- python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py (original) +++ python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Sun Jun 20 06:08:55 2010 @@ -628,6 +628,8 @@ self.assertTrue(bytes) + @unittest.skipIf(getattr('signal', 'SFD_CLOEXEC', None) is None, + "signal.SFD_CLOEXEC only available on Linux >=2.6.27") def test_close_on_exec(self): """If the bit mask passed as the 3rd argument to signalfd includes SFD_CLOEXEC, the returned file descriptor has FD_CLOEXEC set on it. @@ -639,6 +641,8 @@ self.assertTrue(flags & fcntl.FD_CLOEXEC) + @unittest.skipIf(getattr('signal', 'SFD_NONBLOCK', None) is None, + "signal.SFD_NONBLOCK only available on Linux >=2.6.27") def test_nonblocking(self): """If the bit mask passed as the 3rd argument to signalfd includes SFD_NOBLOCK, the file description referenced by the returned file From python-checkins at python.org Sun Jun 20 06:33:55 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sun, 20 Jun 2010 06:33:55 +0200 (CEST) Subject: [Python-checkins] r82109 - python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Message-ID: <20100620043355.3303AEE9C7@mail.python.org> Author: jean-paul.calderone Date: Sun Jun 20 06:33:55 2010 New Revision: 82109 Log: dangers of light night coding revealed also the wonders of feature branches Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Modified: python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py ============================================================================== --- python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py (original) +++ python/branches/py3k-signalfd-issue8407/Lib/test/test_signal.py Sun Jun 20 06:33:55 2010 @@ -628,7 +628,7 @@ self.assertTrue(bytes) - @unittest.skipIf(getattr('signal', 'SFD_CLOEXEC', None) is None, + @unittest.skipIf(getattr(signal, 'SFD_CLOEXEC', None) is None, "signal.SFD_CLOEXEC only available on Linux >=2.6.27") def test_close_on_exec(self): """If the bit mask passed as the 3rd argument to signalfd includes @@ -641,7 +641,7 @@ self.assertTrue(flags & fcntl.FD_CLOEXEC) - @unittest.skipIf(getattr('signal', 'SFD_NONBLOCK', None) is None, + @unittest.skipIf(getattr(signal, 'SFD_NONBLOCK', None) is None, "signal.SFD_NONBLOCK only available on Linux >=2.6.27") def test_nonblocking(self): """If the bit mask passed as the 3rd argument to signalfd includes From python-checkins at python.org Sun Jun 20 17:12:04 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 20 Jun 2010 17:12:04 +0200 (CEST) Subject: [Python-checkins] r82112 - python/trunk/README Message-ID: <20100620151204.B081CEE86@mail.python.org> Author: benjamin.peterson Date: Sun Jun 20 17:12:04 2010 New Revision: 82112 Log: update emacs section Modified: python/trunk/README Modified: python/trunk/README ============================================================================== --- python/trunk/README (original) +++ python/trunk/README Sun Jun 20 17:12:04 2010 @@ -1147,16 +1147,10 @@ ---------- There's an excellent Emacs editing mode for Python code; see the file -Misc/python-mode.el. Originally written by the famous Tim Peters, it -is now maintained by the equally famous Barry Warsaw (it's no -coincidence that they now both work on the same team). The latest -version, along with various other contributed Python-related Emacs -goodies, is online at http://www.python.org/emacs/python-mode/. And -if you are planning to edit the Python C code, please pick up the -latest version of CC Mode http://www.python.org/emacs/cc-mode/; it -contains a "python" style used throughout most of the Python C source -files. (Newer versions of Emacs or XEmacs may already come with the -latest version of python-mode.) +Misc/python-mode.el. Originally written by the famous Tim Peters, it is now +maintained by the equally famous Barry Warsaw. The latest version, along with +various other contributed Python-related Emacs goodies, is online at +http://launchpad.net/python-mode/. Tkinter From python-checkins at python.org Sun Jun 20 17:25:14 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 20 Jun 2010 17:25:14 +0200 (CEST) Subject: [Python-checkins] r82113 - python/branches/py3k Message-ID: <20100620152514.66687EE9C7@mail.python.org> Author: benjamin.peterson Date: Sun Jun 20 17:25:14 2010 New Revision: 82113 Log: Blocked revisions 82112 via svnmerge ........ r82112 | benjamin.peterson | 2010-06-20 10:12:04 -0500 (Sun, 20 Jun 2010) | 1 line update emacs section ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Jun 20 17:27:07 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 20 Jun 2010 17:27:07 +0200 (CEST) Subject: [Python-checkins] r82114 - python/branches/py3k/README Message-ID: <20100620152707.AB1EFEE9C7@mail.python.org> Author: benjamin.peterson Date: Sun Jun 20 17:27:07 2010 New Revision: 82114 Log: update release schedule url Modified: python/branches/py3k/README Modified: python/branches/py3k/README ============================================================================== --- python/branches/py3k/README (original) +++ python/branches/py3k/README Sun Jun 20 17:27:07 2010 @@ -172,7 +172,7 @@ Release Schedule ---------------- -See PEP 375 for release details: http://www.python.org/dev/peps/pep-0375/ +See PEP 392 for release details: http://www.python.org/dev/peps/pep-0392/ Copyright and License Information From python-checkins at python.org Sun Jun 20 17:27:42 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 20 Jun 2010 17:27:42 +0200 (CEST) Subject: [Python-checkins] r82115 - python/branches/py3k/README Message-ID: <20100620152742.E996BEE9C7@mail.python.org> Author: benjamin.peterson Date: Sun Jun 20 17:27:42 2010 New Revision: 82115 Log: add copyright years Modified: python/branches/py3k/README Modified: python/branches/py3k/README ============================================================================== --- python/branches/py3k/README (original) +++ python/branches/py3k/README Sun Jun 20 17:27:42 2010 @@ -178,7 +178,7 @@ Copyright and License Information --------------------------------- -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Python Software Foundation. All rights reserved. From python-checkins at python.org Sun Jun 20 17:33:04 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 20 Jun 2010 17:33:04 +0200 (CEST) Subject: [Python-checkins] r82116 - peps/trunk/pep-0392.txt Message-ID: <20100620153304.3337AEE9C7@mail.python.org> Author: benjamin.peterson Date: Sun Jun 20 17:33:04 2010 New Revision: 82116 Log: svn keywords must have no spaces Modified: peps/trunk/pep-0392.txt Modified: peps/trunk/pep-0392.txt ============================================================================== --- peps/trunk/pep-0392.txt (original) +++ peps/trunk/pep-0392.txt Sun Jun 20 17:33:04 2010 @@ -1,7 +1,7 @@ PEP: 392 Title: Python 3.2 Release Schedule -Version: $Revision $ -Last-Modified: $Date $ +Version: $Revision$ +Last-Modified: $Date$ Author: Georg Brandl Status: Active Type: Informational From python-checkins at python.org Sun Jun 20 20:50:20 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Jun 2010 20:50:20 +0200 (CEST) Subject: [Python-checkins] r82117 - in python/trunk/Lib/test: test_float.py test_strtod.py Message-ID: <20100620185020.287BDEEA5E@mail.python.org> Author: mark.dickinson Date: Sun Jun 20 20:50:19 2010 New Revision: 82117 Log: Merge test_strtod and test_float string-to-float conversion tests. Modified: python/trunk/Lib/test/test_float.py python/trunk/Lib/test/test_strtod.py Modified: python/trunk/Lib/test/test_float.py ============================================================================== --- python/trunk/Lib/test/test_float.py (original) +++ python/trunk/Lib/test/test_float.py Sun Jun 20 20:50:19 2010 @@ -8,7 +8,6 @@ import random import fractions import sys -import re INF = float("inf") NAN = float("nan") @@ -22,74 +21,6 @@ test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') -finite_decimal_parser = re.compile(r""" # A numeric string consists of: - (?P[-+])? # an optional sign, followed by - (?=\d|\.\d) # a number with at least one digit - (?P\d*) # having a (possibly empty) integer part - (?:\.(?P\d*))? # followed by an optional fractional part - (?:E(?P[-+]?\d+))? # and an optional exponent - \Z -""", re.VERBOSE | re.IGNORECASE | re.UNICODE).match - -# Pure Python version of correctly rounded string->float conversion. -# Avoids any use of floating-point by returning the result as a hex string. -def strtod(s, mant_dig=53, min_exp = -1021, max_exp = 1024): - """Convert a finite decimal string to a hex string representing an - IEEE 754 binary64 float. Return 'inf' or '-inf' on overflow. - This function makes no use of floating-point arithmetic at any - stage.""" - - # parse string into a pair of integers 'a' and 'b' such that - # abs(decimal value) = a/b, and a boolean 'negative'. - m = finite_decimal_parser(s) - if m is None: - raise ValueError('invalid numeric string') - fraction = m.group('frac') or '' - intpart = int(m.group('int') + fraction) - exp = int(m.group('exp') or '0') - len(fraction) - negative = m.group('sign') == '-' - a, b = intpart*10**max(exp, 0), 10**max(0, -exp) - - # quick return for zeros - if not a: - return '-0x0.0p+0' if negative else '0x0.0p+0' - - # compute exponent e for result; may be one too small in the case - # that the rounded value of a/b lies in a different binade from a/b - d = a.bit_length() - b.bit_length() - d += (a >> d if d >= 0 else a << -d) >= b - e = max(d, min_exp) - mant_dig - - # approximate a/b by number of the form q * 2**e; adjust e if necessary - a, b = a << max(-e, 0), b << max(e, 0) - q, r = divmod(a, b) - if 2*r > b or 2*r == b and q & 1: - q += 1 - if q.bit_length() == mant_dig+1: - q //= 2 - e += 1 - - # double check that (q, e) has the right form - assert q.bit_length() <= mant_dig and e >= min_exp - mant_dig - assert q.bit_length() == mant_dig or e == min_exp - mant_dig - - # check for overflow and underflow - if e + q.bit_length() > max_exp: - return '-inf' if negative else 'inf' - if not q: - return '-0x0.0p+0' if negative else '0x0.0p+0' - - # for hex representation, shift so # bits after point is a multiple of 4 - hexdigs = 1 + (mant_dig-2)//4 - shift = 3 - (mant_dig-2)%4 - q, e = q << shift, e - shift - return '{}0x{:x}.{:0{}x}p{:+d}'.format( - '-' if negative else '', - q // 16**hexdigs, - q % 16**hexdigs, - hexdigs, - e + 4*hexdigs) - class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -1378,38 +1309,6 @@ else: self.identical(x, fromHex(toHex(x))) -class StrtodTestCase(unittest.TestCase): - def check_string(self, s): - expected = strtod(s) - try: - fs = float(s) - except OverflowError: - got = '-inf' if s[0] == '-' else 'inf' - else: - got = fs.hex() - self.assertEqual(expected, got, - "Incorrectly rounded str->float conversion for " - "{}: expected {}, got {}".format(s, expected, got)) - - @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', - "applies only when using short float repr style") - def test_bug7632(self): - # check a few particular values that gave incorrectly rounded - # results with previous versions of dtoa.c - test_strings = [ - '94393431193180696942841837085033647913224148539854e-358', - '12579816049008305546974391768996369464963024663104e-357', - '17489628565202117263145367596028389348922981857013e-357', - '18487398785991994634182916638542680759613590482273e-357', - '32002864200581033134358724675198044527469366773928e-358', - '73608278998966969345824653500136787876436005957953e-358', - '64774478836417299491718435234611299336288082136054e-358', - '13704940134126574534878641876947980878824688451169e-357', - '46697445774047060960624497964425416610480524760471e-358', - ] - for s in test_strings: - self.check_string(s) - def test_main(): test_support.run_unittest( @@ -1421,7 +1320,6 @@ RoundTestCase, InfNanTest, HexFloatTestCase, - StrtodTestCase, ) if __name__ == '__main__': Modified: python/trunk/Lib/test/test_strtod.py ============================================================================== --- python/trunk/Lib/test/test_strtod.py (original) +++ python/trunk/Lib/test/test_strtod.py Sun Jun 20 20:50:19 2010 @@ -23,6 +23,8 @@ \Z """, re.VERBOSE | re.IGNORECASE).match +# Pure Python version of correctly rounded string->float conversion. +# Avoids any use of floating-point by returning the result as a hex string. def strtod(s, mant_dig=53, min_exp = -1021, max_exp = 1024): """Convert a finite decimal string to a hex string representing an IEEE 754 binary64 float. Return 'inf' or '-inf' on overflow. @@ -259,6 +261,10 @@ '18487398785991994634182916638542680759613590482273e-357', '32002864200581033134358724675198044527469366773928e-358', '94393431193180696942841837085033647913224148539854e-358', + '73608278998966969345824653500136787876436005957953e-358', + '64774478836417299491718435234611299336288082136054e-358', + '13704940134126574534878641876947980878824688451169e-357', + '46697445774047060960624497964425416610480524760471e-358', # failing case for bug introduced by METD in r77451 (attempted # fix for issue 7632, bug 2), and fixed in r77482. '28639097178261763178489759107321392745108491825303e-311', From python-checkins at python.org Sun Jun 20 21:36:01 2010 From: python-checkins at python.org (jean-paul.calderone) Date: Sun, 20 Jun 2010 21:36:01 +0200 (CEST) Subject: [Python-checkins] r82118 - python/branches/py3k-signalfd-issue8407/Lib/test/regrtest.py Message-ID: <20100620193601.1DDD5EEA84@mail.python.org> Author: jean-paul.calderone Date: Sun Jun 20 21:36:00 2010 New Revision: 82118 Log: verbose test runs please Modified: python/branches/py3k-signalfd-issue8407/Lib/test/regrtest.py Modified: python/branches/py3k-signalfd-issue8407/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k-signalfd-issue8407/Lib/test/regrtest.py (original) +++ python/branches/py3k-signalfd-issue8407/Lib/test/regrtest.py Sun Jun 20 21:36:00 2010 @@ -231,7 +231,7 @@ sys.exit(2) -def main(tests=None, testdir=None, verbose=0, quiet=False, +def main(tests=None, testdir=None, verbose=1, quiet=False, exclude=False, single=False, randomize=False, fromfile=None, findleaks=False, use_resources=None, trace=False, coverdir='coverage', runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, From python-checkins at python.org Sun Jun 20 22:01:04 2010 From: python-checkins at python.org (mark.dickinson) Date: Sun, 20 Jun 2010 22:01:04 +0200 (CEST) Subject: [Python-checkins] r82119 - in python/branches/py3k: Lib/test/test_float.py Lib/test/test_strtod.py Message-ID: <20100620200104.7484AEEA98@mail.python.org> Author: mark.dickinson Date: Sun Jun 20 22:01:04 2010 New Revision: 82119 Log: Merged revisions 82117 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r82117 | mark.dickinson | 2010-06-20 19:50:19 +0100 (Sun, 20 Jun 2010) | 1 line Merge test_strtod and test_float string-to-float conversion tests. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_float.py python/branches/py3k/Lib/test/test_strtod.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 Sun Jun 20 22:01:04 2010 @@ -7,7 +7,6 @@ from math import isinf, isnan, copysign, ldexp import operator import random, fractions -import re INF = float("inf") NAN = float("nan") @@ -21,74 +20,6 @@ test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') -finite_decimal_parser = re.compile(r""" # A numeric string consists of: - (?P[-+])? # an optional sign, followed by - (?=\d|\.\d) # a number with at least one digit - (?P\d*) # having a (possibly empty) integer part - (?:\.(?P\d*))? # followed by an optional fractional part - (?:E(?P[-+]?\d+))? # and an optional exponent - \Z -""", re.VERBOSE | re.IGNORECASE | re.UNICODE).match - -# Pure Python version of correctly rounded string->float conversion. -# Avoids any use of floating-point by returning the result as a hex string. -def strtod(s, mant_dig=53, min_exp = -1021, max_exp = 1024): - """Convert a finite decimal string to a hex string representing an - IEEE 754 binary64 float. Return 'inf' or '-inf' on overflow. - This function makes no use of floating-point arithmetic at any - stage.""" - - # parse string into a pair of integers 'a' and 'b' such that - # abs(decimal value) = a/b, and a boolean 'negative'. - m = finite_decimal_parser(s) - if m is None: - raise ValueError('invalid numeric string') - fraction = m.group('frac') or '' - intpart = int(m.group('int') + fraction) - exp = int(m.group('exp') or '0') - len(fraction) - negative = m.group('sign') == '-' - a, b = intpart*10**max(exp, 0), 10**max(0, -exp) - - # quick return for zeros - if not a: - return '-0x0.0p+0' if negative else '0x0.0p+0' - - # compute exponent e for result; may be one too small in the case - # that the rounded value of a/b lies in a different binade from a/b - d = a.bit_length() - b.bit_length() - d += (a >> d if d >= 0 else a << -d) >= b - e = max(d, min_exp) - mant_dig - - # approximate a/b by number of the form q * 2**e; adjust e if necessary - a, b = a << max(-e, 0), b << max(e, 0) - q, r = divmod(a, b) - if 2*r > b or 2*r == b and q & 1: - q += 1 - if q.bit_length() == mant_dig+1: - q //= 2 - e += 1 - - # double check that (q, e) has the right form - assert q.bit_length() <= mant_dig and e >= min_exp - mant_dig - assert q.bit_length() == mant_dig or e == min_exp - mant_dig - - # check for overflow and underflow - if e + q.bit_length() > max_exp: - return '-inf' if negative else 'inf' - if not q: - return '-0x0.0p+0' if negative else '0x0.0p+0' - - # for hex representation, shift so # bits after point is a multiple of 4 - hexdigs = 1 + (mant_dig-2)//4 - shift = 3 - (mant_dig-2)%4 - q, e = q << shift, e - shift - return '{}0x{:x}.{:0{}x}p{:+d}'.format( - '-' if negative else '', - q // 16**hexdigs, - q % 16**hexdigs, - hexdigs, - e + 4*hexdigs) - class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -1334,38 +1265,6 @@ else: self.identical(x, fromHex(toHex(x))) -class StrtodTestCase(unittest.TestCase): - def check_string(self, s): - expected = strtod(s) - try: - fs = float(s) - except OverflowError: - got = '-inf' if s[0] == '-' else 'inf' - else: - got = fs.hex() - self.assertEqual(expected, got, - "Incorrectly rounded str->float conversion for " - "{}: expected {}, got {}".format(s, expected, got)) - - @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', - "applies only when using short float repr style") - def test_bug7632(self): - # check a few particular values that gave incorrectly rounded - # results with previous versions of dtoa.c - test_strings = [ - '94393431193180696942841837085033647913224148539854e-358', - '12579816049008305546974391768996369464963024663104e-357', - '17489628565202117263145367596028389348922981857013e-357', - '18487398785991994634182916638542680759613590482273e-357', - '32002864200581033134358724675198044527469366773928e-358', - '73608278998966969345824653500136787876436005957953e-358', - '64774478836417299491718435234611299336288082136054e-358', - '13704940134126574534878641876947980878824688451169e-357', - '46697445774047060960624497964425416610480524760471e-358', - ] - for s in test_strings: - self.check_string(s) - def test_main(): support.run_unittest( @@ -1378,7 +1277,6 @@ RoundTestCase, InfNanTest, HexFloatTestCase, - StrtodTestCase, ) if __name__ == '__main__': Modified: python/branches/py3k/Lib/test/test_strtod.py ============================================================================== --- python/branches/py3k/Lib/test/test_strtod.py (original) +++ python/branches/py3k/Lib/test/test_strtod.py Sun Jun 20 22:01:04 2010 @@ -23,6 +23,8 @@ \Z """, re.VERBOSE | re.IGNORECASE).match +# Pure Python version of correctly rounded string->float conversion. +# Avoids any use of floating-point by returning the result as a hex string. def strtod(s, mant_dig=53, min_exp = -1021, max_exp = 1024): """Convert a finite decimal string to a hex string representing an IEEE 754 binary64 float. Return 'inf' or '-inf' on overflow. @@ -259,6 +261,10 @@ '18487398785991994634182916638542680759613590482273e-357', '32002864200581033134358724675198044527469366773928e-358', '94393431193180696942841837085033647913224148539854e-358', + '73608278998966969345824653500136787876436005957953e-358', + '64774478836417299491718435234611299336288082136054e-358', + '13704940134126574534878641876947980878824688451169e-357', + '46697445774047060960624497964425416610480524760471e-358', # failing case for bug introduced by METD in r77451 (attempted # fix for issue 7632, bug 2), and fixed in r77482. '28639097178261763178489759107321392745108491825303e-311', From python-checkins at python.org Sun Jun 20 23:04:52 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Jun 2010 23:04:52 +0200 Subject: [Python-checkins] distutils2: Added support for zipped eggs Message-ID: tarek.ziade pushed ce6942d3c4f2 to distutils2: http://hg.python.org/distutils2/rev/ce6942d3c4f2 changeset: 199:ce6942d3c4f2 parent: 187:48f3b9a445da user: Josip Djolonga date: Sat Jun 05 16:59:49 2010 +0200 summary: Added support for zipped eggs files: src/distutils2/_backport/pkgutil.py, src/distutils2/_backport/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO, src/distutils2/_backport/tests/fake_dists/towel_stuff-0.1.dist-info/METADATA, src/distutils2/depgraph.py, src/distutils2/metadata.py diff --git a/src/distutils2/_backport/pkgutil.py b/src/distutils2/_backport/pkgutil.py --- a/src/distutils2/_backport/pkgutil.py +++ b/src/distutils2/_backport/pkgutil.py @@ -12,6 +12,13 @@ from distutils2.errors import DistutilsError from distutils2.metadata import DistributionMetadata from distutils2.version import suggest_normalized_version, VersionPredicate +import zipimport +try: + import cStringIO as StringIO +except ImportError: + import StringIO +import re +import warnings __all__ = [ 'get_importer', 'iter_importers', 'get_loader', 'find_loader', @@ -726,12 +733,96 @@ metadata = None """A :class:`distutils2.metadata.DistributionMetadata` instance loaded with the distribution's METADATA file.""" + _REQUIREMENT = re.compile( \ + r'(?P[-A-Za-z0-9_.]+)\s*' \ + r'(?P(?:<|<=|!=|==|>=|>)[-A-Za-z0-9_.]+)?\s*' \ + r'(?P(?:\s*,\s*(?:<|<=|!=|==|>=|>)[-A-Za-z0-9_.]+)*)\s*' \ + r'(?P\[.*\])?') def __init__(self, path): - if os.path.isdir(path): - path = os.path.join(path, 'PKG-INFO') - self.metadata = DistributionMetadata(path=path) - self.name = self.metadata['name'] + + # reused from Distribute's pkg_resources + def yield_lines(strs): + """Yield non-empty/non-comment lines of a ``basestring`` or sequence""" + if isinstance(strs, basestring): + for s in strs.splitlines(): + s = s.strip() + if s and not s.startswith('#'): # skip blank lines/comments + yield s + else: + for ss in strs: + for s in yield_lines(ss): + yield s + + requires = None + if path.endswith('.egg'): + if os.path.isdir(path): + path = os.path.join(path, 'EGG-INFO', 'PKG-INFO') + self.metadata = DistributionMetadata(path=path) + try: + req_path = os.path.join(path, 'EGG_INFO', 'requires.txt') + requires = open(req_path, 'r').read() + except IOError: + requires = None + else: + zipf = zipimport.zipimporter(path) + fileobj = StringIO.StringIO(zipf.get_data('EGG-INFO/PKG-INFO')) + self.metadata = DistributionMetadata(fileobj=fileobj) + try: + requires = zipf.get_data('EGG-INFO/requires.txt') + except IOError: + requires = None + elif path.endswith('.egg-info'): + if os.path.isdir(path): + path = os.path.join(path, 'PKG-INFO') + try: + req_f = open(os.path.join(path, 'requires.txt'), 'r') + requires = req_f.read() + except IOError: + requires = None + self.metadata = DistributionMetadata(path=path) + self.name = self.metadata['name'] + else: + raise ValueError('The path must end with .egg-info or .egg') + + provides = "%s (%s)" % (self.metadata['name'], + self.metadata['version']) + if self.metadata['Metadata-Version'] == '1.2': + self.metadata['Provides-Dist'] += (provides,) + else: + self.metadata['Provides'] += (provides,) + reqs = [] + if requires is not None: + for line in yield_lines(requires): + if line[0] == '[': + warnings.warn('distutils2 does not support extensions in requires.txt') + break + else: + match = _REQUIREMENT.match(line.strip()) + if not match: + raise ValueError('Distribution %s has ill formed ' + 'requires.txt file (%s)' % + (self.name, line)) + else: + if match.group('extra'): + s = 'Distribution %s uses extra requirements which'\ + ' are not supported in distutils' % (self.name) + warnings.warn(s) + name = match.group('name') + version = None + if match.group('first'): + version = match.group('first') + if match.group('rest'): + version += match.group('rest') + version = version.replace(' ', '') # trim spaces + if version is None: + reqs.append(name) + else: + reqs.append('%s (%s)' % (name, version)) + if self.metadata['Metadata-Version'] == '1.2': + self.metadata['Requires-Dist'] += reqs + else: + self.metadata['Requires'] += reqs def get_installed_files(self, local=False): return [] @@ -792,7 +883,8 @@ if dir.endswith('.dist-info'): dist = Distribution(os.path.join(realpath, dir)) yield dist - elif use_egg_info and dir.endswith('.egg-info'): + elif use_egg_info and (dir.endswith('.egg-info') or + dir.endswith('.egg')): dist = EggInfoDistribution(os.path.join(realpath, dir)) yield dist @@ -887,7 +979,7 @@ provided = dist.metadata['Provides-Dist'] + dist.metadata['Provides'] for p in provided: - p_components = p.split(' ', 1) + p_components = p.rsplit(' ', 1) if len(p_components) == 1 or predicate is None: if name == p_components[0]: yield dist @@ -896,7 +988,7 @@ p_name, p_ver = p_components if len(p_ver) < 2 or p_ver[0] != '(' or p_ver[-1] != ')': raise DistutilsError(('Distribution %s has invalid ' + - 'provides field') % (dist.name,)) + 'provides field: %s') % (dist.name,p)) p_ver = p_ver[1:-1] # trim off the parenthesis if p_name == name and predicate.match(p_ver): yield dist diff --git a/src/distutils2/_backport/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO b/src/distutils2/_backport/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO --- a/src/distutils2/_backport/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO +++ b/src/distutils2/_backport/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO @@ -2,4 +2,5 @@ Name: bacon Version: 0.1 Provides-Dist: truffles (2.0) +Provides-Dist: bacon (0.1) Obsoletes-Dist: truffles (>=0.9,<=1.5) diff --git a/src/distutils2/_backport/tests/fake_dists/towel_stuff-0.1.dist-info/METADATA b/src/distutils2/_backport/tests/fake_dists/towel_stuff-0.1.dist-info/METADATA --- a/src/distutils2/_backport/tests/fake_dists/towel_stuff-0.1.dist-info/METADATA +++ b/src/distutils2/_backport/tests/fake_dists/towel_stuff-0.1.dist-info/METADATA @@ -2,4 +2,6 @@ Name: towel-stuff Version: 0.1 Provides-Dist: truffles (1.1.2) +Provides-Dist: towel-stuff (0.1) Obsoletes-Dist: truffles (!=0.8,<1.0) +Requires-Dist: bacon (<=0.2) diff --git a/src/distutils2/depgraph.py b/src/distutils2/depgraph.py --- a/src/distutils2/depgraph.py +++ b/src/distutils2/depgraph.py @@ -60,40 +60,41 @@ """ self.missing[distribution].append(requirement) - def to_dot(self, f, skip_disconnected=True): - """ - Writes a DOT output for the graph to the provided *file*. - If *skip_disconnected* is set to ``True``, then all distributions - that are not dependent on any other distributions are skipped. - :type f: ``file`` - ;type skip_disconnected: ``bool`` - """ - if not isinstance(f, file): - raise TypeError('the argument has to be of type file') +def graph_to_dot(graph, f, skip_disconnected=True): + """ + Writes a DOT output for the graph to the provided *file*. + If *skip_disconnected* is set to ``True``, then all distributions + that are not dependent on any other distributions are skipped. - disconnected = [] + :type f: ``file`` + ;type skip_disconnected: ``bool`` + """ + if not isinstance(f, file): + raise TypeError('the argument has to be of type file') - f.write("digraph dependencies {\n") - for dist, adjs in self.adjacency_list.iteritems(): - if len(adjs) == 0 and not skip_disconnected: - disconnected.append(dist) - for (other, label) in adjs: - if not label is None: - f.write('"%s" -> "%s" [label="%s"]\n' % - (dist.name, other.name, label)) - else: - f.write('"%s" -> "%s"\n' % (dist.name, other.name)) - if not skip_disconnected and len(disconnected) > 0: - f.write('subgraph disconnected {\n') - f.write('label = "Disconnected"\n') - f.write('bgcolor = red\n') + disconnected = [] - for dist in disconnected: - f.write('"%s"' % dist.name) - f.write('\n') - f.write('}\n') + f.write("digraph dependencies {\n") + for dist, adjs in graph.adjacency_list.iteritems(): + if len(adjs) == 0 and not skip_disconnected: + disconnected.append(dist) + for (other, label) in adjs: + if not label is None: + f.write('"%s" -> "%s" [label="%s"]\n' % + (dist.name, other.name, label)) + else: + f.write('"%s" -> "%s"\n' % (dist.name, other.name)) + if not skip_disconnected and len(disconnected) > 0: + f.write('subgraph disconnected {\n') + f.write('label = "Disconnected"\n') + f.write('bgcolor = red\n') + + for dist in disconnected: + f.write('"%s"' % dist.name) + f.write('\n') f.write('}\n') + f.write('}\n') def generate_graph(dists): diff --git a/src/distutils2/metadata.py b/src/distutils2/metadata.py --- a/src/distutils2/metadata.py +++ b/src/distutils2/metadata.py @@ -186,13 +186,15 @@ """Distribution meta-data class (1.0 or 1.2). """ def __init__(self, path=None, platform_dependant=False, - execution_context=None): + execution_context=None, fileobj=None): self._fields = {} self.version = None self.docutils_support = _HAS_DOCUTILS self.platform_dependant = platform_dependant if path is not None: self.read(path) + elif fileobj is not None: + self.read_file(fileobj) self.execution_context = execution_context def _set_best_version(self): -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sun Jun 20 23:04:52 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Jun 2010 23:04:52 +0200 Subject: [Python-checkins] distutils2: Finishing support for eggs, the test suite is left Message-ID: tarek.ziade pushed 947dc2559ea3 to distutils2: http://hg.python.org/distutils2/rev/947dc2559ea3 changeset: 200:947dc2559ea3 user: Josip Djolonga date: Sun Jun 06 15:15:07 2010 +0200 summary: Finishing support for eggs, the test suite is left files: src/distutils2/_backport/pkgutil.py, src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/PKG-INFO, src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/SOURCES.txt, src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/dependency_links.txt, src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/entry_points.txt, src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/not-zip-safe, src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/requires.txt, src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/top_level.txt, src/distutils2/_backport/tests/fake_dists/strawberry-0.6.egg, src/distutils2/depgraph.py diff --git a/src/distutils2/_backport/pkgutil.py b/src/distutils2/_backport/pkgutil.py --- a/src/distutils2/_backport/pkgutil.py +++ b/src/distutils2/_backport/pkgutil.py @@ -749,18 +749,18 @@ s = s.strip() if s and not s.startswith('#'): # skip blank lines/comments yield s - else: - for ss in strs: - for s in yield_lines(ss): - yield s + else: + for ss in strs: + for s in yield_lines(ss): + yield s requires = None if path.endswith('.egg'): if os.path.isdir(path): - path = os.path.join(path, 'EGG-INFO', 'PKG-INFO') - self.metadata = DistributionMetadata(path=path) + meta_path = os.path.join(path, 'EGG-INFO', 'PKG-INFO') + self.metadata = DistributionMetadata(path=meta_path) try: - req_path = os.path.join(path, 'EGG_INFO', 'requires.txt') + req_path = os.path.join(path, 'EGG-INFO', 'requires.txt') requires = open(req_path, 'r').read() except IOError: requires = None @@ -772,6 +772,7 @@ requires = zipf.get_data('EGG-INFO/requires.txt') except IOError: requires = None + self.name = self.metadata['name'] elif path.endswith('.egg-info'): if os.path.isdir(path): path = os.path.join(path, 'PKG-INFO') @@ -798,13 +799,13 @@ warnings.warn('distutils2 does not support extensions in requires.txt') break else: - match = _REQUIREMENT.match(line.strip()) + match = self._REQUIREMENT.match(line.strip()) if not match: raise ValueError('Distribution %s has ill formed ' 'requires.txt file (%s)' % (self.name, line)) else: - if match.group('extra'): + if match.group('extras'): s = 'Distribution %s uses extra requirements which'\ ' are not supported in distutils' % (self.name) warnings.warn(s) diff --git a/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/PKG-INFO b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/PKG-INFO new file mode 100644 --- /dev/null +++ b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/PKG-INFO @@ -0,0 +1,18 @@ +Metadata-Version: 1.0 +Name: banana +Version: 0.4 +Summary: A yellow fruit +Home-page: http://en.wikipedia.org/wiki/Banana +Author: Josip Djolonga +Author-email: foo at nbar.com +License: BSD +Description: A fruit +Keywords: foo bar +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Science/Research +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Scientific/Engineering :: GIS diff --git a/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/SOURCES.txt b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/SOURCES.txt new file mode 100644 diff --git a/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/dependency_links.txt b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/dependency_links.txt new file mode 100644 --- /dev/null +++ b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/dependency_links.txt @@ -0,0 +1,1 @@ + diff --git a/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/entry_points.txt b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/entry_points.txt new file mode 100644 --- /dev/null +++ b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/entry_points.txt @@ -0,0 +1,3 @@ + + # -*- Entry points: -*- + \ No newline at end of file diff --git a/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/not-zip-safe b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/not-zip-safe new file mode 100644 --- /dev/null +++ b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/not-zip-safe @@ -0,0 +1,1 @@ + diff --git a/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/requires.txt b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/requires.txt new file mode 100644 --- /dev/null +++ b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/requires.txt @@ -0,0 +1,6 @@ +# this should be ignored + +strawberry >=0.5 + +[section ignored] +foo ==0.5 diff --git a/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/top_level.txt b/src/distutils2/_backport/tests/fake_dists/banana-0.4.egg/EGG-INFO/top_level.txt new file mode 100644 diff --git a/src/distutils2/_backport/tests/fake_dists/strawberry-0.6.egg b/src/distutils2/_backport/tests/fake_dists/strawberry-0.6.egg new file mode 100644 index 0000000000000000000000000000000000000000..6d160e8b161031ae52638514843592187925b757 GIT binary patch literal 1402 zc$`yK)KALH(=X28%1l#;R!B%nEKbc!%uQ8LF-TCbRZuEUEh#N1$r9UQWv|0ty0Ufu2)H%gjmDgJ}xL0otCbPy`8 at OrXVy z$=M1e`3iV~M*-+)g_5F5g~as4%sjABpm0h{1UV)xlPkcRnT3l11j?rGw_!j6Vhl12 zuI}!-o_=or`X%`V at j0nwsX2Nj6(yk|oD9qiubF*7xU_i9RnLxBqqeU~_GC)B*8Q%^m+PITr6Z&8t31F+o4>xK^{d-p7?^ zx~J#&ZkWuS9 0: print("Missing dependencies for %s: %s" % (dist.name, ", ".join(reqs))) - f = open('output.dot', 'w') - graph.to_dot(f, True) + f = open('/home/josip/Desktop/output.dot', 'w') + graph_to_dot(graph, f, True) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sun Jun 20 23:04:52 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Jun 2010 23:04:52 +0200 Subject: [Python-checkins] distutils2: Started writing documentation Message-ID: tarek.ziade pushed 22d3939f9c82 to distutils2: http://hg.python.org/distutils2/rev/22d3939f9c82 changeset: 203:22d3939f9c82 user: Josip Djolonga date: Fri Jun 11 15:37:07 2010 +0200 summary: Started writing documentation files: docs/source/conf.py, docs/source/index.rst, docs/source/pkgutil.rst, src/distutils2/_backport/pkgutil.py diff --git a/docs/source/conf.py b/docs/source/conf.py --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -17,12 +17,13 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.append(os.path.abspath('.')) +sys.path.append(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'src'))) # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [] +extensions = ['sphinx.ext.autodoc'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/docs/source/index.rst b/docs/source/index.rst --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -12,6 +12,7 @@ :maxdepth: 2 metadata + pkgutil Indices and tables ================== diff --git a/docs/source/pkgutil.rst b/docs/source/pkgutil.rst new file mode 100644 --- /dev/null +++ b/docs/source/pkgutil.rst @@ -0,0 +1,9 @@ +======= +pkgutil +======= + +API Reference +============= + +.. automodule:: distutils2._backport.pkgutil + :members: diff --git a/src/distutils2/_backport/pkgutil.py b/src/distutils2/_backport/pkgutil.py --- a/src/distutils2/_backport/pkgutil.py +++ b/src/distutils2/_backport/pkgutil.py @@ -502,11 +502,11 @@ if one wants to distribute different parts of a single logical package as multiple directories. - It also looks for *.pkg files beginning where * matches the name - argument. This feature is similar to *.pth files (see site.py), + It also looks for \*.pkg files beginning where \* matches the name + argument. This feature is similar to \*.pth files (see site.py), except that it doesn't special-case lines starting with 'import'. - A *.pkg file is trusted at face value: apart from checking for - duplicates, all entries found in a *.pkg file are added to the + A \*.pkg file is trusted at face value: apart from checking for + duplicates, all entries found in a \*.pkg file are added to the path, regardless of whether they are exist the filesystem. (This is a feature.) @@ -651,8 +651,10 @@ ``'/'`` have been replaced by the system separator given by ``os.sep``. :parameter local: flag to say if the path should be returned a local absolute path + :type local: boolean :returns: iterator of (path, md5, size) + """ return self._get_records(local) @@ -989,7 +991,8 @@ p_name, p_ver = p_components if len(p_ver) < 2 or p_ver[0] != '(' or p_ver[-1] != ')': raise DistutilsError(('Distribution %s has invalid ' + - 'provides field: %s') % (dist.name,p)) + 'provides field: %s') \ + % (dist.name, p)) p_ver = p_ver[1:-1] # trim off the parenthesis if p_name == name and predicate.match(p_ver): yield dist -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sun Jun 20 23:04:52 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Jun 2010 23:04:52 +0200 Subject: [Python-checkins] distutils2: Finishing documentation, examples are left Message-ID: tarek.ziade pushed 4618d201db9b to distutils2: http://hg.python.org/distutils2/rev/4618d201db9b changeset: 205:4618d201db9b user: Josip Djolonga date: Fri Jun 11 21:53:51 2010 +0200 summary: Finishing documentation, examples are left files: docs/source/depgraph.rst, docs/source/index.rst, docs/source/metadata.rst, docs/source/pkgutil.rst, src/distutils2/_backport/pkgutil.py, src/distutils2/depgraph.py diff --git a/docs/source/depgraph.rst b/docs/source/depgraph.rst new file mode 100644 --- /dev/null +++ b/docs/source/depgraph.rst @@ -0,0 +1,25 @@ +=============================== +Dependency Graph Builder Module +=============================== + +Introduction +------------ + +This module provides the means to create a graph of dependencies from a list +of :class:`distutils2._backport.pkgutil.Distribution` and +:class:`distutils2._backport.pkgutil.EggInfoDistribution` instances. The graph +is represented by the :class:`distutils2.depgraph.DependencyGraph` class that +keeps internally an adjacency list. Several functions are provided that +generate a graph in different manners. First, all of them are documented and +then several use case examples are provided along with graphviz illustrations +of the generated graphs. + +API +--- + +.. automodule:: distutils2.depgraph + :members: + +Example Usage +------------- + diff --git a/docs/source/index.rst b/docs/source/index.rst --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,6 +13,7 @@ metadata pkgutil + depgraph Indices and tables ================== diff --git a/docs/source/metadata.rst b/docs/source/metadata.rst --- a/docs/source/metadata.rst +++ b/docs/source/metadata.rst @@ -5,13 +5,13 @@ Distutils2 provides a :class:`DistributionMetadata` class that can read and write Metadata files. This class is compatible with all versions of Metadata: -- 1.0 : PEP 241 -- 1.1 : PEP 314 -- 1.2 : PEP 345 +* 1.0 : :pep:`241` +* 1.1 : :pep:`314` +* 1.2 : :pep:`345` -The PEP 345 implementation supports the micro-language for the environment +The :pep:`345` implementation supports the micro-language for the environment markers, and displays warnings when versions that are supposed to be -PEP 386 are violating the scheme. +:pep:`386` are violating the scheme. Reading metadata @@ -78,7 +78,7 @@ Conflict checking and best version ================================== -Some fields in PEP 345 have to follow a version scheme in their versions +Some fields in :pep:`345` have to follow a version scheme in their versions predicate. When the scheme is violated, a warning is emited:: >>> from distutils2.metadata import DistributionMetadata @@ -89,7 +89,7 @@ -XXX talk about check() +.. TODO talk about check() diff --git a/docs/source/pkgutil.rst b/docs/source/pkgutil.rst --- a/docs/source/pkgutil.rst +++ b/docs/source/pkgutil.rst @@ -2,8 +2,44 @@ pkgutil ======= +Introduction +============ + +This module provides the necessary functions to provide support for +the "Importer Protocol" as described in :pep:`302` and for working with +the database of installed Python distributions which is specified in +:pep:`376`. In addition to the functions required in :pep:`376`, back support +for older ``.egg`` and ``.egg-info`` distributions is provided as well. These +distributions are represented by the class +:class:`distutils2._backport.pkgutil.EggInfoDistribution` and +most functions provide an extra argument ``use_egg_info`` which indicates if +they should consider these old styled distributions. In this document, +first a complete documentation of the functions and classes +is provided and then several use cases are presented. + API Reference ============= .. automodule:: distutils2._backport.pkgutil :members: + +Example Usage +============= + +* Doing this and that:: + + import sys + + # first compute a + a = x+2 + # then print it out to stdin + print(a) + +* And that and this:: + + from foo import bar + + z = lambda x,y: x^2 + y + + + diff --git a/src/distutils2/_backport/pkgutil.py b/src/distutils2/_backport/pkgutil.py --- a/src/distutils2/_backport/pkgutil.py +++ b/src/distutils2/_backport/pkgutil.py @@ -1,4 +1,4 @@ -"""Utilities to support packages.""" +# Utilities to support packages. # NOTE: This module must remain compatible with Python 2.3, as it is shared # by setuptools for distribution with Python 2.3 and up. @@ -22,7 +22,7 @@ __all__ = [ 'get_importer', 'iter_importers', 'get_loader', 'find_loader', - 'walk_packages', 'iter_modules', + 'walk_packages', 'iter_modules', 'get_data', 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path', 'Distribution', 'EggInfoDistribution', 'distinfo_dirname', 'get_distributions', 'get_distribution', 'get_file_users', @@ -31,7 +31,7 @@ def read_code(stream): - # This helper is needed in order for the PEP 302 emulation to + # This helper is needed in order for the :pep:`302` emulation to # correctly handle compiled files import marshal @@ -86,32 +86,34 @@ def walk_packages(path=None, prefix='', onerror=None): - """Yields (module_loader, name, ispkg) for all modules recursively - on path, or, if path is None, all accessible modules. + """Yields ``(module_loader, name, ispkg)`` for all modules recursively + on *path*, or, if *path* is ``None``, all accessible modules. - 'path' should be either None or a list of paths to look for - modules in. + :parameter path: should be either ``None`` or a list of paths to look for + modules in. + :parameter prefix: is a string to output on the front of every module name + on output. - 'prefix' is a string to output on the front of every module name - on output. - - Note that this function must import all *packages* (NOT all - modules!) on the given path, in order to access the __path__ + Note that this function must import all packages (NOT all + modules!) on the given path, in order to access the ``__path__`` attribute to find submodules. - 'onerror' is a function which gets called with one argument (the + *onerror* is a function which gets called with one argument (the name of the package which was being imported) if any exception occurs while trying to import a package. If no onerror function is - supplied, ImportErrors are caught and ignored, while all other + supplied, ``ImportErrors`` are caught and ignored, while all other exceptions are propagated, terminating the search. Examples: - # list all modules python can access - walk_packages() + * list all modules python can access:: - # list all submodules of ctypes - walk_packages(ctypes.__path__, ctypes.__name__+'.') + walk_packages() + + * list all submodules of ctypes:: + + walk_packages(ctypes.__path__, ctypes.__name__+'.') + """ def seen(p, m={}): @@ -144,14 +146,14 @@ def iter_modules(path=None, prefix=''): - """Yields (module_loader, name, ispkg) for all submodules on path, - or, if path is None, all top-level modules on sys.path. + """Yields ``(module_loader, name, ispkg)`` for all submodules on path, + or, if *path* is ``None``, all top-level modules on ``sys.path``. - 'path' should be either None or a list of paths to look for - modules in. + :parameter path: should be either None or a list of paths to look for + modules in. + :parameter prefix: is a string to output on the front of every module name + on output. - 'prefix' is a string to output on the front of every module name - on output. """ if path is None: @@ -169,6 +171,7 @@ #@simplegeneric def iter_importer_modules(importer, prefix=''): + "" if not hasattr(importer, 'iter_modules'): return [] return importer.iter_modules(prefix) @@ -177,14 +180,15 @@ class ImpImporter: - """PEP 302 Importer that wraps Python's "classic" import algorithm + """:pep:`302` Importer that wraps Python's "classic" import algorithm - ImpImporter(dirname) produces a PEP 302 importer that searches that - directory. ImpImporter(None) produces a PEP 302 importer that searches - the current sys.path, plus any modules that are frozen or built-in. + ``ImpImporter(dirname)`` produces a :pep:`302` importer that searches that + directory. ``ImpImporter(None)`` produces a :pep:`302` importer that + searches the current ``sys.path``, plus any modules that are frozen + or built-in. - Note that ImpImporter does not currently support being used by placement - on sys.meta_path. + Note that :class:`ImpImporter` does not currently support being used by placement + on ``sys.meta_path``. """ def __init__(self, path=None): @@ -239,8 +243,8 @@ class ImpLoader: - """PEP 302 Loader that wraps Python's "classic" import algorithm - """ + """:pep:`302` Loader that wraps Python's "classic" import algorithm """ + code = source = None def __init__(self, fullname, file, filename, etc): @@ -372,17 +376,17 @@ def get_importer(path_item): - """Retrieve a PEP 302 importer for the given path item + """Retrieve a :pep:`302` importer for the given path item - The returned importer is cached in sys.path_importer_cache + The returned importer is cached in ``sys.path_importer_cache`` if it was newly created by a path hook. If there is no importer, a wrapper around the basic import machinery is returned. This wrapper is never inserted into - the importer cache (None is inserted instead). + the importer cache (``None`` is inserted instead). The cache (or part of it) can be cleared manually if a - rescan of sys.path_hooks is necessary. + rescan of ``sys.path_hooks`` is necessary. """ try: importer = sys.path_importer_cache[path_item] @@ -406,7 +410,7 @@ def iter_importers(fullname=""): - """Yield PEP 302 importers for the given module name + """Yield :pep:`302` importers for the given module name If fullname contains a '.', the importers will be for the package containing fullname, otherwise they will be importers for sys.meta_path, @@ -414,20 +418,20 @@ the named module is in a package, that package is imported as a side effect of invoking this function. - Non PEP 302 mechanisms (e.g. the Windows registry) used by the + Non :pep:`302` mechanisms (e.g. the Windows registry) used by the standard import machinery to find files in alternative locations - are partially supported, but are searched AFTER sys.path. Normally, - these locations are searched BEFORE sys.path, preventing sys.path + are partially supported, but are searched AFTER ``sys.path``. Normally, + these locations are searched BEFORE sys.path, preventing ``sys.path`` entries from shadowing them. For this to cause a visible difference in behaviour, there must be a module or package name that is accessible via both sys.path - and one of the non PEP 302 file system mechanisms. In this case, + and one of the non :pep:`302` file system mechanisms. In this case, the emulation will find the former version, while the builtin import mechanism will find the latter. Items of the following types can be affected by this discrepancy: - imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY + ``imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY`` """ if fullname.startswith('.'): raise ImportError("Relative module names not supported") @@ -448,15 +452,15 @@ def get_loader(module_or_name): - """Get a PEP 302 "loader" object for module_or_name + """Get a :pep:`302` "loader" object for module_or_name If the module or package is accessible via the normal import mechanism, a wrapper around the relevant part of that machinery is returned. Returns None if the module cannot be found or imported. If the named module is not already imported, its containing package - (if any) is imported, in order to establish the package __path__. + (if any) is imported, in order to establish the package ``__path__``. - This function uses iter_importers(), and is thus subject to the same + This function uses :func:`iter_importers`, and is thus subject to the same limitations regarding platform-specific special import locations such as the Windows registry. """ @@ -474,12 +478,13 @@ def find_loader(fullname): - """Find a PEP 302 "loader" object for fullname + """Find a :pep:`302` "loader" object for fullname - If fullname contains dots, path must be the containing package's __path__. - Returns None if the module cannot be found or imported. This function uses - iter_importers(), and is thus subject to the same limitations regarding - platform-specific special import locations such as the Windows registry. + If fullname contains dots, path must be the containing package's + ``__path__``. Returns ``None`` if the module cannot be found or imported. + This function uses :func:`iter_importers`, and is thus subject to the same + limitations regarding platform-specific special import locations such as + the Windows registry. """ for importer in iter_importers(fullname): loader = importer.find_module(fullname) @@ -492,21 +497,22 @@ def extend_path(path, name): """Extend a package's path. - Intended use is to place the following code in a package's __init__.py: + Intended use is to place the following code in a package's + ``__init__.py``:: from pkgutil import extend_path __path__ = extend_path(__path__, __name__) - This will add to the package's __path__ all subdirectories of - directories on sys.path named after the package. This is useful + This will add to the package's ``__path__`` all subdirectories of + directories on ``sys.path`` named after the package. This is useful if one wants to distribute different parts of a single logical package as multiple directories. - It also looks for \*.pkg files beginning where \* matches the name - argument. This feature is similar to \*.pth files (see site.py), - except that it doesn't special-case lines starting with 'import'. - A \*.pkg file is trusted at face value: apart from checking for - duplicates, all entries found in a \*.pkg file are added to the + It also looks for ``*.pkg`` files beginning where ``*`` matches the name + argument. This feature is similar to ``*.pth`` files (see ``site.py``), + except that it doesn't special-case lines starting with ``import``. + A ``*.pkg`` file is trusted at face value: apart from checking for + duplicates, all entries found in a ``*.pkg`` file are added to the path, regardless of whether they are exist the filesystem. (This is a feature.) @@ -519,7 +525,7 @@ are not (unicode or 8-bit) strings referring to existing directories are ignored. Unicode items of sys.path that cause errors when used as filenames may cause this function to raise an - exception (in line with os.path.isdir() behavior). + exception (in line with ``os.path.isdir()`` behavior). """ if not isinstance(path, list): @@ -567,23 +573,23 @@ def get_data(package, resource): """Get a resource from a package. - This is a wrapper round the PEP 302 loader get_data API. The package + This is a wrapper round the :pep:`302` loader get_data API. The package argument should be the name of a package, in standard module format - (foo.bar). The resource argument should be in the form of a relative - filename, using '/' as the path separator. The parent directory name '..' - is not allowed, and nor is a rooted name (starting with a '/'). + (``foo.bar``). The resource argument should be in the form of a relative + filename, using ``'/'`` as the path separator. The parent directory name + ``'..'`` is not allowed, and nor is a rooted name (starting with a ``'/'``). The function returns a binary string, which is the contents of the specified resource. For packages located in the filesystem, which have already been imported, - this is the rough equivalent of + this is the rough equivalent of:: d = os.path.dirname(sys.modules[package].__file__) data = open(os.path.join(d, resource), 'rb').read() - If the package cannot be located or loaded, or it uses a PEP 302 loader - which does not support get_data(), then None is returned. + If the package cannot be located or loaded, or it uses a :pep:`302` loader + which does not support :func:`get_data`, then ``None`` is returned. """ loader = get_loader(package) @@ -610,7 +616,7 @@ class Distribution(object): """Created with the *path* of the ``.dist-info`` directory provided to the - constructor. It reads the metadata contained in METADATA when it is + constructor. It reads the metadata contained in ``METADATA`` when it is instantiated.""" # Attribute documenting for Sphinx style documentation, see for more info: @@ -619,9 +625,9 @@ """The name of the distribution.""" metadata = None """A :class:`distutils2.metadata.DistributionMetadata` instance loaded with - the distribution's METADATA file.""" + the distribution's ``METADATA`` file.""" requested = False - """A boolean that indicates whether the REQUESTED metadata file is present + """A boolean that indicates whether the ``REQUESTED`` metadata file is present (in other words, whether the package was installed by user request).""" def __init__(self, path): @@ -642,10 +648,10 @@ def get_installed_files(self, local=False): """ - Iterates over the RECORD entries and returns a tuple (path, md5, size) - for each line. If *local* is ``True``, the returned path is transformed - into a local absolute path. Otherwise the raw value from RECORD is - returned. + Iterates over the ``RECORD`` entries and returns a tuple + ``(path, md5, size)`` for each line. If *local* is ``True``, + the returned path is transformed into a local absolute path. + Otherwise the raw value from RECORD is returned. A local absolute path is an absolute path in which occurrences of ``'/'`` have been replaced by the system separator given by ``os.sep``. @@ -660,7 +666,7 @@ def uses(self, path): """ - Returns ``True`` if path is listed in RECORD. *path* can be a local + Returns ``True`` if path is listed in ``RECORD``. *path* can be a local absolute path or a relative ``'/'``-separated path. :rtype: boolean @@ -682,8 +688,8 @@ directory path, a :class:`DistutilsError` is raised :type path: string :parameter binary: If *binary* is ``True``, opens the file in read-only - binary mode (rb), otherwise opens it in read-only - mode (r). + binary mode (``rb``), otherwise opens it in read-only + mode (``r``). :rtype: file object """ open_flags = 'r' @@ -710,13 +716,13 @@ def get_distinfo_files(self, local=False): """ - Iterates over the RECORD entries and returns paths for each line if the - path is pointing to a file located in the ``.dist-info`` directory or - one of its subdirectories. + Iterates over the ``RECORD`` entries and returns paths for each line if + the path is pointing to a file located in the ``.dist-info`` directory + or one of its subdirectories. :parameter local: If *local* is ``True``, each returned path is transformed into a local absolute path. Otherwise the - raw value from RECORD is returned. + raw value from ``RECORD`` is returned. :type local: boolean :returns: iterator of paths """ @@ -728,13 +734,13 @@ """Created with the *path* of the ``.egg-info`` directory or file provided to the constructor. It reads the metadata contained in the file itself, or if the given path happens to be a directory, the metadata is read from the - file PKG-INFO under that directory.""" + file ``PKG-INFO`` under that directory.""" name = '' """The name of the distribution.""" metadata = None """A :class:`distutils2.metadata.DistributionMetadata` instance loaded with - the distribution's METADATA file.""" + the distribution's ``METADATA`` file.""" _REQUIREMENT = re.compile( \ r'(?P[-A-Za-z0-9_.]+)\s*' \ r'(?P(?:<|<=|!=|==|>=|>)[-A-Za-z0-9_.]+)?\s*' \ @@ -896,8 +902,8 @@ """ Scans all elements in ``sys.path`` and looks for all directories ending with ``.dist-info``. Returns a :class:`Distribution` corresponding to the - ``.dist-info`` directory that contains the METADATA that matches *name* for - the *name* metadata field. + ``.dist-info`` directory that contains the ``METADATA`` that matches *name* + for the *name* metadata field. If no distribution exists with the given *name* and the parameter *use_egg_info* is set to ``True``, then all files and directories ending with ``.egg-info`` are scanned. A :class:`EggInfoDistribution` instance is diff --git a/src/distutils2/depgraph.py b/src/distutils2/depgraph.py --- a/src/distutils2/depgraph.py +++ b/src/distutils2/depgraph.py @@ -7,7 +7,7 @@ from distutils2.errors import DistutilsError from distutils2.version import VersionPredicate -__all__ = ['DependencyGraph', 'generate_graph'] +__all__ = ['DependencyGraph', 'generate_graph', 'dependent_dists'] class DependencyGraph(object): -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sun Jun 20 23:04:52 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Jun 2010 23:04:52 +0200 Subject: [Python-checkins] distutils2: Made the test suite pep8 conformant, and added cases for .egg distributions Message-ID: tarek.ziade pushed b7a4b2e06644 to distutils2: http://hg.python.org/distutils2/rev/b7a4b2e06644 changeset: 201:b7a4b2e06644 user: Josip Djolonga date: Sun Jun 06 16:13:17 2010 +0200 summary: Made the test suite pep8 conformant, and added cases for .egg distributions files: src/distutils2/_backport/tests/test_pkgutil.py diff --git a/src/distutils2/_backport/tests/test_pkgutil.py b/src/distutils2/_backport/tests/test_pkgutil.py --- a/src/distutils2/_backport/tests/test_pkgutil.py +++ b/src/distutils2/_backport/tests/test_pkgutil.py @@ -18,6 +18,7 @@ # TODO Add a test for absolute pathed RECORD items (e.g. /etc/myapp/config.ini) + class TestPkgUtilDistribution(unittest2.TestCase): """Tests the pkgutil.Distribution class""" @@ -26,15 +27,16 @@ self.fake_dists_path = os.path.abspath( os.path.join(os.path.dirname(__file__), 'fake_dists')) - self.distinfo_dirs = [ os.path.join(self.fake_dists_path, dir) + + self.distinfo_dirs = [os.path.join(self.fake_dists_path, dir) for dir in os.listdir(self.fake_dists_path) - if dir.endswith('.dist-info') - ] + if dir.endswith('.dist-info')] def get_hexdigest(file): md5_hash = md5() md5_hash.update(open(file).read()) return md5_hash.hexdigest() + def record_pieces(file): path = os.path.relpath(file, sys.prefix) digest = get_hexdigest(file) @@ -51,7 +53,8 @@ for path, dirs, files in os.walk(dist_location): for f in files: - record_writer.writerow(record_pieces(os.path.join(path, f))) + record_writer.writerow(record_pieces( + os.path.join(path, f))) for file in ['INSTALLER', 'METADATA', 'REQUESTED']: record_writer.writerow(record_pieces( os.path.join(distinfo_dir, file))) @@ -60,7 +63,8 @@ record_reader = csv.reader(open(record_file, 'rb')) record_data = [] for row in record_reader: - path, md5_, size = row[:] + [ None for i in xrange(len(row), 3) ] + path, md5_, size = row[:] + \ + [None for i in xrange(len(row), 3)] record_data.append([path, (md5_, size,)]) self.records[distinfo_dir] = dict(record_data) @@ -108,7 +112,8 @@ distinfo_name = 'grammar-1.0a4' distinfo_dir = os.path.join(self.fake_dists_path, distinfo_name + '.dist-info') - true_path = [self.fake_dists_path, distinfo_name, 'grammar', 'utils.py'] + true_path = [self.fake_dists_path, distinfo_name, \ + 'grammar', 'utils.py'] true_path = os.path.relpath(os.path.join(*true_path), sys.prefix) false_path = [self.fake_dists_path, 'towel_stuff-0.1', 'towel_stuff', '__init__.py'] @@ -150,7 +155,8 @@ self.assertRaises(DistutilsError, dist.get_distinfo_file, other_distinfo_file) # Test for a file that does not exist and should not exist - self.assertRaises(DistutilsError, dist.get_distinfo_file, 'ENTRYPOINTS') + self.assertRaises(DistutilsError, dist.get_distinfo_file, \ + 'ENTRYPOINTS') def test_get_distinfo_files(self): """Test for the iteration of RECORD path entries.""" @@ -161,13 +167,12 @@ dist = Distribution(distinfo_dir) # Test for the iteration of the raw path distinfo_record_paths = self.records[distinfo_dir].keys() - found = [ path for path in dist.get_distinfo_files() ] + found = [path for path in dist.get_distinfo_files()] self.assertEqual(sorted(found), sorted(distinfo_record_paths)) # Test for the iteration of local absolute paths - distinfo_record_paths = [ os.path.join(sys.prefix, path) - for path in self.records[distinfo_dir].keys() - ] - found = [ path for path in dist.get_distinfo_files(local=True) ] + distinfo_record_paths = [os.path.join(sys.prefix, path) + for path in self.records[distinfo_dir].keys()] + found = [path for path in dist.get_distinfo_files(local=True)] self.assertEqual(sorted(found), sorted(distinfo_record_paths)) @@ -190,8 +195,9 @@ """Given a name and a version, we expect the distinfo_dirname function to return a standard distribution information directory name.""" - items = [ # (name, version, standard_dirname) - # Test for a very simple single word name and decimal version number + items = [# (name, version, standard_dirname) + # Test for a very simple single word name and decimal + # version number ('docutils', '0.5', 'docutils-0.5.dist-info'), # Test for another except this time with a '-' in the name, which # needs to be transformed during the name lookup @@ -221,7 +227,7 @@ EggInfoDistribution # Verify the fake dists have been found. - dists = [ dist for dist in get_distributions() ] + dists = [dist for dist in get_distributions()] for dist in dists: if not isinstance(dist, Distribution): self.fail("item received was not a Distribution instance: " @@ -234,10 +240,11 @@ self.assertListEqual(sorted(found_dists), sorted(fake_dists)) # Now, test if the egg-info distributions are found correctly as well - fake_dists += [('bacon', '0.1'), ('cheese', '2.0.2')] + fake_dists += [('bacon', '0.1'), ('cheese', '2.0.2'), + ('banana', '0.4'), ('strawberry', '0.6')] found_dists = [] - dists = [ dist for dist in get_distributions(use_egg_info=True) ] + dists = [dist for dist in get_distributions(use_egg_info=True)] for dist in dists: if not (isinstance(dist, Distribution) or \ isinstance(dist, EggInfoDistribution)): @@ -248,7 +255,6 @@ self.assertListEqual(sorted(fake_dists), sorted(found_dists)) - def test_get_distribution(self): """Test for looking up a distribution by name.""" # Test the lookup of the towel-stuff distribution @@ -274,6 +280,8 @@ # instructed to self.assertEqual(None, get_distribution('bacon')) self.assertEqual(None, get_distribution('cheese')) + self.assertEqual(None, get_distribution('strawberry')) + self.assertEqual(None, get_distribution('banana')) # Now check that it works well in both situations, when egg-info # is a file and directory respectively. @@ -285,6 +293,14 @@ self.assertTrue(isinstance(dist, EggInfoDistribution)) self.assertEqual(dist.name, 'bacon') + dist = get_distribution('banana', use_egg_info=True) + self.assertTrue(isinstance(dist, EggInfoDistribution)) + self.assertEqual(dist.name, 'banana') + + dist = get_distribution('strawberry', use_egg_info=True) + self.assertTrue(isinstance(dist, EggInfoDistribution)) + self.assertEqual(dist.name, 'strawberry') + def test_get_file_users(self): """Test the iteration of distributions that use a file.""" from distutils2._backport.pkgutil import get_file_users, Distribution @@ -300,7 +316,7 @@ from distutils2._backport.pkgutil import provides_distribution from distutils2.errors import DistutilsError - checkLists = lambda x,y: self.assertListEqual(sorted(x), sorted(y)) + checkLists = lambda x, y: self.assertListEqual(sorted(x), sorted(y)) l = [dist.name for dist in provides_distribution('truffles')] checkLists(l, ['choxie', 'towel-stuff']) @@ -318,10 +334,12 @@ l = [dist.name for dist in provides_distribution('truffles', '1.1')] checkLists(l, ['towel-stuff']) - l = [dist.name for dist in provides_distribution('truffles', '!=1.1,<=2.0')] + l = [dist.name for dist in provides_distribution('truffles', \ + '!=1.1,<=2.0')] checkLists(l, ['choxie']) - l = [dist.name for dist in provides_distribution('truffles', '!=1.1,<=2.0', + l = [dist.name for dist in provides_distribution('truffles', \ + '!=1.1,<=2.0', use_egg_info=True)] checkLists(l, ['choxie', 'bacon', 'cheese']) @@ -338,12 +356,39 @@ l = [dist.name for dist in provides_distribution('truffles', '>=1.0')] checkLists(l, ['choxie', 'towel-stuff']) + l = [dist.name for dist in provides_distribution('strawberry', '0.6', + use_egg_info=True)] + checkLists(l, ['strawberry']) + + l = [dist.name for dist in provides_distribution('strawberry', '>=0.5', + use_egg_info=True)] + checkLists(l, ['strawberry']) + + + l = [dist.name for dist in provides_distribution('strawberry', '>0.6', + use_egg_info=True)] + checkLists(l, []) + + + l = [dist.name for dist in provides_distribution('banana', '0.4', + use_egg_info=True)] + checkLists(l, ['banana']) + + l = [dist.name for dist in provides_distribution('banana', '>=0.3', + use_egg_info=True)] + checkLists(l, ['banana']) + + + l = [dist.name for dist in provides_distribution('banana', '!=0.4', + use_egg_info=True)] + checkLists(l, []) + def test_obsoletes(self): """ Test looking for distributions based on what they obsolete """ from distutils2._backport.pkgutil import obsoletes_distribution from distutils2.errors import DistutilsError - checkLists = lambda x,y: self.assertListEqual(sorted(x), sorted(y)) + checkLists = lambda x, y: self.assertListEqual(sorted(x), sorted(y)) l = [dist.name for dist in obsoletes_distribution('truffles', '1.0')] checkLists(l, []) @@ -363,7 +408,8 @@ l = [dist.name for dist in obsoletes_distribution('truffles', '0.9.6')] checkLists(l, ['choxie', 'towel-stuff']) - l = [dist.name for dist in obsoletes_distribution('truffles', '0.5.2.3')] + l = [dist.name for dist in obsoletes_distribution('truffles', \ + '0.5.2.3')] checkLists(l, ['choxie', 'towel-stuff']) l = [dist.name for dist in obsoletes_distribution('truffles', '0.2')] @@ -377,12 +423,14 @@ suite.addTest(testcase_loader(TestPkgUtilDistribution)) return suite + def test_main(): run_unittest(test_suite()) if __name__ == "__main__": test_main() + def test_suite(): suite = unittest2.TestSuite() testcase_loader = unittest2.loader.defaultTestLoader.loadTestsFromTestCase @@ -390,8 +438,10 @@ suite.addTest(testcase_loader(TestPkgUtilDistribution)) return suite + def test_main(): run_unittest(test_suite()) + if __name__ == "__main__": test_main() -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sun Jun 20 23:04:52 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Jun 2010 23:04:52 +0200 Subject: [Python-checkins] distutils2: Removed a hardcoded string Message-ID: tarek.ziade pushed 9b2d53d64abc to distutils2: http://hg.python.org/distutils2/rev/9b2d53d64abc changeset: 202:9b2d53d64abc user: Josip Djolonga date: Sun Jun 06 16:14:49 2010 +0200 summary: Removed a hardcoded string files: src/distutils2/depgraph.py diff --git a/src/distutils2/depgraph.py b/src/distutils2/depgraph.py --- a/src/distutils2/depgraph.py +++ b/src/distutils2/depgraph.py @@ -175,13 +175,11 @@ return dep if __name__ == '__main__': - import sys - sys.path.append('/home/josip/dev/distutils2/src/distutils2/_backport/tests/fake_dists') dists = list(pkgutil.get_distributions(use_egg_info=True)) graph = generate_graph(dists) for dist, reqs in graph.missing.iteritems(): if len(reqs) > 0: print("Missing dependencies for %s: %s" % (dist.name, ", ".join(reqs))) - f = open('/home/josip/Desktop/output.dot', 'w') + f = open('output.dot', 'w') graph_to_dot(graph, f, True) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sun Jun 20 23:04:52 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Jun 2010 23:04:52 +0200 Subject: [Python-checkins] distutils2: Fix two markup errors found thanks to Sphinx Message-ID: tarek.ziade pushed 59b2a9f41d8e to distutils2: http://hg.python.org/distutils2/rev/59b2a9f41d8e changeset: 204:59b2a9f41d8e user: ?ric Araujo date: Fri Jun 11 16:13:49 2010 +0200 summary: Fix two markup errors found thanks to Sphinx files: src/distutils2/_backport/pkgutil.py diff --git a/src/distutils2/_backport/pkgutil.py b/src/distutils2/_backport/pkgutil.py --- a/src/distutils2/_backport/pkgutil.py +++ b/src/distutils2/_backport/pkgutil.py @@ -649,12 +649,12 @@ A local absolute path is an absolute path in which occurrences of ``'/'`` have been replaced by the system separator given by ``os.sep``. + :parameter local: flag to say if the path should be returned a local absolute path :type local: boolean :returns: iterator of (path, md5, size) - """ return self._get_records(local) @@ -907,7 +907,7 @@ This function only returns the first result founded, as no more than one value is expected. If the directory is not found, ``None`` is returned. - :rtype: :class:`Distribution` or :class:`EggInfoDistribution: or None""" + :rtype: :class:`Distribution` or :class:`EggInfoDistribution` or None""" found = None for dist in get_distributions(): if dist.name == name: -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sun Jun 20 23:04:52 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Jun 2010 23:04:52 +0200 Subject: [Python-checkins] distutils2: Merged with Tarek's work Message-ID: tarek.ziade pushed 8722041aaad5 to distutils2: http://hg.python.org/distutils2/rev/8722041aaad5 changeset: 208:8722041aaad5 parent: 207:5fb9cdbeb097 parent: 198:0e9228d9bbda user: Josip Djolonga date: Sat Jun 12 21:51:16 2010 +0200 summary: Merged with Tarek's work files: src/distutils2/_backport/tests/test_pkgutil.py, src/distutils2/cmd.py, src/distutils2/depgraph.py diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,5 @@ .*\.pyc$ .*\.pyo$ +^src/build ^docs/build .*\.swp$ - diff --git a/src/CONTRIBUTORS.txt b/src/CONTRIBUTORS.txt --- a/src/CONTRIBUTORS.txt +++ b/src/CONTRIBUTORS.txt @@ -9,6 +9,7 @@ Thanks to: +- ??ric Araujo - Pior Bastida - Titus Brown - Nicolas Cadou diff --git a/src/distutils2/_backport/tests/__init__.py b/src/distutils2/_backport/tests/__init__.py --- a/src/distutils2/_backport/tests/__init__.py +++ b/src/distutils2/_backport/tests/__init__.py @@ -1,12 +1,13 @@ import os import sys -import unittest2 + +from distutils2.tests.support import unittest here = os.path.dirname(__file__) def test_suite(): - suite = unittest2.TestSuite() + suite = unittest.TestSuite() for fn in os.listdir(here): if fn.startswith("test") and fn.endswith(".py"): modname = "distutils2._backport.tests." + fn[:-3] diff --git a/src/distutils2/_backport/tests/test_sysconfig.py b/src/distutils2/_backport/tests/test_sysconfig.py --- a/src/distutils2/_backport/tests/test_sysconfig.py +++ b/src/distutils2/_backport/tests/test_sysconfig.py @@ -4,7 +4,6 @@ executing have not been removed. """ -import unittest2 import sys import os import shutil @@ -19,8 +18,9 @@ get_path, get_path_names, _get_default_scheme, _subst_vars, _expand_vars, get_scheme_names, _CONFIG_FILE) +from distutils2.tests.support import unittest -class TestSysConfig(unittest2.TestCase): +class TestSysConfig(unittest.TestCase): def setUp(self): """Make a copy of sys.path""" @@ -97,7 +97,7 @@ substitution key (which would be weird). """ - self.failUnlessEqual(_subst_vars('{py{version}}', {'version': '31'}), '{py31}') + self.assertEqual(_subst_vars('{py{version}}', {'version': '31'}), '{py31}') def test_get_paths(self): scheme = get_paths() @@ -262,7 +262,7 @@ _expand_globals(config) def test_suite(): - return unittest2.makeSuite(TestSysConfig) + return unittest.makeSuite(TestSysConfig) def test_main(): run_unittest(test_suite()) diff --git a/src/distutils2/cmd.py b/src/distutils2/command/cmd.py rename from src/distutils2/cmd.py rename to src/distutils2/command/cmd.py diff --git a/src/distutils2/command/install_egg_info.py b/src/distutils2/command/install_egg_info.py --- a/src/distutils2/command/install_egg_info.py +++ b/src/distutils2/command/install_egg_info.py @@ -4,7 +4,7 @@ a package's PKG-INFO metadata.""" -from distutils2.cmd import Command +from distutils2.command.cmd import Command from distutils2 import log from distutils2._backport.shutil import rmtree import os, sys, re diff --git a/src/distutils2/config.py b/src/distutils2/config.py --- a/src/distutils2/config.py +++ b/src/distutils2/config.py @@ -6,7 +6,7 @@ import os from ConfigParser import ConfigParser -from distutils2.cmd import Command +from distutils2.command.cmd import Command DEFAULT_PYPIRC = """\ [distutils] diff --git a/src/distutils2/core.py b/src/distutils2/core.py --- a/src/distutils2/core.py +++ b/src/distutils2/core.py @@ -17,7 +17,7 @@ # Mainly import these so setup scripts can "from distutils2.core import" them. from distutils2.dist import Distribution -from distutils2.cmd import Command +from distutils2.command.cmd import Command from distutils2.config import PyPIRCCommand from distutils2.extension import Extension diff --git a/src/distutils2/depgraph.py b/src/distutils2/depgraph.py --- a/src/distutils2/depgraph.py +++ b/src/distutils2/depgraph.py @@ -112,11 +112,8 @@ """ graph = DependencyGraph() provided = {} # maps names to lists of (version, dist) tuples - dists = list(dists) # maybe use generator_tools in future - missing = [] # a list of (instance, requirement) tuples - # first, build the graph and find out the provides for dist in dists: graph.add_distribution(dist) diff --git a/src/distutils2/dist.py b/src/distutils2/dist.py --- a/src/distutils2/dist.py +++ b/src/distutils2/dist.py @@ -493,7 +493,7 @@ None if the user asked for help on this command. """ # late import because of mutual dependence between these modules - from distutils2.cmd import Command + from distutils2.command.cmd import Command # Pull the current command from the head of the command line command = args[0] @@ -607,7 +607,7 @@ """ # late import because of mutual dependence between these modules from distutils2.core import gen_usage - from distutils2.cmd import Command + from distutils2.command.cmd import Command if global_options: if display_options: @@ -904,7 +904,7 @@ Returns the reinitialized command object. """ - from distutils2.cmd import Command + from distutils2.command.cmd import Command if not isinstance(command, Command): command_name = command command = self.get_command_obj(command_name) diff --git a/src/distutils2/tests/__init__.py b/src/distutils2/tests/__init__.py --- a/src/distutils2/tests/__init__.py +++ b/src/distutils2/tests/__init__.py @@ -1,20 +1,25 @@ -"""Test suite for distutils. +"""Test suite for distutils2. This test suite consists of a collection of test modules in the -distutils.tests package. Each test module has a name starting with +distutils2.tests package. Each test module has a name starting with 'test' and contains a function test_suite(). The function is expected -to return an initialized unittest2.TestSuite instance. +to return an initialized unittest.TestSuite instance. -Tests for the command classes in the distutils.command package are -included in distutils.tests as well, instead of using a separate -distutils.command.tests package, since command identification is done +Tests for the command classes in the distutils2.command package are +included in distutils2.tests as well, instead of using a separate +distutils2.command.tests package, since command identification is done by import rather than matching pre-defined names. +Utility code is included in distutils2.tests.support. Always import +unittest from that module, it will be the right version (standard +library unittest for 2.7 and higher, third-party unittest2 release for +older versions). """ + import os import sys import warnings -import unittest2 +from distutils2.tests.support import unittest from test.test_support import TESTFN # use TESTFN from stdlib/test_support. @@ -23,7 +28,7 @@ verbose = 1 def test_suite(): - suite = unittest2.TestSuite() + suite = unittest.TestSuite() for fn in os.listdir(here): if fn.startswith("test") and fn.endswith(".py"): modname = "distutils2.tests." + fn[:-3] @@ -42,17 +47,17 @@ class BasicTestRunner: def run(self, test): - result = unittest2.TestResult() + result = unittest.TestResult() test(result) return result def _run_suite(suite, verbose_=1): - """Run tests from a unittest2.TestSuite-derived class.""" + """Run tests from a unittest.TestSuite-derived class.""" global verbose verbose = verbose_ if verbose_: - runner = unittest2.TextTestRunner(sys.stdout, verbosity=2) + runner = unittest.TextTestRunner(sys.stdout, verbosity=2) else: runner = BasicTestRunner() @@ -68,22 +73,22 @@ def run_unittest(classes, verbose_=1): - """Run tests from unittest2.TestCase-derived classes. + """Run tests from unittest.TestCase-derived classes. - Extracted from stdlib test.test_support and modified to support unittest2. + Extracted from stdlib test.test_support and modified to support unittest. """ - valid_types = (unittest2.TestSuite, unittest2.TestCase) - suite = unittest2.TestSuite() + valid_types = (unittest.TestSuite, unittest.TestCase) + suite = unittest.TestSuite() for cls in classes: if isinstance(cls, str): if cls in sys.modules: - suite.addTest(unittest2.findTestCases(sys.modules[cls])) + suite.addTest(unittest.findTestCases(sys.modules[cls])) else: raise ValueError("str arguments must be keys in sys.modules") elif isinstance(cls, valid_types): suite.addTest(cls) else: - suite.addTest(unittest2.makeSuite(cls)) + suite.addTest(unittest.makeSuite(cls)) _run_suite(suite, verbose_) @@ -128,4 +133,4 @@ if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/support.py b/src/distutils2/tests/support.py --- a/src/distutils2/tests/support.py +++ b/src/distutils2/tests/support.py @@ -1,5 +1,12 @@ -"""Support code for distutils test cases.""" +"""Support code for distutils2 test cases. + +Always import unittest from this module, it will be the right version +(standard library unittest for 2.7 and higher, third-party unittest2 +release for older versions). +""" + import os +import sys import shutil import tempfile from copy import deepcopy @@ -9,6 +16,13 @@ from distutils2.log import DEBUG, INFO, WARN, ERROR, FATAL from distutils2.core import Distribution +if sys.version_info >= (2, 7): + # improved unittest package from 2.7's standard library + import unittest +else: + # external release of same package for older versions + import unittest2 as unittest + class LoggingSilencer(object): def setUp(self): diff --git a/src/distutils2/tests/test_bdist.py b/src/distutils2/tests/test_bdist.py --- a/src/distutils2/tests/test_bdist.py +++ b/src/distutils2/tests/test_bdist.py @@ -1,5 +1,4 @@ """Tests for distutils.command.bdist.""" -import unittest2 import sys import os import tempfile @@ -10,12 +9,13 @@ from distutils2.core import Distribution from distutils2.command.bdist import bdist from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.spawn import find_executable from distutils2 import spawn from distutils2.errors import DistutilsExecError class BuildTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def test_formats(self): @@ -38,7 +38,7 @@ self.assertEquals(founded, formats) def test_suite(): - return unittest2.makeSuite(BuildTestCase) + return unittest.makeSuite(BuildTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_bdist_dumb.py b/src/distutils2/tests/test_bdist_dumb.py --- a/src/distutils2/tests/test_bdist_dumb.py +++ b/src/distutils2/tests/test_bdist_dumb.py @@ -1,6 +1,5 @@ """Tests for distutils.command.bdist_dumb.""" -import unittest2 import sys import os @@ -12,6 +11,7 @@ zlib = None from distutils2.tests import run_unittest +from distutils2.tests.support import unittest from distutils2.core import Distribution from distutils2.command.bdist_dumb import bdist_dumb @@ -29,7 +29,7 @@ class BuildDumbTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(BuildDumbTestCase, self).setUp() @@ -42,7 +42,7 @@ sys.argv[:] = self.old_sys_argv[1] super(BuildDumbTestCase, self).tearDown() - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_simple_built(self): # let's create a simple package @@ -99,7 +99,7 @@ self.assertEquals(cmd.format, default) def test_suite(): - return unittest2.makeSuite(BuildDumbTestCase) + return unittest.makeSuite(BuildDumbTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_bdist_msi.py b/src/distutils2/tests/test_bdist_msi.py --- a/src/distutils2/tests/test_bdist_msi.py +++ b/src/distutils2/tests/test_bdist_msi.py @@ -1,16 +1,16 @@ """Tests for distutils.command.bdist_msi.""" -import unittest2 import sys from distutils2.tests import run_unittest from distutils2.tests import support +from distutils2.tests.support import unittest class BDistMSITestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): - @unittest2.skipUnless(sys.platform=="win32", "These tests are only for win32") + @unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") def test_minial(self): # minimal test XXX need more tests from distutils2.command.bdist_msi import bdist_msi @@ -19,7 +19,7 @@ cmd.ensure_finalized() def test_suite(): - return unittest2.makeSuite(BDistMSITestCase) + return unittest.makeSuite(BDistMSITestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_bdist_wininst.py b/src/distutils2/tests/test_bdist_wininst.py --- a/src/distutils2/tests/test_bdist_wininst.py +++ b/src/distutils2/tests/test_bdist_wininst.py @@ -1,14 +1,14 @@ """Tests for distutils.command.bdist_wininst.""" -import unittest2 from distutils2.tests import run_unittest from distutils2.command.bdist_wininst import bdist_wininst from distutils2.tests import support +from distutils2.tests.support import unittest class BuildWinInstTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_get_exe_bytes(self): @@ -26,7 +26,7 @@ self.assertTrue(len(exe_file) > 10) def test_suite(): - return unittest2.makeSuite(BuildWinInstTestCase) + return unittest.makeSuite(BuildWinInstTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_build.py b/src/distutils2/tests/test_build.py --- a/src/distutils2/tests/test_build.py +++ b/src/distutils2/tests/test_build.py @@ -1,10 +1,10 @@ """Tests for distutils.command.build.""" -import unittest2 import os import sys from distutils2.command.build import build from distutils2.tests import support +from distutils2.tests.support import unittest try: from sysconfig import get_platform except ImportError: @@ -12,7 +12,7 @@ class BuildTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_finalize_options(self): pkg_dir, dist = self.create_dist() @@ -51,7 +51,7 @@ self.assertEquals(cmd.executable, os.path.normpath(sys.executable)) def test_suite(): - return unittest2.makeSuite(BuildTestCase) + return unittest.makeSuite(BuildTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_build_clib.py b/src/distutils2/tests/test_build_clib.py --- a/src/distutils2/tests/test_build_clib.py +++ b/src/distutils2/tests/test_build_clib.py @@ -1,5 +1,4 @@ """Tests for distutils.command.build_clib.""" -import unittest2 import os import sys @@ -7,10 +6,11 @@ from distutils2.errors import DistutilsSetupError from distutils2.tests import support from distutils2.spawn import find_executable +from distutils2.tests.support import unittest class BuildCLibTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_check_library_dist(self): pkg_dir, dist = self.create_dist() @@ -137,7 +137,7 @@ self.assertTrue('libfoo.a' in os.listdir(build_temp)) def test_suite(): - return unittest2.makeSuite(BuildCLibTestCase) + return unittest.makeSuite(BuildCLibTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_build_ext.py b/src/distutils2/tests/test_build_ext.py --- a/src/distutils2/tests/test_build_ext.py +++ b/src/distutils2/tests/test_build_ext.py @@ -6,6 +6,7 @@ import warnings import distutils2.tests +from distutils2.tests.support import unittest from distutils2.core import Extension, Distribution from distutils2.command.build_ext import build_ext from distutils2.tests import support @@ -17,7 +18,6 @@ except ImportError: from distutils2._backport import sysconfig -import unittest2 # http://bugs.python.org/issue4373 # Don't load the xx module more than once. @@ -29,7 +29,7 @@ class BuildExtTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def setUp(self): # Create a simple test environment # Note that we're making changes to sys.path @@ -46,7 +46,7 @@ build_ext.USER_BASE = site.USER_BASE # XXX only works with 2.6 > -- dunno why yet - @unittest2.skipUnless(sys.version_info >= (2, 6,), 'works for >= 2.6') + @unittest.skipUnless(sys.version_info >= (2, 6,), 'works for >= 2.6') def test_build_ext(self): global ALREADY_TESTED xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') @@ -412,8 +412,8 @@ if distutils2.tests.verbose: print ('test_build_ext: Cannot find source code (test' ' must run in python build dir)') - return unittest2.TestSuite() - else: return unittest2.makeSuite(BuildExtTestCase) + return unittest.TestSuite() + else: return unittest.makeSuite(BuildExtTestCase) if __name__ == '__main__': distsutils2.tests.run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_build_py.py b/src/distutils2/tests/test_build_py.py --- a/src/distutils2/tests/test_build_py.py +++ b/src/distutils2/tests/test_build_py.py @@ -3,18 +3,18 @@ import os import sys import StringIO -import unittest2 from distutils2.command.build_py import build_py from distutils2.core import Distribution from distutils2.errors import DistutilsFileError from distutils2.tests import support +from distutils2.tests.support import unittest class BuildPyTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_package_data(self): sources = self.mkdtemp() @@ -90,7 +90,7 @@ os.chdir(cwd) sys.stdout = old_stdout - @unittest2.skipUnless(hasattr(sys, 'dont_write_bytecode'), + @unittest.skipUnless(hasattr(sys, 'dont_write_bytecode'), 'dont_write_bytecode support') def test_dont_write_bytecode(self): # makes sure byte_compile is not used @@ -109,7 +109,7 @@ self.assertTrue('byte-compiling is disabled' in self.logs[0][1]) def test_suite(): - return unittest2.makeSuite(BuildPyTestCase) + return unittest.makeSuite(BuildPyTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_build_scripts.py b/src/distutils2/tests/test_build_scripts.py --- a/src/distutils2/tests/test_build_scripts.py +++ b/src/distutils2/tests/test_build_scripts.py @@ -1,7 +1,6 @@ """Tests for distutils.command.build_scripts.""" import os -import unittest2 from distutils2.command.build_scripts import build_scripts from distutils2.core import Distribution @@ -11,11 +10,12 @@ from distutils2._backport import sysconfig from distutils2.tests import support +from distutils2.tests.support import unittest class BuildScriptsTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_default_settings(self): cmd = self.get_build_scripts_cmd("/foo/bar", []) @@ -106,7 +106,7 @@ self.assertTrue(name in built) def test_suite(): - return unittest2.makeSuite(BuildScriptsTestCase) + return unittest.makeSuite(BuildScriptsTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_ccompiler.py b/src/distutils2/tests/test_ccompiler.py --- a/src/distutils2/tests/test_ccompiler.py +++ b/src/distutils2/tests/test_ccompiler.py @@ -1,11 +1,11 @@ """Tests for distutils.ccompiler.""" import os -import unittest2 from distutils2.tests import captured_stdout from distutils2.compiler.ccompiler import (gen_lib_options, CCompiler, get_default_compiler, customize_compiler) from distutils2.tests import support +from distutils2.tests.support import unittest class FakeCompiler(object): def library_dir_option(self, dir): @@ -20,7 +20,7 @@ def library_option(self, lib): return "-l" + lib -class CCompilerTestCase(support.EnvironGuard, unittest2.TestCase): +class CCompilerTestCase(support.EnvironGuard, unittest.TestCase): def test_gen_lib_options(self): compiler = FakeCompiler() @@ -54,7 +54,7 @@ self.assertEquals(comp.exes['archiver'], 'my_ar -arflags') def test_suite(): - return unittest2.makeSuite(CCompilerTestCase) + return unittest.makeSuite(CCompilerTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_check.py b/src/distutils2/tests/test_check.py --- a/src/distutils2/tests/test_check.py +++ b/src/distutils2/tests/test_check.py @@ -1,14 +1,14 @@ """Tests for distutils.command.check.""" -import unittest2 from distutils2.command.check import check from distutils2.metadata import _HAS_DOCUTILS from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.errors import DistutilsSetupError class CheckTestCase(support.LoggingSilencer, support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def _run(self, metadata=None, **options): if metadata is None: @@ -27,7 +27,7 @@ # by default, check is checking the metadata # should have some warnings cmd = self._run() - self.assert_(len(cmd._warnings) > 0) + self.assertTrue(len(cmd._warnings) > 0) # now let's add the required fields # and run it again, to make sure we don't get @@ -79,7 +79,7 @@ 'restructuredtext': 1}) def test_suite(): - return unittest2.makeSuite(CheckTestCase) + return unittest.makeSuite(CheckTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_clean.py b/src/distutils2/tests/test_clean.py --- a/src/distutils2/tests/test_clean.py +++ b/src/distutils2/tests/test_clean.py @@ -1,15 +1,15 @@ """Tests for distutils.command.clean.""" import sys import os -import unittest2 import getpass from distutils2.command.clean import clean from distutils2.tests import support +from distutils2.tests.support import unittest class cleanTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_simple_run(self): pkg_dir, dist = self.create_dist() @@ -44,7 +44,7 @@ cmd.run() def test_suite(): - return unittest2.makeSuite(cleanTestCase) + return unittest.makeSuite(cleanTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_cmd.py b/src/distutils2/tests/test_cmd.py --- a/src/distutils2/tests/test_cmd.py +++ b/src/distutils2/tests/test_cmd.py @@ -1,17 +1,17 @@ """Tests for distutils.cmd.""" -import unittest2 import os from distutils2.tests import captured_stdout, run_unittest -from distutils2.cmd import Command +from distutils2.command.cmd import Command from distutils2.dist import Distribution from distutils2.errors import DistutilsOptionError +from distutils2.tests.support import unittest class MyCmd(Command): def initialize_options(self): pass -class CommandTestCase(unittest2.TestCase): +class CommandTestCase(unittest.TestCase): def setUp(self): dist = Distribution() @@ -104,7 +104,7 @@ self.assertRaises(DistutilsOptionError, cmd.ensure_dirname, 'option2') def test_suite(): - return unittest2.makeSuite(CommandTestCase) + return unittest.makeSuite(CommandTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_config.py b/src/distutils2/tests/test_config.py --- a/src/distutils2/tests/test_config.py +++ b/src/distutils2/tests/test_config.py @@ -1,7 +1,6 @@ """Tests for distutils.pypirc.pypirc.""" import sys import os -import unittest2 import tempfile import shutil @@ -11,6 +10,7 @@ from distutils2.log import WARN from distutils2.tests import support +from distutils2.tests.support import unittest PYPIRC = """\ [distutils] @@ -50,7 +50,7 @@ class PyPIRCCommandTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def setUp(self): """Patches the environment.""" @@ -112,7 +112,7 @@ self.assertEquals(content, WANTED) def test_suite(): - return unittest2.makeSuite(PyPIRCCommandTestCase) + return unittest.makeSuite(PyPIRCCommandTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_config_cmd.py b/src/distutils2/tests/test_config_cmd.py --- a/src/distutils2/tests/test_config_cmd.py +++ b/src/distutils2/tests/test_config_cmd.py @@ -1,15 +1,15 @@ """Tests for distutils.command.config.""" -import unittest2 import os import sys from distutils2.command.config import dump_file, config from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2 import log class ConfigTestCase(support.LoggingSilencer, support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def _info(self, msg, *args): for line in msg.splitlines(): @@ -83,7 +83,7 @@ self.assertTrue(not os.path.exists(f)) def test_suite(): - return unittest2.makeSuite(ConfigTestCase) + return unittest.makeSuite(ConfigTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_converter.py b/src/distutils2/tests/test_converter.py --- a/src/distutils2/tests/test_converter.py +++ b/src/distutils2/tests/test_converter.py @@ -1,8 +1,8 @@ """Tests for distutils.converter.""" import os import sys -import unittest2 from distutils2.converter import DistutilsRefactoringTool +from distutils2.tests.support import unittest _CURDIR = os.path.dirname(__file__) @@ -15,9 +15,9 @@ f.close() -class ConverterTestCase(unittest2.TestCase): +class ConverterTestCase(unittest.TestCase): - @unittest2.skipUnless(not sys.version < '2.6', 'Needs Python >=2.6') + @unittest.skipUnless(not sys.version < '2.6', 'Needs Python >=2.6') def test_conversions(self): # for all XX_before in the conversions/ dir # we run the refactoring tool @@ -33,7 +33,7 @@ self.assertEquals(str(res), wanted) def test_suite(): - return unittest2.makeSuite(ConverterTestCase) + return unittest.makeSuite(ConverterTestCase) if __name__ == '__main__': - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_core.py b/src/distutils2/tests/test_core.py --- a/src/distutils2/tests/test_core.py +++ b/src/distutils2/tests/test_core.py @@ -6,8 +6,8 @@ import shutil import sys from distutils2.tests import captured_stdout -import unittest2 from distutils2.tests import support +from distutils2.tests.support import unittest # setup script that uses __file__ setup_using___file__ = """\ @@ -28,7 +28,7 @@ """ -class CoreTestCase(support.EnvironGuard, unittest2.TestCase): +class CoreTestCase(support.EnvironGuard, unittest.TestCase): def setUp(self): super(CoreTestCase, self).setUp() @@ -92,7 +92,7 @@ self.assertEqual(cwd, output) def test_suite(): - return unittest2.makeSuite(CoreTestCase) + return unittest.makeSuite(CoreTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_cygwinccompiler.py b/src/distutils2/tests/test_cygwinccompiler.py --- a/src/distutils2/tests/test_cygwinccompiler.py +++ b/src/distutils2/tests/test_cygwinccompiler.py @@ -1,5 +1,4 @@ """Tests for distutils.cygwinccompiler.""" -import unittest2 import sys import os import warnings @@ -18,9 +17,10 @@ get_msvcr, RE_VERSION) from distutils2.util import get_compiler_versions from distutils2.tests import support +from distutils2.tests.support import unittest class CygwinCCompilerTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(CygwinCCompilerTestCase, self).setUp() @@ -94,7 +94,7 @@ def test_suite(): - return unittest2.makeSuite(CygwinCCompilerTestCase) + return unittest.makeSuite(CygwinCCompilerTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_dist.py b/src/distutils2/tests/test_dist.py --- a/src/distutils2/tests/test_dist.py +++ b/src/distutils2/tests/test_dist.py @@ -4,15 +4,15 @@ import os import StringIO import sys -import unittest2 import warnings import textwrap from distutils2.dist import Distribution, fix_help_options, DistributionMetadata -from distutils2.cmd import Command +from distutils2.command.cmd import Command import distutils2.dist from distutils2.tests import TESTFN, captured_stdout from distutils2.tests import support +from distutils2.tests.support import unittest class test_dist(Command): """Sample distutils2 extension command.""" @@ -40,7 +40,7 @@ class DistributionTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(DistributionTestCase, self).setUp() @@ -242,7 +242,7 @@ class MetadataTestCase(support.TempdirManager, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(MetadataTestCase, self).setUp() @@ -422,10 +422,10 @@ self.assertEquals(metadata['requires-dist'], ['foo']) def test_suite(): - suite = unittest2.TestSuite() - suite.addTest(unittest2.makeSuite(DistributionTestCase)) - suite.addTest(unittest2.makeSuite(MetadataTestCase)) + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(DistributionTestCase)) + suite.addTest(unittest.makeSuite(MetadataTestCase)) return suite if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_emxccompiler.py b/src/distutils2/tests/test_emxccompiler.py --- a/src/distutils2/tests/test_emxccompiler.py +++ b/src/distutils2/tests/test_emxccompiler.py @@ -1,5 +1,4 @@ """Tests for distutils.emxccompiler.""" -import unittest2 import sys import os import warnings @@ -10,14 +9,15 @@ from distutils2.compiler.emxccompiler import get_versions from distutils2.util import get_compiler_versions from distutils2.tests import support +from distutils2.tests.support import unittest class EmxCCompilerTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): pass def test_suite(): - return unittest2.makeSuite(EmxCCompilerTestCase) + return unittest.makeSuite(EmxCCompilerTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_extension.py b/src/distutils2/tests/test_extension.py --- a/src/distutils2/tests/test_extension.py +++ b/src/distutils2/tests/test_extension.py @@ -1,16 +1,16 @@ """Tests for distutils.extension.""" -import unittest2 import os import warnings from distutils2.extension import Extension +from distutils2.tests.support import unittest -class ExtensionTestCase(unittest2.TestCase): +class ExtensionTestCase(unittest.TestCase): pass def test_suite(): - return unittest2.makeSuite(ExtensionTestCase) + return unittest.makeSuite(ExtensionTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install.py b/src/distutils2/tests/test_install.py --- a/src/distutils2/tests/test_install.py +++ b/src/distutils2/tests/test_install.py @@ -3,7 +3,6 @@ import os import os.path import sys -import unittest2 import site from distutils2._backport import sysconfig @@ -22,11 +21,12 @@ from distutils2.errors import DistutilsOptionError from distutils2.tests import support +from distutils2.tests.support import unittest class InstallTestCase(support.TempdirManager, support.EnvironGuard, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_home_installation_scheme(self): # This ensure two things: @@ -214,7 +214,7 @@ self.assertTrue(len(self.logs) > old_logs_len) def test_suite(): - return unittest2.makeSuite(InstallTestCase) + return unittest.makeSuite(InstallTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install_data.py b/src/distutils2/tests/test_install_data.py --- a/src/distutils2/tests/test_install_data.py +++ b/src/distutils2/tests/test_install_data.py @@ -1,16 +1,16 @@ """Tests for distutils.command.install_data.""" import sys import os -import unittest2 import getpass from distutils2.command.install_data import install_data from distutils2.tests import support +from distutils2.tests.support import unittest class InstallDataTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def test_simple_run(self): pkg_dir, dist = self.create_dist() @@ -70,7 +70,7 @@ self.assertTrue(os.path.exists(os.path.join(inst, rone))) def test_suite(): - return unittest2.makeSuite(InstallDataTestCase) + return unittest.makeSuite(InstallDataTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install_headers.py b/src/distutils2/tests/test_install_headers.py --- a/src/distutils2/tests/test_install_headers.py +++ b/src/distutils2/tests/test_install_headers.py @@ -1,16 +1,16 @@ """Tests for distutils.command.install_headers.""" import sys import os -import unittest2 import getpass from distutils2.command.install_headers import install_headers from distutils2.tests import support +from distutils2.tests.support import unittest class InstallHeadersTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def test_simple_run(self): # we have two headers @@ -34,7 +34,7 @@ self.assertEquals(len(cmd.get_outputs()), 2) def test_suite(): - return unittest2.makeSuite(InstallHeadersTestCase) + return unittest.makeSuite(InstallHeadersTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install_lib.py b/src/distutils2/tests/test_install_lib.py --- a/src/distutils2/tests/test_install_lib.py +++ b/src/distutils2/tests/test_install_lib.py @@ -1,12 +1,12 @@ """Tests for distutils.command.install_data.""" import sys import os -import unittest2 from distutils2.command.install_lib import install_lib from distutils2.extension import Extension from distutils2.tests import support from distutils2.errors import DistutilsOptionError +from distutils2.tests.support import unittest try: no_bytecode = sys.dont_write_bytecode @@ -18,7 +18,7 @@ class InstallLibTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, - unittest2.TestCase): + unittest.TestCase): def test_finalize_options(self): pkg_dir, dist = self.create_dist() @@ -38,7 +38,7 @@ cmd.finalize_options() self.assertEquals(cmd.optimize, 2) - @unittest2.skipIf(no_bytecode, 'byte-compile not supported') + @unittest.skipIf(no_bytecode, 'byte-compile not supported') def test_byte_compile(self): pkg_dir, dist = self.create_dist() cmd = install_lib(dist) @@ -84,7 +84,7 @@ # get_input should return 2 elements self.assertEquals(len(cmd.get_inputs()), 2) - @unittest2.skipUnless(bytecode_support, 'sys.dont_write_bytecode not supported') + @unittest.skipUnless(bytecode_support, 'sys.dont_write_bytecode not supported') def test_dont_write_bytecode(self): # makes sure byte_compile is not used pkg_dir, dist = self.create_dist() @@ -102,7 +102,7 @@ self.assertTrue('byte-compiling is disabled' in self.logs[0][1]) def test_suite(): - return unittest2.makeSuite(InstallLibTestCase) + return unittest.makeSuite(InstallLibTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_install_scripts.py b/src/distutils2/tests/test_install_scripts.py --- a/src/distutils2/tests/test_install_scripts.py +++ b/src/distutils2/tests/test_install_scripts.py @@ -1,17 +1,17 @@ """Tests for distutils.command.install_scripts.""" import os -import unittest2 from distutils2.command.install_scripts import install_scripts from distutils2.core import Distribution from distutils2.tests import support +from distutils2.tests.support import unittest class InstallScriptsTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_default_settings(self): dist = Distribution() @@ -73,7 +73,7 @@ def test_suite(): - return unittest2.makeSuite(InstallScriptsTestCase) + return unittest.makeSuite(InstallScriptsTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_manifest.py b/src/distutils2/tests/test_manifest.py --- a/src/distutils2/tests/test_manifest.py +++ b/src/distutils2/tests/test_manifest.py @@ -1,10 +1,10 @@ """Tests for distutils.manifest.""" -import unittest2 import os import sys import logging from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.manifest import Manifest _MANIFEST = """\ @@ -18,7 +18,7 @@ """ class ManifestTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def test_manifest_reader(self): @@ -51,7 +51,7 @@ def test_suite(): - return unittest2.makeSuite(ManifestTestCase) + return unittest.makeSuite(ManifestTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_metadata.py b/src/distutils2/tests/test_metadata.py --- a/src/distutils2/tests/test_metadata.py +++ b/src/distutils2/tests/test_metadata.py @@ -1,13 +1,13 @@ """Tests for distutils.command.bdist.""" -import unittest2 import os import sys from StringIO import StringIO from distutils2.metadata import (DistributionMetadata, _interpret, PKG_INFO_PREFERRED_VERSION) +from distutils2.tests.support import unittest -class DistributionMetadataTestCase(unittest2.TestCase): +class DistributionMetadataTestCase(unittest.TestCase): def test_interpret(self): @@ -64,7 +64,7 @@ res = res.read() f = open(PKG_INFO) wanted = f.read() - self.assert_('Keywords: keyring,password,crypt' in res) + self.assertTrue('Keywords: keyring,password,crypt' in res) f.close() def test_metadata_markers(self): @@ -228,7 +228,7 @@ def test_suite(): - return unittest2.makeSuite(DistributionMetadataTestCase) + return unittest.makeSuite(DistributionMetadataTestCase) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_msvc9compiler.py b/src/distutils2/tests/test_msvc9compiler.py --- a/src/distutils2/tests/test_msvc9compiler.py +++ b/src/distutils2/tests/test_msvc9compiler.py @@ -1,10 +1,10 @@ """Tests for distutils.msvc9compiler.""" import sys -import unittest2 import os from distutils2.errors import DistutilsPlatformError from distutils2.tests import support +from distutils2.tests.support import unittest _MANIFEST = """\ @@ -62,9 +62,9 @@ class msvc9compilerTestCase(support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): - @unittest2.skipUnless(sys.platform=="win32", "These tests are only for win32") + @unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") def test_no_compiler(self): # makes sure query_vcvarsall throws # a DistutilsPlatformError if the compiler @@ -86,7 +86,7 @@ finally: msvc9compiler.find_vcvarsall = old_find_vcvarsall - @unittest2.skipUnless(sys.platform=="win32", "These tests are only for win32") + @unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") def test_reg_class(self): from distutils2.msvccompiler import get_build_version if get_build_version() < 8.0: @@ -110,7 +110,7 @@ keys = Reg.read_keys(HKCU, r'Control Panel') self.assertTrue('Desktop' in keys) - @unittest2.skipUnless(sys.platform=="win32", "These tests are only for win32") + @unittest.skipUnless(sys.platform=="win32", "These tests are only for win32") def test_remove_visual_c_ref(self): from distutils2.msvc9compiler import MSVCCompiler tempdir = self.mkdtemp() @@ -133,7 +133,7 @@ def test_suite(): - return unittest2.makeSuite(msvc9compilerTestCase) + return unittest.makeSuite(msvc9compilerTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_pypi_versions.py b/src/distutils2/tests/test_pypi_versions.py --- a/src/distutils2/tests/test_pypi_versions.py +++ b/src/distutils2/tests/test_pypi_versions.py @@ -17,9 +17,9 @@ import xmlrpclib import os.path -import unittest2 from distutils2.version import suggest_normalized_version +from distutils2.tests.support import unittest def test_pypi(): # @@ -121,11 +121,11 @@ print "Have Suggestion : ", have_sugg, pct % (have_sugg/total_versions*100,) print "No Suggestion : ", no_sugg, pct % (no_sugg/total_versions*100,) -class TestPyPI(unittest2.TestCase): +class TestPyPI(unittest.TestCase): pass def test_suite(): - return unittest2.makeSuite(TestPyPI) + return unittest.makeSuite(TestPyPI) if __name__ == '__main__': run_unittest(test_suite()) diff --git a/src/distutils2/tests/test_register.py b/src/distutils2/tests/test_register.py --- a/src/distutils2/tests/test_register.py +++ b/src/distutils2/tests/test_register.py @@ -2,7 +2,6 @@ # -*- encoding: utf8 -*- import sys import os -import unittest2 import getpass import urllib2 import warnings @@ -19,6 +18,7 @@ from distutils2.errors import DistutilsSetupError from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.tests.test_config import PYPIRC, PyPIRCCommandTestCase PYPIRC_NOPASSWORD = """\ @@ -192,7 +192,7 @@ self.assertEquals(headers['Content-length'], '290') self.assertTrue('tarek' in req.data) - @unittest2.skipUnless(DOCUTILS_SUPPORT, 'needs docutils') + @unittest.skipUnless(DOCUTILS_SUPPORT, 'needs docutils') def test_strict(self): # testing the script option # when on, the register command stops if @@ -250,7 +250,7 @@ self.assertEquals(data['requires_dist'], ['lxml']) def test_suite(): - return unittest2.makeSuite(RegisterTestCase) + return unittest.makeSuite(RegisterTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_sdist.py b/src/distutils2/tests/test_sdist.py --- a/src/distutils2/tests/test_sdist.py +++ b/src/distutils2/tests/test_sdist.py @@ -1,6 +1,5 @@ """Tests for distutils.command.sdist.""" import os -import unittest2 import shutil import zipfile import tarfile @@ -29,6 +28,7 @@ from distutils2.command.sdist import sdist from distutils2.command.sdist import show_formats from distutils2.core import Distribution +from distutils2.tests.support import unittest from distutils2.tests.test_config import PyPIRCCommandTestCase from distutils2.errors import DistutilsExecError, DistutilsOptionError from distutils2.spawn import find_executable @@ -97,7 +97,7 @@ cmd.warn = _warn return dist, cmd - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_prune_file_list(self): # this test creates a package with some vcs dirs in it # and launch sdist to make sure they get pruned @@ -139,7 +139,7 @@ # making sure everything has been pruned correctly self.assertEquals(len(content), 4) - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_make_distribution(self): # check if tar and gzip are installed @@ -176,7 +176,7 @@ self.assertEquals(result, ['fake-1.0.tar', 'fake-1.0.tar.gz']) - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_add_defaults(self): # http://bugs.python.org/issue2279 @@ -238,7 +238,7 @@ manifest = open(join(self.tmp_dir, 'MANIFEST')).read() self.assertEquals(manifest, MANIFEST % {'sep': os.sep}) - @unittest2.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(zlib, "requires zlib") def test_metadata_check_option(self): # testing the `medata-check` option dist, cmd = self.get_cmd(metadata={}) @@ -293,8 +293,8 @@ cmd.formats = 'supazipa' self.assertRaises(DistutilsOptionError, cmd.finalize_options) - @unittest2.skipUnless(zlib, "requires zlib") - @unittest2.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") + @unittest.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") def test_make_distribution_owner_group(self): # check if tar and gzip are installed @@ -357,7 +357,7 @@ self.assertIn('MANIFEST.in', cmd.filelist.files) def test_suite(): - return unittest2.makeSuite(SDistTestCase) + return unittest.makeSuite(SDistTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_spawn.py b/src/distutils2/tests/test_spawn.py --- a/src/distutils2/tests/test_spawn.py +++ b/src/distutils2/tests/test_spawn.py @@ -1,5 +1,4 @@ """Tests for distutils.spawn.""" -import unittest2 import os import time from distutils2.tests import captured_stdout @@ -8,10 +7,11 @@ from distutils2.spawn import spawn, find_executable from distutils2.errors import DistutilsExecError from distutils2.tests import support +from distutils2.tests.support import unittest class SpawnTestCase(support.TempdirManager, support.LoggingSilencer, - unittest2.TestCase): + unittest.TestCase): def test_nt_quote_args(self): @@ -23,7 +23,7 @@ self.assertEquals(res, wanted) - @unittest2.skipUnless(os.name in ('nt', 'posix'), + @unittest.skipUnless(os.name in ('nt', 'posix'), 'Runs only under posix or nt') def test_spawn(self): tmpdir = self.mkdtemp() @@ -54,7 +54,7 @@ spawn([exe]) # should work without any error def test_suite(): - return unittest2.makeSuite(SpawnTestCase) + return unittest.makeSuite(SpawnTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_unixccompiler.py b/src/distutils2/tests/test_unixccompiler.py --- a/src/distutils2/tests/test_unixccompiler.py +++ b/src/distutils2/tests/test_unixccompiler.py @@ -1,6 +1,5 @@ """Tests for distutils.unixccompiler.""" import sys -import unittest2 try: import sysconfig @@ -8,8 +7,9 @@ from distutils2._backport import sysconfig from distutils2.compiler.unixccompiler import UnixCCompiler +from distutils2.tests.support import unittest -class UnixCCompilerTestCase(unittest2.TestCase): +class UnixCCompilerTestCase(unittest.TestCase): def setUp(self): self._backup_platform = sys.platform @@ -127,7 +127,7 @@ def test_suite(): - return unittest2.makeSuite(UnixCCompilerTestCase) + return unittest.makeSuite(UnixCCompilerTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_upload.py b/src/distutils2/tests/test_upload.py --- a/src/distutils2/tests/test_upload.py +++ b/src/distutils2/tests/test_upload.py @@ -2,13 +2,13 @@ # -*- encoding: utf8 -*- import sys import os -import unittest2 from distutils2.command import upload as upload_mod from distutils2.command.upload import upload from distutils2.core import Distribution from distutils2.tests import support +from distutils2.tests.support import unittest from distutils2.tests.test_config import PYPIRC, PyPIRCCommandTestCase PYPIRC_LONG_PASSWORD = """\ @@ -116,7 +116,7 @@ # what did we send ? self.assertIn('d??d??', self.last_open.req.data) headers = dict(self.last_open.req.headers) - self.assert_(headers['Content-length'] > 2000) + self.assertTrue(int(headers['Content-length']) < 2000) self.assertTrue(headers['Content-type'].startswith('multipart/form-data')) self.assertEquals(self.last_open.req.get_method(), 'POST') self.assertEquals(self.last_open.req.get_full_url(), @@ -126,7 +126,7 @@ self.assertFalse('\n' in auth) def test_suite(): - return unittest2.makeSuite(uploadTestCase) + return unittest.makeSuite(uploadTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_util.py b/src/distutils2/tests/test_util.py --- a/src/distutils2/tests/test_util.py +++ b/src/distutils2/tests/test_util.py @@ -1,7 +1,6 @@ """Tests for distutils.util.""" import os import sys -import unittest2 from copy import copy from StringIO import StringIO import subprocess @@ -17,6 +16,7 @@ byte_compile, find_packages) from distutils2 import util from distutils2.tests import support +from distutils2.tests.support import unittest class FakePopen(object): test_class = None @@ -34,7 +34,7 @@ class UtilTestCase(support.EnvironGuard, support.TempdirManager, - unittest2.TestCase): + unittest.TestCase): def setUp(self): super(UtilTestCase, self).setUp() @@ -243,7 +243,7 @@ res = get_compiler_versions() self.assertEquals(res[2], None) - @unittest2.skipUnless(hasattr(sys, 'dont_write_bytecode'), + @unittest.skipUnless(hasattr(sys, 'dont_write_bytecode'), 'no dont_write_bytecode support') def test_dont_write_bytecode(self): # makes sure byte_compile raise a DistutilsError @@ -298,7 +298,7 @@ def test_suite(): - return unittest2.makeSuite(UtilTestCase) + return unittest.makeSuite(UtilTestCase) if __name__ == "__main__": - unittest2.main(defaultTest="test_suite") + unittest.main(defaultTest="test_suite") diff --git a/src/distutils2/tests/test_version.py b/src/distutils2/tests/test_version.py --- a/src/distutils2/tests/test_version.py +++ b/src/distutils2/tests/test_version.py @@ -1,5 +1,4 @@ """Tests for distutils.version.""" -import unittest import doctest import os @@ -7,6 +6,7 @@ from distutils2.version import IrrationalVersionError from distutils2.version import suggest_normalized_version as suggest from distutils2.version import VersionPredicate +from distutils2.tests.support import unittest class VersionTestCase(unittest.TestCase): diff --git a/src/distutils2/version.py b/src/distutils2/version.py --- a/src/distutils2/version.py +++ b/src/distutils2/version.py @@ -3,6 +3,10 @@ from distutils2.errors import IrrationalVersionError, HugeMajorVersionNumError +__all__ = ['NormalizedVersion', 'suggest_normalized_version', + 'VersionPredicate', 'is_valid_version', 'is_valid_versions', + 'is_valid_predicate'] + # A marker used in the second and third parts of the `parts` tuple, for # versions that don't have those segments, to sort properly. An example # of versions in sort order ('highest' last): @@ -18,9 +22,9 @@ # | # 'dev' < 'f' ----------------------------------------------/ # Other letters would do, but 'f' for 'final' is kind of nice. -FINAL_MARKER = ('f',) +_FINAL_MARKER = ('f',) -VERSION_RE = re.compile(r''' +_VERSION_RE = re.compile(r''' ^ (?P\d+\.\d+) # minimum 'N.N' (?P(?:\.\d+)*) # any number of extra '.N' segments @@ -70,13 +74,13 @@ self._parse(s, error_on_huge_major_num) @classmethod - def from_parts(cls, version, prerelease=FINAL_MARKER, - devpost=FINAL_MARKER): + def from_parts(cls, version, prerelease=_FINAL_MARKER, + devpost=_FINAL_MARKER): return cls(cls.parts_to_str((version, prerelease, devpost))) def _parse(self, s, error_on_huge_major_num=True): """Parses a string version into parts.""" - match = VERSION_RE.search(s) + match = _VERSION_RE.search(s) if not match: raise IrrationalVersionError(s) @@ -98,7 +102,7 @@ pad_zeros_length=1) parts.append(tuple(block)) else: - parts.append(FINAL_MARKER) + parts.append(_FINAL_MARKER) # postdev if groups.get('postdev'): @@ -106,14 +110,14 @@ dev = groups.get('dev') postdev = [] if post is not None: - postdev.extend([FINAL_MARKER[0], 'post', int(post)]) + postdev.extend([_FINAL_MARKER[0], 'post', int(post)]) if dev is None: - postdev.append(FINAL_MARKER[0]) + postdev.append(_FINAL_MARKER[0]) if dev is not None: postdev.extend(['dev', int(dev)]) parts.append(tuple(postdev)) else: - parts.append(FINAL_MARKER) + parts.append(_FINAL_MARKER) self.parts = tuple(parts) if error_on_huge_major_num and self.parts[0][0] > 1980: raise HugeMajorVersionNumError("huge major version number, %r, " @@ -154,10 +158,10 @@ # XXX This doesn't check for invalid tuples main, prerel, postdev = parts s = '.'.join(str(v) for v in main) - if prerel is not FINAL_MARKER: + if prerel is not _FINAL_MARKER: s += prerel[0] s += '.'.join(str(v) for v in prerel[1:]) - if postdev and postdev is not FINAL_MARKER: + if postdev and postdev is not _FINAL_MARKER: if postdev[0] == 'f': postdev = postdev[1:] i = 0 @@ -197,6 +201,9 @@ def __ge__(self, other): return self.__eq__(other) or self.__gt__(other) + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + def suggest_normalized_version(s): """Suggest a normalized version close to the given version string. @@ -361,7 +368,7 @@ return False return True -class Versions(VersionPredicate): +class _Versions(VersionPredicate): def __init__(self, predicate): predicate = predicate.strip() match = _PLAIN_VERSIONS.match(predicate) @@ -372,7 +379,7 @@ self.predicates = [_split_predicate(pred.strip()) for pred in predicates.split(',')] -class Version(VersionPredicate): +class _Version(VersionPredicate): def __init__(self, predicate): predicate = predicate.strip() match = _PLAIN_VERSIONS.match(predicate) @@ -391,7 +398,7 @@ def is_valid_versions(predicate): try: - Versions(predicate) + _Versions(predicate) except (ValueError, IrrationalVersionError): return False else: @@ -399,7 +406,7 @@ def is_valid_version(predicate): try: - Version(predicate) + _Version(predicate) except (ValueError, IrrationalVersionError): return False else: diff --git a/src/runtests.py b/src/runtests.py --- a/src/runtests.py +++ b/src/runtests.py @@ -26,9 +26,9 @@ if __name__ == "__main__": try: - import unittest2 + from distutils2.tests.support import unittest except ImportError: - print('!!! You need to install unittest2') + print('Error: You have to install unittest2') sys.exit(1) sys.exit(test_main()) diff --git a/src/setup.py b/src/setup.py --- a/src/setup.py +++ b/src/setup.py @@ -17,19 +17,17 @@ f.close() def get_tip_revision(path=os.getcwd()): + from subprocess import Popen, PIPE try: - from mercurial.hg import repository - from mercurial.ui import ui - from mercurial import node - from mercurial.error import RepoError - except ImportError: + cmd = Popen(['hg', 'tip', '--template', '{rev}', '-R', path], + stdout=PIPE, stderr=PIPE) + except OSError: return 0 - try: - repo = repository(ui(), path) - tip = repo.changelog.tip() - return repo.changelog.rev(tip) - except RepoError: + rev = cmd.stdout.read() + if rev == '': + # there has been an error in the command return 0 + return int(rev) DEV_SUFFIX = '.dev%d' % get_tip_revision('..') -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sun Jun 20 23:04:52 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 20 Jun 2010 23:04:52 +0200 Subject: [Python-checkins] distutils2: Added test case for graph_to_dot Message-ID: tarek.ziade pushed 7bfa383dd0bf to distutils2: http://hg.python.org/distutils2/rev/7bfa383dd0bf changeset: 212:7bfa383dd0bf user: Josip Djolonga date: Wed Jun 16 20:27:45 2010 +0200 summary: Added test case for graph_to_dot files: src/distutils2/depgraph.py, src/distutils2/tests/test_depgraph.py diff --git a/src/distutils2/depgraph.py b/src/distutils2/depgraph.py --- a/src/distutils2/depgraph.py +++ b/src/distutils2/depgraph.py @@ -75,12 +75,9 @@ If *skip_disconnected* is set to ``True``, then all distributions that are not dependent on any other distribution are skipped. - :type f: ``file`` + :type f: has to support ``file``-like operations :type skip_disconnected: ``bool`` """ - if not isinstance(f, file): - raise TypeError('the argument has to be of type file') - disconnected = [] f.write("digraph dependencies {\n") diff --git a/src/distutils2/tests/test_depgraph.py b/src/distutils2/tests/test_depgraph.py --- a/src/distutils2/tests/test_depgraph.py +++ b/src/distutils2/tests/test_depgraph.py @@ -7,12 +7,20 @@ import os import sys +import re +try: + import cStringIO as StringIO +except ImportErorr: + import StringIO class DepGraphTestCase(support.LoggingSilencer, unittest.TestCase): DISTROS_DIST = ('choxie', 'grammar', 'towel-stuff') DISTROS_EGG = ('bacon', 'banana', 'strawberry', 'cheese') + EDGE = re.compile( + r'"(?P.*)" -> "(?P.*)" \[label="(?P