r69127 - in python/branches/py3k-issue1717: Doc/documenting/markup.rst Doc/library/collections.rst Doc/library/datetime.rst Doc/library/queue.rst Doc/library/shelve.rst Doc/reference/datamodel.rst Doc/tools/sphinxext/download.html Doc/whatsnew/2.7.rst Lib/_abcoll.py Lib/colorsys.py Lib/distutils/command/install_lib.py Lib/distutils/command/wininst-9.0-amd64.exe Lib/distutils/command/wininst-9.0.exe Lib/distutils/tests/test_sdist.py Lib/importlib/test/abc.py Lib/importlib/test/builtin/test_
Author: mark.dickinson Date: Fri Jan 30 17:52:02 2009 New Revision: 69127 Log: Merged revisions 69064,69068,69072,69075,69081-69082,69086,69088-69089,69092,69096,69098,69101,69105,69108,69110-69111,69114,69116-69118,69120 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ................ r69064 | guilherme.polo | 2009-01-28 20:40:48 +0000 (Wed, 28 Jan 2009) | 23 lines Merged revisions 69060-69063 via svnmerge from svn+ssh://pythondev/python/trunk ........ r69060 | guilherme.polo | 2009-01-28 17:23:28 -0200 (Wed, 28 Jan 2009) | 2 lines Added support for collecting tests only from specific packages. ........ r69061 | guilherme.polo | 2009-01-28 17:28:04 -0200 (Wed, 28 Jan 2009) | 4 lines * Renaming test_tk_* to test_ttk_* since that is what they are testing. * Added ttk tests to the expected skips mapping just like where test_tcl was expected to be skipped too. ........ r69062 | guilherme.polo | 2009-01-28 18:02:01 -0200 (Wed, 28 Jan 2009) | 1 line Make sure the root windows gets destroyed ........ r69063 | guilherme.polo | 2009-01-28 18:03:26 -0200 (Wed, 28 Jan 2009) | 2 lines Issue #5083: New 'gui' resource for regrtest. ........ ................ r69068 | mark.dickinson | 2009-01-28 21:25:58 +0000 (Wed, 28 Jan 2009) | 3 lines Issue #4707: round(x, n) now returns an integer when x is an integer. Previously it returned a float. ................ r69072 | raymond.hettinger | 2009-01-28 23:33:59 +0000 (Wed, 28 Jan 2009) | 1 line Beef-up tests for collections ABCs. ................ r69075 | raymond.hettinger | 2009-01-29 00:01:27 +0000 (Thu, 29 Jan 2009) | 1 line Correct docs for ABCs (MutableSequence was missing __setiem). Simplify the table by taking out inherited requirements for abstract methods. ................ r69081 | benjamin.peterson | 2009-01-29 01:59:38 +0000 (Thu, 29 Jan 2009) | 14 lines Blocked revisions 69070,69074 via svnmerge ........ r69070 | raymond.hettinger | 2009-01-28 17:02:26 -0600 (Wed, 28 Jan 2009) | 6 lines Issue 4920: Fixed next() vs __next__() issues in the ABCs for Iterator and MutableSet. Also added thorough test for required abstractmethods. ........ r69074 | raymond.hettinger | 2009-01-28 17:58:16 -0600 (Wed, 28 Jan 2009) | 1 line Correct docs for ABCs (MutableSequence was missing __setiem). Simplify the table by taking out inherited requirements for abstract methods. ........ ................ r69082 | benjamin.peterson | 2009-01-29 02:14:30 +0000 (Thu, 29 Jan 2009) | 8 lines Blocked revisions 68521 via svnmerge ........ r68521 | hirokazu.yamamoto | 2009-01-10 21:28:13 -0600 (Sat, 10 Jan 2009) | 1 line Fixed version number in build_ssl.bat. ........ ................ r69086 | raymond.hettinger | 2009-01-29 03:41:55 +0000 (Thu, 29 Jan 2009) | 1 line Update itertools.__doc__ to include all tools. ................ r69088 | raymond.hettinger | 2009-01-29 03:48:02 +0000 (Thu, 29 Jan 2009) | 1 line Fix typo. ................ r69089 | benjamin.peterson | 2009-01-29 03:52:26 +0000 (Thu, 29 Jan 2009) | 12 lines Blocked revisions 69085,69087 via svnmerge ........ r69085 | raymond.hettinger | 2009-01-28 21:21:42 -0600 (Wed, 28 Jan 2009) | 1 line Update itertools.__doc__ to include all tools. ........ r69087 | raymond.hettinger | 2009-01-28 21:43:44 -0600 (Wed, 28 Jan 2009) | 1 line Fix typo. ........ ................ r69092 | brett.cannon | 2009-01-29 04:10:21 +0000 (Thu, 29 Jan 2009) | 17 lines Merged revisions 69078-69080 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r69078 | brett.cannon | 2009-01-28 16:54:11 -0800 (Wed, 28 Jan 2009) | 2 lines Clarify some __del__ stuff. ........ r69079 | brett.cannon | 2009-01-28 16:54:32 -0800 (Wed, 28 Jan 2009) | 2 lines Minor spelling mistake in datetime docs. ........ r69080 | brett.cannon | 2009-01-28 16:55:33 -0800 (Wed, 28 Jan 2009) | 2 lines Ignore .pyc and .pyo files. ........ ................ r69096 | mark.hammond | 2009-01-29 12:36:50 +0000 (Thu, 29 Jan 2009) | 9 lines Merged revisions 69094 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r69094 | mark.hammond | 2009-01-29 23:13:31 +1100 (Thu, 29 Jan 2009) | 2 lines Fix issue5075: bdist_wininst should not depend on the vc runtime? ........ ................ r69098 | mark.hammond | 2009-01-29 13:08:01 +0000 (Thu, 29 Jan 2009) | 2 lines Fix issue5076: bdist_wininst fails on py3k ................ r69101 | antoine.pitrou | 2009-01-29 20:26:59 +0000 (Thu, 29 Jan 2009) | 11 lines Merged revisions 69100 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r69100 | antoine.pitrou | 2009-01-29 21:19:34 +0100 (jeu., 29 janv. 2009) | 5 lines Issue #2047: shutil.move() could believe that its destination path was inside its source path if it began with the same letters (e.g. "src" vs. "src.new"). ........ ................ r69105 | raymond.hettinger | 2009-01-29 22:26:20 +0000 (Thu, 29 Jan 2009) | 1 line Fix error in docs. The source says proto 2 is the default. ................ r69108 | tarek.ziade | 2009-01-29 23:54:06 +0000 (Thu, 29 Jan 2009) | 9 lines Merged revisions 69106 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r69106 | tarek.ziade | 2009-01-30 00:49:17 +0100 (Fri, 30 Jan 2009) | 1 line fixed test_make_distribution so it runs on any platform, as long as tar an gzip are available ........ ................ r69110 | brett.cannon | 2009-01-30 00:22:35 +0000 (Fri, 30 Jan 2009) | 2 lines Merge testing ABCs for importlib into importlib.test.abc. ................ r69111 | brett.cannon | 2009-01-30 01:31:34 +0000 (Fri, 30 Jan 2009) | 3 lines The trace module was trying to turn ints into ints since co_lnotab was changed to a bytes object. ................ r69114 | benjamin.peterson | 2009-01-30 02:29:43 +0000 (Fri, 30 Jan 2009) | 1 line fix a case of set_daemon #5087 ................ r69116 | benjamin.peterson | 2009-01-30 03:01:08 +0000 (Fri, 30 Jan 2009) | 16 lines Blocked revisions 68772,68892,69039 via svnmerge ........ r68772 | benjamin.peterson | 2009-01-19 09:42:23 -0600 (Mon, 19 Jan 2009) | 1 line add a note about the ftruncate change ........ r68892 | martin.v.loewis | 2009-01-24 09:45:18 -0600 (Sat, 24 Jan 2009) | 2 lines Add heading for 2.7a0. ........ r69039 | benjamin.peterson | 2009-01-27 17:15:48 -0600 (Tue, 27 Jan 2009) | 1 line use True and False ........ ................ r69117 | hirokazu.yamamoto | 2009-01-30 03:15:05 +0000 (Fri, 30 Jan 2009) | 1 line Issue #5041: Fixed memory leak. ................ r69118 | benjamin.peterson | 2009-01-30 03:39:35 +0000 (Fri, 30 Jan 2009) | 34 lines Merged revisions 68884,68973,68978,69003,69083,69112-69113 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r68884 | kristjan.jonsson | 2009-01-24 04:52:26 -0600 (Sat, 24 Jan 2009) | 1 line Add a test for UNC import paths, see issue 3677 ........ r68973 | georg.brandl | 2009-01-26 15:29:38 -0600 (Mon, 26 Jan 2009) | 2 lines Copy over docs on advanced role features from Sphinx docs. ........ r68978 | mark.dickinson | 2009-01-26 15:51:56 -0600 (Mon, 26 Jan 2009) | 3 lines Issue #5073: Fix occasional failure of bsddb/test/test_lock.py. Thanks Hirokazu Yamamoto for the patch. ........ r69003 | benjamin.peterson | 2009-01-26 21:07:53 -0600 (Mon, 26 Jan 2009) | 1 line excellent place to use a set() #5069 ........ r69083 | benjamin.peterson | 2009-01-28 21:03:00 -0600 (Wed, 28 Jan 2009) | 1 line fix download url ........ r69112 | benjamin.peterson | 2009-01-29 20:02:25 -0600 (Thu, 29 Jan 2009) | 1 line pep8tify conditionals ........ r69113 | benjamin.peterson | 2009-01-29 20:24:39 -0600 (Thu, 29 Jan 2009) | 1 line make _tkinter._flatten check the result of PySequence_Size for errors #3880 ........ ................ r69120 | benjamin.peterson | 2009-01-30 04:00:29 +0000 (Fri, 30 Jan 2009) | 21 lines Merged revisions 68840,68881,68943,68945 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r68840 | andrew.kuchling | 2009-01-20 20:15:43 -0600 (Tue, 20 Jan 2009) | 1 line Add some items ........ r68881 | andrew.kuchling | 2009-01-23 21:28:18 -0600 (Fri, 23 Jan 2009) | 1 line Add various items ........ r68943 | tarek.ziade | 2009-01-25 16:09:10 -0600 (Sun, 25 Jan 2009) | 1 line Issue #5052: removed backward compatibility information (out of date) ........ r68945 | tarek.ziade | 2009-01-25 16:11:04 -0600 (Sun, 25 Jan 2009) | 1 line added missing module docstring ........ ................ Added: python/branches/py3k-issue1717/Lib/importlib/test/abc.py - copied unchanged from r69120, /python/branches/py3k/Lib/importlib/test/abc.py python/branches/py3k-issue1717/Lib/test/test_ttk_guionly.py - copied unchanged from r69120, /python/branches/py3k/Lib/test/test_ttk_guionly.py python/branches/py3k-issue1717/Lib/test/test_ttk_textonly.py - copied unchanged from r69120, /python/branches/py3k/Lib/test/test_ttk_textonly.py Removed: python/branches/py3k-issue1717/Lib/importlib/test/finder_tests.py python/branches/py3k-issue1717/Lib/importlib/test/loader_tests.py python/branches/py3k-issue1717/Lib/test/test_tk_guionly.py python/branches/py3k-issue1717/Lib/test/test_tk_textonly.py Modified: python/branches/py3k-issue1717/ (props changed) python/branches/py3k-issue1717/Doc/documenting/markup.rst python/branches/py3k-issue1717/Doc/library/collections.rst python/branches/py3k-issue1717/Doc/library/datetime.rst python/branches/py3k-issue1717/Doc/library/queue.rst python/branches/py3k-issue1717/Doc/library/shelve.rst python/branches/py3k-issue1717/Doc/reference/datamodel.rst python/branches/py3k-issue1717/Doc/tools/sphinxext/download.html python/branches/py3k-issue1717/Doc/whatsnew/2.7.rst python/branches/py3k-issue1717/Lib/_abcoll.py python/branches/py3k-issue1717/Lib/colorsys.py python/branches/py3k-issue1717/Lib/distutils/command/install_lib.py python/branches/py3k-issue1717/Lib/distutils/command/wininst-9.0-amd64.exe python/branches/py3k-issue1717/Lib/distutils/command/wininst-9.0.exe python/branches/py3k-issue1717/Lib/distutils/tests/test_sdist.py python/branches/py3k-issue1717/Lib/importlib/test/builtin/test_finder.py python/branches/py3k-issue1717/Lib/importlib/test/extension/test_finder.py python/branches/py3k-issue1717/Lib/importlib/test/frozen/test_finder.py python/branches/py3k-issue1717/Lib/importlib/test/source/test_finder.py python/branches/py3k-issue1717/Lib/posixpath.py python/branches/py3k-issue1717/Lib/shutil.py python/branches/py3k-issue1717/Lib/test/regrtest.py python/branches/py3k-issue1717/Lib/test/test_builtin.py python/branches/py3k-issue1717/Lib/test/test_collections.py python/branches/py3k-issue1717/Lib/test/test_long.py python/branches/py3k-issue1717/Lib/test/test_shutil.py python/branches/py3k-issue1717/Lib/test/test_tcl.py python/branches/py3k-issue1717/Lib/tkinter/test/runtktests.py python/branches/py3k-issue1717/Lib/tkinter/test/test_ttk/test_widgets.py python/branches/py3k-issue1717/Lib/trace.py python/branches/py3k-issue1717/Misc/NEWS python/branches/py3k-issue1717/Modules/_tkinter.c python/branches/py3k-issue1717/Modules/itertoolsmodule.c python/branches/py3k-issue1717/Objects/longobject.c python/branches/py3k-issue1717/PC/bdist_wininst/install.c python/branches/py3k-issue1717/PCbuild/bdist_wininst.vcproj python/branches/py3k-issue1717/Python/bltinmodule.c python/branches/py3k-issue1717/Python/import.c Modified: python/branches/py3k-issue1717/Doc/documenting/markup.rst ============================================================================== --- python/branches/py3k-issue1717/Doc/documenting/markup.rst (original) +++ python/branches/py3k-issue1717/Doc/documenting/markup.rst Fri Jan 30 17:52:02 2009 @@ -290,10 +290,22 @@ For all other roles, you have to write ``:rolename:`content```. -.. note:: +There are some additional facilities that make cross-referencing roles more +versatile: - For all cross-referencing roles, if you prefix the content with ``!``, no - reference/hyperlink will be created. +* You may supply an explicit title and reference target, like in reST direct + hyperlinks: ``:role:`title <target>``` will refer to *target*, but the link + text will be *title*. + +* If you prefix the content with ``!``, no reference/hyperlink will be created. + +* For the Python object roles, if you prefix the content with ``~``, the link + text will only be the last component of the target. For example, + ``:meth:`~Queue.Queue.get``` will refer to ``Queue.Queue.get`` but only + display ``get`` as the link text. + + In HTML output, the link's ``title`` attribute (that is e.g. shown as a + tool-tip on mouse-hover) will always be the full target name. The following roles refer to objects in modules and are possibly hyperlinked if a matching identifier is found: Modified: python/branches/py3k-issue1717/Doc/library/collections.rst ============================================================================== --- python/branches/py3k-issue1717/Doc/library/collections.rst (original) +++ python/branches/py3k-issue1717/Doc/library/collections.rst Fri Jan 30 17:52:02 2009 @@ -45,31 +45,29 @@ :class:`Callable` ``__call__`` :class:`Sequence` :class:`Sized`, ``__getitem__`` ``__contains__``. ``__iter__``, ``__reversed__``. - :class:`Iterable`, and ``__len__`` ``index``, and ``count`` + :class:`Iterable`, ``index``, and ``count`` :class:`Container` -:class:`MutableSequence` :class:`Sequence` ``__getitem__`` Inherited Sequence methods and +:class:`MutableSequence` :class:`Sequence` ``__setitem__`` Inherited Sequence methods and ``__delitem__``, ``append``, ``reverse``, ``extend``, ``pop``, - ``insert``, ``remove``, and ``__iadd__`` - and ``__len__`` + and ``insert`` ``remove``, and ``__iadd__`` -:class:`Set` :class:`Sized`, ``__len__``, ``__le__``, ``__lt__``, ``__eq__``, ``__ne__``, - :class:`Iterable`, ``__iter__``, and ``__gt__``, ``__ge__``, ``__and__``, ``__or__`` - :class:`Container` ``__contains__`` ``__sub__``, ``__xor__``, and ``isdisjoint`` +:class:`Set` :class:`Sized`, ``__le__``, ``__lt__``, ``__eq__``, ``__ne__``, + :class:`Iterable`, ``__gt__``, ``__ge__``, ``__and__``, ``__or__`` + :class:`Container` ``__sub__``, ``__xor__``, and ``isdisjoint`` :class:`MutableSet` :class:`Set` ``add`` and Inherited Set methods and ``discard`` ``clear``, ``pop``, ``remove``, ``__ior__``, ``__iand__``, ``__ixor__``, and ``__isub__`` -:class:`Mapping` :class:`Sized`, ``__getitem__``, ``__contains__``, ``keys``, ``items``, ``values``, - :class:`Iterable`, ``__len__``. and ``get``, ``__eq__``, and ``__ne__`` - :class:`Container` ``__iter__`` - -:class:`MutableMapping` :class:`Mapping` ``__getitem__`` Inherited Mapping methods and - ``__setitem__``, ``pop``, ``popitem``, ``clear``, ``update``, - ``__delitem__``, and ``setdefault`` - ``__iter__``, and - ``__len__`` +:class:`Mapping` :class:`Sized`, ``__getitem__`` ``__contains__``, ``keys``, ``items``, ``values``, + :class:`Iterable`, ``get``, ``__eq__``, and ``__ne__`` + :class:`Container` + +:class:`MutableMapping` :class:`Mapping` ``__setitem__`` and Inherited Mapping methods and + ``__delitem__`` ``pop``, ``popitem``, ``clear``, ``update``, + and ``setdefault`` + :class:`MappingView` :class:`Sized` ``__len__`` :class:`KeysView` :class:`MappingView`, ``__contains__``, Modified: python/branches/py3k-issue1717/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k-issue1717/Doc/library/datetime.rst (original) +++ python/branches/py3k-issue1717/Doc/library/datetime.rst Fri Jan 30 17:52:02 2009 @@ -1266,7 +1266,7 @@ :class:`tzinfo` Objects ----------------------- -:class:`tzinfo` is an abstract base clase, meaning that this class should not be +: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 Modified: python/branches/py3k-issue1717/Doc/library/queue.rst ============================================================================== --- python/branches/py3k-issue1717/Doc/library/queue.rst (original) +++ python/branches/py3k-issue1717/Doc/library/queue.rst Fri Jan 30 17:52:02 2009 @@ -147,7 +147,7 @@ q = Queue() for i in range(num_worker_threads): t = Thread(target=worker) - t.set_daemon(True) + t.daemon = True t.start() for item in source(): Modified: python/branches/py3k-issue1717/Doc/library/shelve.rst ============================================================================== --- python/branches/py3k-issue1717/Doc/library/shelve.rst (original) +++ python/branches/py3k-issue1717/Doc/library/shelve.rst Fri Jan 30 17:52:02 2009 @@ -23,7 +23,7 @@ database file is opened for reading and writing. The optional *flag* parameter has the same interpretation as the *flag* parameter of :func:`dbm.open`. - By default, version 0 pickles are used to serialize values. The version of the + By default, version 2 pickles are used to serialize values. The version of the pickle protocol can be specified with the *protocol* parameter. By default, mutations to persistent-dictionary mutable entries are not Modified: python/branches/py3k-issue1717/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k-issue1717/Doc/reference/datamodel.rst (original) +++ python/branches/py3k-issue1717/Doc/reference/datamodel.rst Fri Jan 30 17:52:02 2009 @@ -1096,7 +1096,9 @@ is printed to ``sys.stderr`` instead. Also, when :meth:`__del__` is invoked in response to a module being deleted (e.g., when execution of the program is done), other globals referenced by the :meth:`__del__` method may already have - been deleted. For this reason, :meth:`__del__` methods should do the absolute + been deleted or in the process of being torn down (e.g. the import + machinery shutting down). For this reason, :meth:`__del__` methods + should do the absolute minimum needed to maintain external invariants. Starting with version 1.5, Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other Modified: python/branches/py3k-issue1717/Doc/tools/sphinxext/download.html ============================================================================== --- python/branches/py3k-issue1717/Doc/tools/sphinxext/download.html (original) +++ python/branches/py3k-issue1717/Doc/tools/sphinxext/download.html Fri Jan 30 17:52:02 2009 @@ -31,7 +31,7 @@ <td><a href="{{ dlbase }}/python-{{ release }}-docs-html.tar.bz2">Download</a> (ca. 4 MB)</td> </tr> <tr><td>Plain Text</td> - <td><a href="{{ dlbase }}/python-docs-text.zip">Download</a> (ca. 2 MB)</td> + <td><a href="{{ dlbase }}/python-{{ release }}-text.zip">Download</a> (ca. 2 MB)</td> <td><a href="{{ dlbase }}/python-{{ release }}-docs-text.tar.bz2">Download</a> (ca. 1.5 MB)</td> </tr> </table> Modified: python/branches/py3k-issue1717/Doc/whatsnew/2.7.rst ============================================================================== --- python/branches/py3k-issue1717/Doc/whatsnew/2.7.rst (original) +++ python/branches/py3k-issue1717/Doc/whatsnew/2.7.rst Fri Jan 30 17:52:02 2009 @@ -6,6 +6,8 @@ :Release: |release| :Date: |today| +.. Fix accents on Kristjan Valur Jonsson, Fuerstenau. + .. $Id$ Rules for maintenance: @@ -60,11 +62,6 @@ .. ======================================================================== -Kristján Valur Jónsson, issue 4293 -Py_AddPendingCall is now thread safe. This allows any worker thread -to submit notifications to the python main thread. This is particularly -useful for asynchronous IO operations. - Other Language Changes ====================== @@ -95,7 +92,19 @@ Optimizations ------------- -To be written. +A few performance enhancements have been added: + +* The garbage collector now performs better when many objects are + being allocated without deallocating any. A full garbage collection + pass is only performed when the middle generation has been collected + 10 times and when the number of survivor objects from the middle + generation exceeds 10% of the number of objects in the oldest + generation. The second condition was added to reduce the number + of full garbage collections as the number of objects on the heap grows, + avoiding quadratic performance when allocating very many objects. + (Suggested by Martin von Loewis and implemented by Antoine Pitrou; + :issue:`4074`.) + .. ====================================================================== @@ -108,6 +117,62 @@ :file:`Misc/NEWS` file in the source tree for a more complete list of changes, or look through the Subversion logs for all the details. +* It is not mandatory anymore to store clear text passwords in the + :file:`.pypirc` file when registering and uploading packages to PyPI. As long + as the username is present in that file, the :mod:`distutils` package will + prompt for the password if not present. (Added by tarek, with the initial + contribution of Nathan Van Gheem; :issue:`4394`.) + +* The :mod:`bz2` module's :class:`BZ2File` now supports the context + management protocol, so you can write ``with bz2.BZ2File(...) as f: ...``. + (Contributed by Hagen Fuerstenau; :issue:`3860`.) + +* A new :class:`Counter` class in the :mod:`collections` module is + useful for tallying data. :class:`Counter` instances behave mostly + like dictionaries but return zero for missing keys instead of + raising a :exc:`KeyError`:: + + >>> from collections import Counter + >>> c=Counter() + >>> for letter in 'here is a sample of english text': + ... c[letter] += 1 + ... + >>> c + Counter({' ': 6, 'e': 5, 's': 3, 'a': 2, 'i': 2, 'h': 2, + 'l': 2, 't': 2, 'g': 1, 'f': 1, 'm': 1, 'o': 1, 'n': 1, + 'p': 1, 'r': 1, 'x': 1}) + >>> c['e'] + 5 + >>> c['z'] + 0 + + There are two additional :class:`Counter` methods: :meth:`most_common` + returns the N most common elements and their counts, and :meth:`elements` + returns an iterator over the contained element, repeating each element + as many times as its count:: + + >>> c.most_common(5) + [(' ', 6), ('e', 5), ('s', 3), ('a', 2), ('i', 2)] + >>> c.elements() -> + 'a', 'a', ' ', ' ', ' ', ' ', ' ', ' ', + 'e', 'e', 'e', 'e', 'e', 'g', 'f', 'i', 'i', + 'h', 'h', 'm', 'l', 'l', 'o', 'n', 'p', 's', + 's', 's', 'r', 't', 't', 'x'] + + Contributed by Raymond Hettinger; :issue:`1696199`. + +* The :mod:`gzip` module's :class:`GzipFile` now supports the context + management protocol, so you can write ``with gzip.GzipFile(...) as f: ...``. + (Contributed by Hagen Fuerstenau; :issue:`3860`.) + +* The :class:`io.FileIO` class now raises an :exc:`OSError` when passed + an invalid file descriptor. (Implemented by Benjamin Peterson; + :issue:`4991`.) + +* The :mod:`pydoc` module now has help for the various symbols that Python + uses. You can now do ``help('<<')`` or ``help('@')``, for example. + (Contributed by David Laban; :issue:`4739`.) + * A new function in the :mod:`subprocess` module, :func:`check_output`, runs a command with a specified set of arguments and returns the command's output as a string if the command runs without @@ -125,11 +190,9 @@ (Contributed by Gregory P. Smith.) -* It is not mandatory anymore to store clear text passwords in the - :file:`.pypirc` file when registering and uploading packages to PyPI. As long - as the username is present in that file, the :mod:`distutils` package will - prompt for the password if not present. (Added by tarek, with the initial - contribution of Nathan Van Gheem; :issue:`4394`.) +* The :func:`is_zipfile` function in the :mod:`zipfile` module will now + accept a file object, in addition to the path names accepted in earlier + versions. (Contributed by Gabriel Genellina; :issue:`4756`.) .. ====================================================================== .. whole new modules get described in subsections here @@ -145,7 +208,13 @@ * If you use the :file:`.gdbinit` file provided with Python, the "pyo" macro in the 2.7 version will now work when the thread being debugged doesn't hold the GIL; the macro will now acquire it before printing. - (Contributed by haypo XXX; :issue:`3632`.) + (Contributed by Victor Stinner; :issue:`3632`.) + +* :cfunc:`Py_AddPendingCall` is now thread safe, letting any + worker thread submit notifications to the main Python thread. This + is particularly useful for asynchronous IO operations. + (Contributed by Kristjan Valur Jonsson; :issue:`4293`.) + .. ====================================================================== @@ -157,7 +226,11 @@ :data:`CRT_ASSEMBLY_VERSION`, :data:`VC_ASSEMBLY_PUBLICKEYTOKEN`, and :data:`LIBRARIES_ASSEMBLY_NAME_PREFIX`. - (Added by Martin von Loewis (XXX check); :issue:`4365`.) + (Contributed by David Cournapeau; :issue:`4365`.) + +* The new :cfunc:`_beginthreadex` API is used to start threads, and + the native thread-local storage functions are now used. + (Contributed by Kristjan Valur Jonsson; :issue:`3582`.) .. ====================================================================== Modified: python/branches/py3k-issue1717/Lib/_abcoll.py ============================================================================== --- python/branches/py3k-issue1717/Lib/_abcoll.py (original) +++ python/branches/py3k-issue1717/Lib/_abcoll.py Fri Jan 30 17:52:02 2009 @@ -301,7 +301,7 @@ """Return the popped value. Raise KeyError if empty.""" it = iter(self) try: - value = it.__next__() + value = next(it) except StopIteration: raise KeyError self.discard(value) Modified: python/branches/py3k-issue1717/Lib/colorsys.py ============================================================================== --- python/branches/py3k-issue1717/Lib/colorsys.py (original) +++ python/branches/py3k-issue1717/Lib/colorsys.py Fri Jan 30 17:52:02 2009 @@ -44,12 +44,18 @@ r = y + 0.948262*i + 0.624013*q g = y - 0.276066*i - 0.639810*q b = y - 1.105450*i + 1.729860*q - if r < 0.0: r = 0.0 - if g < 0.0: g = 0.0 - if b < 0.0: b = 0.0 - if r > 1.0: r = 1.0 - if g > 1.0: g = 1.0 - if b > 1.0: b = 1.0 + if r < 0.0: + r = 0.0 + if g < 0.0: + g = 0.0 + if b < 0.0: + b = 0.0 + if r > 1.0: + r = 1.0 + if g > 1.0: + g = 1.0 + if b > 1.0: + b = 1.0 return (r, g, b) @@ -63,30 +69,42 @@ minc = min(r, g, b) # XXX Can optimize (maxc+minc) and (maxc-minc) l = (minc+maxc)/2.0 - if minc == maxc: return 0.0, l, 0.0 - if l <= 0.5: s = (maxc-minc) / (maxc+minc) - else: s = (maxc-minc) / (2.0-maxc-minc) + if minc == maxc: + return 0.0, l, 0.0 + if l <= 0.5: + s = (maxc-minc) / (maxc+minc) + else: + s = (maxc-minc) / (2.0-maxc-minc) rc = (maxc-r) / (maxc-minc) gc = (maxc-g) / (maxc-minc) bc = (maxc-b) / (maxc-minc) - if r == maxc: h = bc-gc - elif g == maxc: h = 2.0+rc-bc - else: h = 4.0+gc-rc + if r == maxc: + h = bc-gc + elif g == maxc: + h = 2.0+rc-bc + else: + h = 4.0+gc-rc h = (h/6.0) % 1.0 return h, l, s def hls_to_rgb(h, l, s): - if s == 0.0: return l, l, l - if l <= 0.5: m2 = l * (1.0+s) - else: m2 = l+s-(l*s) + if s == 0.0: + return l, l, l + if l <= 0.5: + m2 = l * (1.0+s) + else: + m2 = l+s-(l*s) m1 = 2.0*l - m2 return (_v(m1, m2, h+ONE_THIRD), _v(m1, m2, h), _v(m1, m2, h-ONE_THIRD)) def _v(m1, m2, hue): hue = hue % 1.0 - if hue < ONE_SIXTH: return m1 + (m2-m1)*hue*6.0 - if hue < 0.5: return m2 - if hue < TWO_THIRD: return m1 + (m2-m1)*(TWO_THIRD-hue)*6.0 + if hue < ONE_SIXTH: + return m1 + (m2-m1)*hue*6.0 + if hue < 0.5: + return m2 + if hue < TWO_THIRD: + return m1 + (m2-m1)*(TWO_THIRD-hue)*6.0 return m1 @@ -99,29 +117,40 @@ maxc = max(r, g, b) minc = min(r, g, b) v = maxc - if minc == maxc: return 0.0, 0.0, v + if minc == maxc: + return 0.0, 0.0, v s = (maxc-minc) / maxc rc = (maxc-r) / (maxc-minc) gc = (maxc-g) / (maxc-minc) bc = (maxc-b) / (maxc-minc) - if r == maxc: h = bc-gc - elif g == maxc: h = 2.0+rc-bc - else: h = 4.0+gc-rc + if r == maxc: + h = bc-gc + elif g == maxc: + h = 2.0+rc-bc + else: + h = 4.0+gc-rc h = (h/6.0) % 1.0 return h, s, v def hsv_to_rgb(h, s, v): - if s == 0.0: return v, v, v + if s == 0.0: + return v, v, v i = int(h*6.0) # XXX assume int() truncates! f = (h*6.0) - i p = v*(1.0 - s) q = v*(1.0 - s*f) t = v*(1.0 - s*(1.0-f)) i = i%6 - if i == 0: return v, t, p - if i == 1: return q, v, p - if i == 2: return p, v, t - if i == 3: return p, q, v - if i == 4: return t, p, v - if i == 5: return v, p, q + if i == 0: + return v, t, p + if i == 1: + return q, v, p + if i == 2: + return p, v, t + if i == 3: + return p, q, v + if i == 4: + return t, p, v + if i == 5: + return v, p, q # Cannot get here Modified: python/branches/py3k-issue1717/Lib/distutils/command/install_lib.py ============================================================================== --- python/branches/py3k-issue1717/Lib/distutils/command/install_lib.py (original) +++ python/branches/py3k-issue1717/Lib/distutils/command/install_lib.py Fri Jan 30 17:52:02 2009 @@ -1,3 +1,8 @@ +"""distutils.command.install_lib + +Implements the Distutils 'install_lib' command +(install all Python modules).""" + __revision__ = "$Id$" import sys, os Modified: python/branches/py3k-issue1717/Lib/distutils/command/wininst-9.0-amd64.exe ============================================================================== Binary files. No diff available. Modified: python/branches/py3k-issue1717/Lib/distutils/command/wininst-9.0.exe ============================================================================== Binary files. No diff available. Modified: python/branches/py3k-issue1717/Lib/distutils/tests/test_sdist.py ============================================================================== --- python/branches/py3k-issue1717/Lib/distutils/tests/test_sdist.py (original) +++ python/branches/py3k-issue1717/Lib/distutils/tests/test_sdist.py Fri Jan 30 17:52:02 2009 @@ -10,7 +10,7 @@ from distutils.core import Distribution from distutils.tests.test_config import PyPIRCCommandTestCase from distutils.errors import DistutilsExecError -from distutils.spawn import spawn +from distutils.spawn import find_executable CURDIR = os.path.dirname(__file__) TEMP_PKG = join(CURDIR, 'temppkg') @@ -111,15 +111,12 @@ def test_make_distribution(self): - self._init_tmp_pkg() + # check if tar and gzip are installed + if (find_executable('tar') is None or + find_executable('gzip') is None): + return - # check if tar is installed under win32 - if sys.platform == 'win32': - try: - spawn('tar --help') - except DistutilsExecError: - # let's return, no need to go further - return + self._init_tmp_pkg() # now building a sdist dist = Distribution() Modified: python/branches/py3k-issue1717/Lib/importlib/test/builtin/test_finder.py ============================================================================== --- python/branches/py3k-issue1717/Lib/importlib/test/builtin/test_finder.py (original) +++ python/branches/py3k-issue1717/Lib/importlib/test/builtin/test_finder.py Fri Jan 30 17:52:02 2009 @@ -1,11 +1,11 @@ from importlib import machinery -from .. import finder_tests +from .. import abc from .. import support import sys import unittest -class FinderTests(finder_tests.FinderTests): +class FinderTests(abc.FinderTests): """Test find_module() for built-in modules.""" Modified: python/branches/py3k-issue1717/Lib/importlib/test/extension/test_finder.py ============================================================================== --- python/branches/py3k-issue1717/Lib/importlib/test/extension/test_finder.py (original) +++ python/branches/py3k-issue1717/Lib/importlib/test/extension/test_finder.py Fri Jan 30 17:52:02 2009 @@ -1,10 +1,10 @@ import importlib -from .. import finder_tests +from .. import abc from . import test_path_hook import unittest -class FinderTests(finder_tests.FinderTests): +class FinderTests(abc.FinderTests): """Test the finder for extension modules.""" Deleted: python/branches/py3k-issue1717/Lib/importlib/test/finder_tests.py ============================================================================== --- python/branches/py3k-issue1717/Lib/importlib/test/finder_tests.py Fri Jan 30 17:52:02 2009 +++ (empty file) @@ -1,39 +0,0 @@ -import abc -import unittest - - -class FinderTests(unittest.TestCase, metaclass=abc.ABCMeta): - - """Basic tests for a finder to pass.""" - - @abc.abstractmethod - def test_module(self): - # Test importing a top-level module. - pass - - @abc.abstractmethod - def test_package(self): - # Test importing a package. - pass - - @abc.abstractmethod - def test_module_in_package(self): - # Test importing a module contained within a package. - # A value for 'path' should be used if for a meta_path finder. - pass - - @abc.abstractmethod - def test_package_in_package(self): - # Test importing a subpackage. - # A value for 'path' should be used if for a meta_path finder. - pass - - @abc.abstractmethod - def test_package_over_module(self): - # Test that packages are chosen over modules. - pass - - @abc.abstractmethod - def test_failure(self): - # Test trying to find a module that cannot be handled. - pass Modified: python/branches/py3k-issue1717/Lib/importlib/test/frozen/test_finder.py ============================================================================== --- python/branches/py3k-issue1717/Lib/importlib/test/frozen/test_finder.py (original) +++ python/branches/py3k-issue1717/Lib/importlib/test/frozen/test_finder.py Fri Jan 30 17:52:02 2009 @@ -1,10 +1,10 @@ from ... import machinery -from .. import finder_tests +from .. import abc import unittest -class FinderTests(finder_tests.FinderTests): +class FinderTests(abc.FinderTests): """Test finding frozen modules.""" Deleted: python/branches/py3k-issue1717/Lib/importlib/test/loader_tests.py ============================================================================== --- python/branches/py3k-issue1717/Lib/importlib/test/loader_tests.py Fri Jan 30 17:52:02 2009 +++ (empty file) @@ -1,61 +0,0 @@ -import abc -import unittest - - -class LoaderTests(unittest.TestCase, metaclass=abc.ABCMeta): - - @abc.abstractmethod - def test_module(self): - """A module should load without issue. - - After the loader returns the module should be in sys.modules. - - Attributes to verify: - - * __file__ - * __loader__ - * __name__ - * No __path__ - - """ - pass - - @abc.abstractmethod - def test_package(self): - """Loading a package should work. - - After the loader returns the module should be in sys.modules. - - Attributes to verify: - - * __file__ - * __loader__ - * __name__ - * __path__ - - """ - pass - - @abc.abstractmethod - def test_lacking_parent(self): - """A loader should not be dependent on it's parent package being - imported.""" - pass - - @abc.abstractmethod - def test_module_reuse(self): - """If a module is already in sys.modules, it should be reused.""" - pass - - @abc.abstractmethod - def test_state_after_failure(self): - """If a module is already in sys.modules and a reload fails - (e.g. a SyntaxError), the module should be in the state it was before - the reload began.""" - pass - - @abc.abstractmethod - def test_unloadable(self): - """Test ImportError is raised when the loader is asked to load a module - it can't.""" - pass Modified: python/branches/py3k-issue1717/Lib/importlib/test/source/test_finder.py ============================================================================== --- python/branches/py3k-issue1717/Lib/importlib/test/source/test_finder.py (original) +++ python/branches/py3k-issue1717/Lib/importlib/test/source/test_finder.py Fri Jan 30 17:52:02 2009 @@ -1,5 +1,5 @@ import importlib -from .. import finder_tests +from .. import abc from .. import support import os import py_compile @@ -7,7 +7,7 @@ import warnings -class FinderTests(finder_tests.FinderTests): +class FinderTests(abc.FinderTests): """For a top-level module, it should just be found directly in the directory being searched. This is true for a directory with source Modified: python/branches/py3k-issue1717/Lib/posixpath.py ============================================================================== --- python/branches/py3k-issue1717/Lib/posixpath.py (original) +++ python/branches/py3k-issue1717/Lib/posixpath.py Fri Jan 30 17:52:02 2009 @@ -403,12 +403,12 @@ until we either arrive at something that isn't a symlink, or encounter a path we've seen before (meaning that there's a loop). """ - paths_seen = [] + paths_seen = set() while islink(path): if path in paths_seen: # Already seen this path, so we must have a symlink loop return None - paths_seen.append(path) + paths_seen.add(path) # Resolve where the link points to resolved = os.readlink(path) if not isabs(resolved): Modified: python/branches/py3k-issue1717/Lib/shutil.py ============================================================================== --- python/branches/py3k-issue1717/Lib/shutil.py (original) +++ python/branches/py3k-issue1717/Lib/shutil.py Fri Jan 30 17:52:02 2009 @@ -265,4 +265,10 @@ os.unlink(src) def destinsrc(src, dst): - return abspath(dst).startswith(abspath(src)) + src = abspath(src) + dst = abspath(dst) + if not src.endswith(os.path.sep): + src += os.path.sep + if not dst.endswith(os.path.sep): + dst += os.path.sep + return dst.startswith(src) Modified: python/branches/py3k-issue1717/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k-issue1717/Lib/test/regrtest.py (original) +++ python/branches/py3k-issue1717/Lib/test/regrtest.py Fri Jan 30 17:52:02 2009 @@ -123,6 +123,8 @@ urlfetch - It is okay to download files required on testing. + gui - Run tests that require a running GUI. + To enable all resources except one, use '-uall,-<resource>'. For example, to run all the tests except for the bsddb tests, give the option '-uall,-bsddb'. @@ -176,7 +178,7 @@ from test import support RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', 'bsddb', - 'decimal', 'compiler', 'subprocess', 'urlfetch') + 'decimal', 'compiler', 'subprocess', 'urlfetch', 'gui') def usage(msg): @@ -1073,6 +1075,8 @@ test_pty test_socketserver test_tcl + test_ttk_guionly + test_ttk_textonly test_timeout test_urllibnet test_multiprocessing @@ -1088,6 +1092,8 @@ test_kqueue test_ossaudiodev test_tcl + test_ttk_guionly + test_ttk_textonly test_zipimport test_zlib """, @@ -1103,6 +1109,8 @@ test_ossaudiodev test_pep277 test_tcl + test_ttk_guionly + test_ttk_textonly test_multiprocessing """, 'netbsd3': @@ -1117,6 +1125,8 @@ test_ossaudiodev test_pep277 test_tcl + test_ttk_guionly + test_ttk_textonly test_multiprocessing """, } Modified: python/branches/py3k-issue1717/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k-issue1717/Lib/test/test_builtin.py (original) +++ python/branches/py3k-issue1717/Lib/test/test_builtin.py Fri Jan 30 17:52:02 2009 @@ -1066,9 +1066,9 @@ self.assertEqual(round(8), 8) self.assertEqual(round(-8), -8) self.assertEqual(type(round(0)), int) - self.assertEqual(type(round(-8, -1)), float) - self.assertEqual(type(round(-8, 0)), float) - self.assertEqual(type(round(-8, 1)), float) + self.assertEqual(type(round(-8, -1)), int) + self.assertEqual(type(round(-8, 0)), int) + self.assertEqual(type(round(-8, 1)), int) # test new kwargs self.assertEqual(round(number=-8.0, ndigits=-1), -10.0) Modified: python/branches/py3k-issue1717/Lib/test/test_collections.py ============================================================================== --- python/branches/py3k-issue1717/Lib/test/test_collections.py (original) +++ python/branches/py3k-issue1717/Lib/test/test_collections.py Fri Jan 30 17:52:02 2009 @@ -160,7 +160,24 @@ self.assertEqual(p, q) self.assertEqual(p._fields, q._fields) -class TestOneTrickPonyABCs(unittest.TestCase): +class ABCTestCase(unittest.TestCase): + + def validate_abstract_methods(self, abc, *names): + methodstubs = dict.fromkeys(names, lambda s, *args: 0) + + # everything should work will all required methods are present + C = type('C', (abc,), methodstubs) + C() + + # instantiation should fail if a required method is missing + for name in names: + stubs = methodstubs.copy() + del stubs[name] + C = type('C', (abc,), stubs) + self.assertRaises(TypeError, C, name) + + +class TestOneTrickPonyABCs(ABCTestCase): def test_Hashable(self): # Check some non-hashables @@ -185,6 +202,7 @@ return super().__hash__() self.assertEqual(hash(H()), 0) self.failIf(issubclass(int, H)) + self.validate_abstract_methods(Hashable, '__hash__') def test_Iterable(self): # Check some non-iterables @@ -208,6 +226,7 @@ return super().__iter__() self.assertEqual(list(I()), []) self.failIf(issubclass(str, I)) + self.validate_abstract_methods(Iterable, '__iter__') def test_Iterator(self): non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()] @@ -225,6 +244,7 @@ for x in samples: self.failUnless(isinstance(x, Iterator), repr(x)) self.failUnless(issubclass(type(x), Iterator), repr(type(x))) + self.validate_abstract_methods(Iterator, '__next__') def test_Sized(self): non_samples = [None, 42, 3.14, 1j, @@ -241,6 +261,7 @@ for x in samples: self.failUnless(isinstance(x, Sized), repr(x)) self.failUnless(issubclass(type(x), Sized), repr(type(x))) + self.validate_abstract_methods(Sized, '__len__') def test_Container(self): non_samples = [None, 42, 3.14, 1j, @@ -257,6 +278,7 @@ for x in samples: self.failUnless(isinstance(x, Container), repr(x)) self.failUnless(issubclass(type(x), Container), repr(type(x))) + self.validate_abstract_methods(Container, '__contains__') def test_Callable(self): non_samples = [None, 42, 3.14, 1j, @@ -275,6 +297,7 @@ for x in samples: self.failUnless(isinstance(x, Callable), repr(x)) self.failUnless(issubclass(type(x), Callable), repr(type(x))) + self.validate_abstract_methods(Callable, '__call__') def test_direct_subclassing(self): for B in Hashable, Iterable, Iterator, Sized, Container, Callable: @@ -292,7 +315,7 @@ self.failUnless(issubclass(C, B)) -class TestCollectionABCs(unittest.TestCase): +class TestCollectionABCs(ABCTestCase): # XXX For now, we only test some virtual inheritance properties. # We should also test the proper behavior of the collection ABCs @@ -302,6 +325,7 @@ for sample in [set, frozenset]: self.failUnless(isinstance(sample(), Set)) self.failUnless(issubclass(sample, Set)) + self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') def test_hash_Set(self): class OneTwoThreeSet(Set): @@ -323,22 +347,57 @@ self.failUnless(issubclass(set, MutableSet)) self.failIf(isinstance(frozenset(), MutableSet)) self.failIf(issubclass(frozenset, MutableSet)) + self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', + 'add', 'discard') + + def test_issue_4920(self): + # MutableSet.pop() method did not work + class MySet(collections.MutableSet): + __slots__=['__s'] + def __init__(self,items=None): + if items is None: + items=[] + self.__s=set(items) + def __contains__(self,v): + return v in self.__s + def __iter__(self): + return iter(self.__s) + def __len__(self): + return len(self.__s) + def add(self,v): + result=v not in self.__s + self.__s.add(v) + return result + def discard(self,v): + result=v in self.__s + self.__s.discard(v) + return result + def __repr__(self): + return "MySet(%s)" % repr(list(self)) + s = MySet([5,43,2,1]) + self.assertEqual(s.pop(), 1) def test_Mapping(self): for sample in [dict]: self.failUnless(isinstance(sample(), Mapping)) self.failUnless(issubclass(sample, Mapping)) + self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', + '__getitem__') def test_MutableMapping(self): for sample in [dict]: self.failUnless(isinstance(sample(), MutableMapping)) self.failUnless(issubclass(sample, MutableMapping)) + self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', + '__getitem__', '__setitem__', '__delitem__') def test_Sequence(self): for sample in [tuple, list, bytes, str]: self.failUnless(isinstance(sample(), Sequence)) self.failUnless(issubclass(sample, Sequence)) self.failUnless(issubclass(str, Sequence)) + self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', + '__getitem__') def test_ByteString(self): for sample in [bytes, bytearray]: @@ -358,6 +417,8 @@ self.failUnless(isinstance(sample(), MutableSequence)) self.failUnless(issubclass(sample, MutableSequence)) self.failIf(issubclass(str, MutableSequence)) + self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', + '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') class TestCounter(unittest.TestCase): Modified: python/branches/py3k-issue1717/Lib/test/test_long.py ============================================================================== --- python/branches/py3k-issue1717/Lib/test/test_long.py (original) +++ python/branches/py3k-issue1717/Lib/test/test_long.py Fri Jan 30 17:52:02 2009 @@ -896,6 +896,81 @@ self.assertEqual((a+1).bit_length(), i+1) self.assertEqual((-a-1).bit_length(), i+1) + def test_round(self): + # check round-half-even algorithm. For round to nearest ten; + # rounding map is invariant under adding multiples of 20 + test_dict = {0:0, 1:0, 2:0, 3:0, 4:0, 5:0, + 6:10, 7:10, 8:10, 9:10, 10:10, 11:10, 12:10, 13:10, 14:10, + 15:20, 16:20, 17:20, 18:20, 19:20} + for offset in range(-520, 520, 20): + for k, v in test_dict.items(): + got = round(k+offset, -1) + expected = v+offset + self.assertEqual(got, expected) + self.assert_(type(got) is int) + + # larger second argument + self.assertEqual(round(-150, -2), -200) + self.assertEqual(round(-149, -2), -100) + self.assertEqual(round(-51, -2), -100) + self.assertEqual(round(-50, -2), 0) + self.assertEqual(round(-49, -2), 0) + self.assertEqual(round(-1, -2), 0) + self.assertEqual(round(0, -2), 0) + self.assertEqual(round(1, -2), 0) + self.assertEqual(round(49, -2), 0) + self.assertEqual(round(50, -2), 0) + self.assertEqual(round(51, -2), 100) + self.assertEqual(round(149, -2), 100) + self.assertEqual(round(150, -2), 200) + self.assertEqual(round(250, -2), 200) + self.assertEqual(round(251, -2), 300) + self.assertEqual(round(172500, -3), 172000) + self.assertEqual(round(173500, -3), 174000) + self.assertEqual(round(31415926535, -1), 31415926540) + self.assertEqual(round(31415926535, -2), 31415926500) + self.assertEqual(round(31415926535, -3), 31415927000) + self.assertEqual(round(31415926535, -4), 31415930000) + self.assertEqual(round(31415926535, -5), 31415900000) + self.assertEqual(round(31415926535, -6), 31416000000) + self.assertEqual(round(31415926535, -7), 31420000000) + self.assertEqual(round(31415926535, -8), 31400000000) + self.assertEqual(round(31415926535, -9), 31000000000) + self.assertEqual(round(31415926535, -10), 30000000000) + self.assertEqual(round(31415926535, -11), 0) + self.assertEqual(round(31415926535, -12), 0) + self.assertEqual(round(31415926535, -999), 0) + + # should get correct results even for huge inputs + for k in range(10, 100): + got = round(10**k + 324678, -3) + expect = 10**k + 325000 + self.assertEqual(got, expect) + self.assert_(type(got) is int) + + # nonnegative second argument: round(x, n) should just return x + for n in range(5): + for i in range(100): + x = random.randrange(-10000, 10000) + got = round(x, n) + self.assertEqual(got, x) + self.assert_(type(got) is int) + for huge_n in 2**31-1, 2**31, 2**63-1, 2**63, 2**100, 10**100: + self.assertEqual(round(8979323, huge_n), 8979323) + + # omitted second argument + for i in range(100): + x = random.randrange(-10000, 10000) + got = round(x) + self.assertEqual(got, x) + self.assert_(type(got) is int) + + # bad second argument + bad_exponents = ('brian', 2.0, 0j, None) + for e in bad_exponents: + self.assertRaises(TypeError, round, 3, e) + + def test_main(): support.run_unittest(LongTest) Modified: python/branches/py3k-issue1717/Lib/test/test_shutil.py ============================================================================== --- python/branches/py3k-issue1717/Lib/test/test_shutil.py (original) +++ python/branches/py3k-issue1717/Lib/test/test_shutil.py Fri Jan 30 17:52:02 2009 @@ -340,7 +340,29 @@ dst = os.path.join(self.src_dir, "bar") self.assertRaises(shutil.Error, shutil.move, self.src_dir, dst) + def test_destinsrc_false_negative(self): + os.mkdir(TESTFN) + try: + for src, dst in [('srcdir', 'srcdir/dest')]: + src = os.path.join(TESTFN, src) + dst = os.path.join(TESTFN, dst) + self.assert_(shutil.destinsrc(src, dst), + msg='destinsrc() wrongly concluded that ' + 'dst (%s) is not in src (%s)' % (dst, src)) + finally: + shutil.rmtree(TESTFN, ignore_errors=True) + def test_destinsrc_false_positive(self): + os.mkdir(TESTFN) + try: + for src, dst in [('srcdir', 'src/dest'), ('srcdir', 'srcdir.new')]: + src = os.path.join(TESTFN, src) + dst = os.path.join(TESTFN, dst) + self.failIf(shutil.destinsrc(src, dst), + msg='destinsrc() wrongly concluded that ' + 'dst (%s) is in src (%s)' % (dst, src)) + finally: + shutil.rmtree(TESTFN, ignore_errors=True) def test_main(): support.run_unittest(TestShutil, TestMove) Modified: python/branches/py3k-issue1717/Lib/test/test_tcl.py ============================================================================== --- python/branches/py3k-issue1717/Lib/test/test_tcl.py (original) +++ python/branches/py3k-issue1717/Lib/test/test_tcl.py Fri Jan 30 17:52:02 2009 @@ -2,10 +2,19 @@ import unittest import os +import _tkinter from test import support from tkinter import Tcl from _tkinter import TclError + +class TkinterTest(unittest.TestCase): + + def testFlattenLen(self): + # flatten(<object with no length>) + self.assertRaises(TypeError, _tkinter._flatten, True) + + class TclTest(unittest.TestCase): def setUp(self): @@ -151,7 +160,7 @@ os.environ['DISPLAY'] = old_display def test_main(): - support.run_unittest(TclTest) + support.run_unittest(TclTest, TkinterTest) if __name__ == "__main__": test_main() Deleted: python/branches/py3k-issue1717/Lib/test/test_tk_guionly.py ============================================================================== --- python/branches/py3k-issue1717/Lib/test/test_tk_guionly.py Fri Jan 30 17:52:02 2009 +++ (empty file) @@ -1,14 +0,0 @@ -from test import support -from tkinter.test import runtktests - -def test_main(enable_gui=False): - if enable_gui: - if support.use_resources is None: - support.use_resources = ['gui'] - elif 'gui' not in support.use_resources: - support.use_resources.append('gui') - - support.run_unittest(*runtktests.get_tests(text=False)) - -if __name__ == '__main__': - test_main(enable_gui=True) Deleted: python/branches/py3k-issue1717/Lib/test/test_tk_textonly.py ============================================================================== --- python/branches/py3k-issue1717/Lib/test/test_tk_textonly.py Fri Jan 30 17:52:02 2009 +++ (empty file) @@ -1,8 +0,0 @@ -from test import support -from tkinter.test import runtktests - -def test_main(): - support.run_unittest(*runtktests.get_tests(gui=False)) - -if __name__ == '__main__': - test_main() Modified: python/branches/py3k-issue1717/Lib/tkinter/test/runtktests.py ============================================================================== --- python/branches/py3k-issue1717/Lib/tkinter/test/runtktests.py (original) +++ python/branches/py3k-issue1717/Lib/tkinter/test/runtktests.py Fri Jan 30 17:52:02 2009 @@ -19,9 +19,13 @@ return True return False -def get_tests_modules(basepath=this_dir_path, gui=True): +def get_tests_modules(basepath=this_dir_path, gui=True, packages=None): """This will import and yield modules whose names start with test_ - and are inside packages found in the path starting at basepath.""" + and are inside packages found in the path starting at basepath. + + If packages is specified it should contain package names that + want their tests collected. + """ py_ext = '.py' for dirpath, dirnames, filenames in os.walk(basepath): @@ -31,6 +35,9 @@ if is_package(dirpath) and filenames: pkg_name = dirpath[len(basepath) + len(os.sep):].replace('/', '.') + if packages and pkg_name not in packages: + continue + filenames = filter( lambda x: x.startswith('test_') and x.endswith(py_ext), filenames) @@ -48,7 +55,7 @@ if gui: raise -def get_tests(text=True, gui=True): +def get_tests(text=True, gui=True, packages=None): """Yield all the tests in the modules found by get_tests_modules. If nogui is True, only tests that do not require a GUI will be @@ -58,7 +65,7 @@ attrs.append('tests_nogui') if gui: attrs.append('tests_gui') - for module in get_tests_modules(gui=gui): + for module in get_tests_modules(gui=gui, packages=packages): for attr in attrs: for test in getattr(module, attr, ()): yield test Modified: python/branches/py3k-issue1717/Lib/tkinter/test/test_ttk/test_widgets.py ============================================================================== --- python/branches/py3k-issue1717/Lib/tkinter/test/test_ttk/test_widgets.py (original) +++ python/branches/py3k-issue1717/Lib/tkinter/test/test_ttk/test_widgets.py Fri Jan 30 17:52:02 2009 @@ -708,10 +708,13 @@ class TreeviewTest(unittest.TestCase): def setUp(self): - self.tv = ttk.Treeview() + self.root = support.get_tk_root() + self.tv = ttk.Treeview(self.root) def tearDown(self): self.tv.destroy() + self.root.update_idletasks() + self.root.destroy() def test_bbox(self): Modified: python/branches/py3k-issue1717/Lib/trace.py ============================================================================== --- python/branches/py3k-issue1717/Lib/trace.py (original) +++ python/branches/py3k-issue1717/Lib/trace.py Fri Jan 30 17:52:02 2009 @@ -367,7 +367,7 @@ """Return dict where keys are lines in the line number table.""" linenos = {} - line_increments = [ord(c) for c in code.co_lnotab[1::2]] + line_increments = code.co_lnotab[1::2] table_length = len(line_increments) docstring = False Modified: python/branches/py3k-issue1717/Misc/NEWS ============================================================================== --- python/branches/py3k-issue1717/Misc/NEWS (original) +++ python/branches/py3k-issue1717/Misc/NEWS Fri Jan 30 17:52:02 2009 @@ -17,6 +17,14 @@ the type definition cmpfunc. The tp_compare slot is reserved for future usage. +- Issue #4707: round(x, n) now returns an integer if x is an integer. + Previously it returned a float. + +- Issue #4753: By enabling a configure option named '--with-computed-gotos' + on compilers that support it (notably: gcc, SunPro, icc), the bytecode + evaluation loop is compiled with a new dispatch mechanism which gives + speedups of up to 20%, depending on the system, on various benchmarks. + - Issue #4874: Most builtin decoders now reject unicode input. - Issue #4842: Don't allow trailing 'L' when constructing an integer @@ -144,6 +152,13 @@ Library ------- +- Fix a bug in the trace module where a bytes object from co_lnotab had its + items being passed through ord(). + +- Issue #2047: shutil.move() could believe that its destination path was + inside its source path if it began with the same letters (e.g. "src" vs. + "src.new"). + - Added the ttk module. See issue #2983: Ttk support for Tkinter. - Removed isSequenceType(), isMappingType, and isNumberType() from the @@ -423,6 +438,12 @@ buffer. +Tests +----- + +- Issue #5083: New 'gui' resource for regrtest. + + Docs ---- Modified: python/branches/py3k-issue1717/Modules/_tkinter.c ============================================================================== --- python/branches/py3k-issue1717/Modules/_tkinter.c (original) +++ python/branches/py3k-issue1717/Modules/_tkinter.c Fri Jan 30 17:52:02 2009 @@ -2794,7 +2794,9 @@ return NULL; context.maxsize = PySequence_Size(item); - if (context.maxsize <= 0) + if (context.maxsize < 0) + return NULL; + if (context.maxsize == 0) return PyTuple_New(0); context.tuple = PyTuple_New(context.maxsize); Modified: python/branches/py3k-issue1717/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k-issue1717/Modules/itertoolsmodule.c (original) +++ python/branches/py3k-issue1717/Modules/itertoolsmodule.c Fri Jan 30 17:52:02 2009 @@ -3400,16 +3400,23 @@ repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ \n\ Iterators terminating on the shortest input sequence:\n\ -zip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\ +chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\ +compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\ +dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ +groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\ filterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\ islice(seq, [start,] stop [, step]) --> elements from\n\ seq[start:stop:step]\n\ starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\ tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\ -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\ takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\ +zip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\ +\n\ +Combinatoric generators:\n\ +product(p, q, ... [repeat=1]) --> cartesian product\n\ +permutations(p[, r])\n\ +combinations(p[, r])\n\ +combinations_with_replacement(p[, r])\n\ "); Modified: python/branches/py3k-issue1717/Objects/longobject.c ============================================================================== --- python/branches/py3k-issue1717/Objects/longobject.c (original) +++ python/branches/py3k-issue1717/Objects/longobject.c Fri Jan 30 17:52:02 2009 @@ -3643,32 +3643,140 @@ PyUnicode_GET_SIZE(format_spec)); } - static PyObject * long_round(PyObject *self, PyObject *args) { -#define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */ - int ndigits = UNDEF_NDIGITS; - double x; - PyObject *res; - - if (!PyArg_ParseTuple(args, "|i", &ndigits)) - return NULL; + 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 - if (ndigits == UNDEF_NDIGITS) + */ + if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) + return NULL; + if (o_ndigits == NULL) return long_long(self); - /* If called with two args, defer to float.__round__(). */ - x = PyLong_AsDouble(self); - if (x == -1.0 && PyErr_Occurred()) + ndigits = (PyLongObject *)PyNumber_Index(o_ndigits); + if (ndigits == NULL) return NULL; - self = PyFloat_FromDouble(x); - if (self == NULL) - return NULL; - res = PyObject_CallMethod(self, "__round__", "i", ndigits); + + 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); + Py_DECREF(ndigits); + ndigits = (PyLongObject *)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); - return res; -#undef UNDEF_NDIGITS + self = temp; + if (self == NULL) + goto error; + + /* 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; + } + Py_DECREF(q); + Py_DECREF(r); + Py_DECREF(pow); + Py_DECREF(ndigits); + return self; + + error: + Py_XDECREF(q); + Py_XDECREF(r); + Py_XDECREF(pow); + Py_XDECREF(self); + Py_XDECREF(ndigits); + return NULL; } static PyObject * @@ -3773,8 +3881,8 @@ {"__ceil__", (PyCFunction)long_long, METH_NOARGS, "Ceiling of an Integral returns itself."}, {"__round__", (PyCFunction)long_round, METH_VARARGS, - "Rounding an Integral returns itself.\n" - "Rounding with an ndigits arguments defers to float.__round__."}, + "Rounding an Integral returns itself.\n" + "Rounding with an ndigits argument also returns an integer."}, {"__getnewargs__", (PyCFunction)long_getnewargs, METH_NOARGS}, {"__format__", (PyCFunction)long__format__, METH_VARARGS}, {"__sizeof__", (PyCFunction)long_sizeof, METH_NOARGS, Modified: python/branches/py3k-issue1717/PC/bdist_wininst/install.c ============================================================================== --- python/branches/py3k-issue1717/PC/bdist_wininst/install.c (original) +++ python/branches/py3k-issue1717/PC/bdist_wininst/install.c Fri Jan 30 17:52:02 2009 @@ -114,6 +114,7 @@ FILE *logfile; char modulename[MAX_PATH]; +wchar_t wmodulename[MAX_PATH]; HWND hwndMain; HWND hDialog; @@ -299,6 +300,27 @@ typedef void PyObject; +// Convert a "char *" string to "whcar_t *", or NULL on error. +// Result string must be free'd +wchar_t *widen_string(char *src) +{ + wchar_t *result; + DWORD dest_cch; + int src_len = strlen(src) + 1; // include NULL term in all ops + /* use MultiByteToWideChar() to see how much we need. */ + /* NOTE: this will include the null-term in the length */ + dest_cch = MultiByteToWideChar(CP_ACP, 0, src, src_len, NULL, 0); + // alloc the buffer + result = (wchar_t *)malloc(dest_cch * sizeof(wchar_t)); + if (result==NULL) + return NULL; + /* do the conversion */ + if (0==MultiByteToWideChar(CP_ACP, 0, src, src_len, result, dest_cch)) { + free(result); + return NULL; + } + return result; +} /* * Returns number of files which failed to compile, @@ -307,7 +329,7 @@ static int compile_filelist(HINSTANCE hPython, BOOL optimize_flag) { DECLPROC(hPython, void, Py_Initialize, (void)); - DECLPROC(hPython, void, Py_SetProgramName, (char *)); + DECLPROC(hPython, void, Py_SetProgramName, (wchar_t *)); DECLPROC(hPython, void, Py_Finalize, (void)); DECLPROC(hPython, int, PyRun_SimpleString, (char *)); DECLPROC(hPython, PyObject *, PySys_GetObject, (char *)); @@ -326,7 +348,7 @@ return -1; *Py_OptimizeFlag = optimize_flag ? 1 : 0; - Py_SetProgramName(modulename); + Py_SetProgramName(wmodulename); Py_Initialize(); errors += do_compile_files(PyRun_SimpleString, optimize_flag); @@ -694,10 +716,12 @@ */ static int -run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv) +do_run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv) { + int fh, result, i; + static wchar_t *wargv[256]; DECLPROC(hPython, void, Py_Initialize, (void)); - DECLPROC(hPython, int, PySys_SetArgv, (int, char **)); + DECLPROC(hPython, int, PySys_SetArgv, (int, wchar_t **)); DECLPROC(hPython, int, PyRun_SimpleString, (char *)); DECLPROC(hPython, void, Py_Finalize, (void)); DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...)); @@ -706,9 +730,6 @@ DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...)); DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *)); - int result = 0; - int fh; - if (!Py_Initialize || !PySys_SetArgv || !PyRun_SimpleString || !Py_Finalize) return 1; @@ -730,11 +751,20 @@ } SetDlgItemText(hDialog, IDC_INFO, "Running Script..."); - + Py_Initialize(); prepare_script_environment(hPython); - PySys_SetArgv(argc, argv); + // widen the argv array for py3k. + memset(wargv, 0, sizeof(wargv)); + for (i=0;i<argc;i++) + wargv[i] = argv[i] ? widen_string(argv[i]) : NULL; + PySys_SetArgv(argc, wargv); + // free the strings we just widened. + for (i=0;i<argc;i++) + if (wargv[i]) + free(wargv[i]); + result = 3; { struct _stat statbuf; @@ -751,7 +781,57 @@ Py_Finalize(); close(fh); + return result; +} + +static int +run_installscript(char *pathname, int argc, char **argv, char **pOutput) +{ + HINSTANCE hPython; + int result = 1; + int out_buf_size; + HANDLE redirected, old_stderr, old_stdout; + char *tempname; + + *pOutput = NULL; + tempname = tempnam(NULL, NULL); + // We use a static CRT while the Python version we load uses + // the CRT from one of various possibile DLLs. As a result we + // need to redirect the standard handles using the API rather + // than the CRT. + redirected = CreateFile( + tempname, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, + NULL); + old_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + old_stderr = GetStdHandle(STD_ERROR_HANDLE); + SetStdHandle(STD_OUTPUT_HANDLE, redirected); + SetStdHandle(STD_ERROR_HANDLE, redirected); + + hPython = LoadPythonDll(pythondll); + if (hPython) { + result = do_run_installscript(hPython, pathname, argc, argv); + FreeLibrary(hPython); + } else { + fprintf(stderr, "*** Could not load Python ***"); + } + SetStdHandle(STD_OUTPUT_HANDLE, old_stdout); + SetStdHandle(STD_ERROR_HANDLE, old_stderr); + out_buf_size = min(GetFileSize(redirected, NULL), 4096); + *pOutput = malloc(out_buf_size+1); + if (*pOutput) { + DWORD nread = 0; + SetFilePointer(redirected, 0, 0, FILE_BEGIN); + ReadFile(redirected, *pOutput, out_buf_size, &nread, NULL); + (*pOutput)[nread] = '\0'; + } + CloseHandle(redirected); + DeleteFile(tempname); return result; } @@ -759,7 +839,7 @@ { int rc; DECLPROC(hPython, void, Py_Initialize, (void)); - DECLPROC(hPython, void, Py_SetProgramName, (char *)); + DECLPROC(hPython, void, Py_SetProgramName, (wchar_t *)); DECLPROC(hPython, void, Py_Finalize, (void)); DECLPROC(hPython, int, PyRun_SimpleString, (char *)); DECLPROC(hPython, void, PyErr_Print, (void)); @@ -768,7 +848,7 @@ !PyRun_SimpleString || !PyErr_Print) return -1; - Py_SetProgramName(modulename); + Py_SetProgramName(wmodulename); Py_Initialize(); prepare_script_environment(hPython); rc = PyRun_SimpleString(script); @@ -781,11 +861,21 @@ static int run_simple_script(char *script) { int rc; - char *tempname; HINSTANCE hPython; - tempname = tempnam(NULL, NULL); - freopen(tempname, "a", stderr); - freopen(tempname, "a", stdout); + char *tempname = tempnam(NULL, NULL); + // Redirect output using win32 API - see comments above... + HANDLE redirected = CreateFile( + tempname, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, + NULL); + HANDLE old_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + HANDLE old_stderr = GetStdHandle(STD_ERROR_HANDLE); + SetStdHandle(STD_OUTPUT_HANDLE, redirected); + SetStdHandle(STD_ERROR_HANDLE, redirected); hPython = LoadPythonDll(pythondll); if (!hPython) { @@ -796,10 +886,8 @@ } rc = do_run_simple_script(hPython, script); FreeLibrary(hPython); - fflush(stderr); - fclose(stderr); - fflush(stdout); - fclose(stdout); + SetStdHandle(STD_OUTPUT_HANDLE, old_stdout); + SetStdHandle(STD_ERROR_HANDLE, old_stderr); /* We only care about the output when we fail. If the script works OK, then we discard it */ @@ -808,24 +896,24 @@ char *err_buf; const char *prefix = "Running the pre-installation script failed\r\n"; int prefix_len = strlen(prefix); - FILE *fp = fopen(tempname, "rb"); - fseek(fp, 0, SEEK_END); - err_buf_size = ftell(fp); - fseek(fp, 0, SEEK_SET); + err_buf_size = GetFileSize(redirected, NULL); + if (err_buf_size==INVALID_FILE_SIZE) // an error - let's try anyway... + err_buf_size = 4096; err_buf = malloc(prefix_len + err_buf_size + 1); if (err_buf) { - int n; + DWORD n = 0; strcpy(err_buf, prefix); - n = fread(err_buf+prefix_len, 1, err_buf_size, fp); + SetFilePointer(redirected, 0, 0, FILE_BEGIN); + ReadFile(redirected, err_buf+prefix_len, err_buf_size, &n, NULL); err_buf[prefix_len+n] = '\0'; - fclose(fp); set_failure_reason(err_buf); free(err_buf); } else { set_failure_reason("Out of memory!"); } } - remove(tempname); + CloseHandle(redirected); + DeleteFile(tempname); return rc; } @@ -1946,12 +2034,9 @@ if (success && install_script && install_script[0]) { char fname[MAX_PATH]; - char *tempname; - FILE *fp; - char buffer[4096]; - int n; + char *buffer; HCURSOR hCursor; - HINSTANCE hPython; + int result; char *argv[3] = {NULL, "-install", NULL}; @@ -1964,48 +2049,21 @@ if (logfile) fprintf(logfile, "300 Run Script: [%s]%s\n", pythondll, fname); - tempname = tempnam(NULL, NULL); - - if (!freopen(tempname, "a", stderr)) - MessageBox(GetFocus(), "freopen stderr", NULL, MB_OK); - if (!freopen(tempname, "a", stdout)) - MessageBox(GetFocus(), "freopen stdout", NULL, MB_OK); -/* - if (0 != setvbuf(stdout, NULL, _IONBF, 0)) - MessageBox(GetFocus(), "setvbuf stdout", NULL, MB_OK); -*/ hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); argv[0] = fname; - hPython = LoadPythonDll(pythondll); - if (hPython) { - int result; - result = run_installscript(hPython, fname, 2, argv); - if (-1 == result) { - fprintf(stderr, "*** run_installscript: internal error 0x%X ***\n", result); - } - FreeLibrary(hPython); - } else { - fprintf(stderr, "*** Could not load Python ***"); + result = run_installscript(fname, 2, argv, &buffer); + if (0 != result) { + fprintf(stderr, "*** run_installscript: internal error 0x%X ***\n", result); } - fflush(stderr); - fclose(stderr); - fflush(stdout); - fclose(stdout); - - fp = fopen(tempname, "rb"); - n = fread(buffer, 1, sizeof(buffer), fp); - fclose(fp); - remove(tempname); - - buffer[n] = '\0'; - - SetDlgItemText(hwnd, IDC_INFO, buffer); + if (buffer) + SetDlgItemText(hwnd, IDC_INFO, buffer); SetDlgItemText(hwnd, IDC_TITLE, "Postinstall script finished.\n" "Click the Finish button to exit the Setup wizard."); + free(buffer); SetCursor(hCursor); CloseLogfile(); } @@ -2418,42 +2476,17 @@ /* this function may be called more than one time with the same script, only run it one time */ if (strcmp(lastscript, scriptname)) { - HINSTANCE hPython; char *argv[3] = {NULL, "-remove", NULL}; - char buffer[4096]; - FILE *fp; - char *tempname; - int n; + char *buffer = NULL; argv[0] = scriptname; - tempname = tempnam(NULL, NULL); + if (0 != run_installscript(scriptname, 2, argv, &buffer)) + fprintf(stderr, "*** Could not run installation script ***"); - if (!freopen(tempname, "a", stderr)) - MessageBox(GetFocus(), "freopen stderr", NULL, MB_OK); - if (!freopen(tempname, "a", stdout)) - MessageBox(GetFocus(), "freopen stdout", NULL, MB_OK); - - hPython = LoadLibrary(dllname); - if (hPython) { - if (0x80000000 == run_installscript(hPython, scriptname, 2, argv)) - fprintf(stderr, "*** Could not load Python ***"); - FreeLibrary(hPython); - } - - fflush(stderr); - fclose(stderr); - fflush(stdout); - fclose(stdout); - - fp = fopen(tempname, "rb"); - n = fread(buffer, 1, sizeof(buffer), fp); - fclose(fp); - remove(tempname); - - buffer[n] = '\0'; - if (buffer[0]) + if (buffer && buffer[0]) MessageBox(GetFocus(), buffer, "uninstall-script", MB_OK); + free(buffer); strcpy(lastscript, scriptname); } @@ -2617,6 +2650,7 @@ char *basename; GetModuleFileName(NULL, modulename, sizeof(modulename)); + GetModuleFileNameW(NULL, wmodulename, sizeof(wmodulename)/sizeof(wmodulename[0])); /* Map the executable file to memory */ arc_data = MapExistingFile(modulename, &arc_size); Modified: python/branches/py3k-issue1717/PCbuild/bdist_wininst.vcproj ============================================================================== --- python/branches/py3k-issue1717/PCbuild/bdist_wininst.vcproj (original) +++ python/branches/py3k-issue1717/PCbuild/bdist_wininst.vcproj Fri Jan 30 17:52:02 2009 @@ -55,7 +55,7 @@ AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib" PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" StringPooling="true" - RuntimeLibrary="2" + RuntimeLibrary="0" EnableFunctionLevelLinking="true" WarningLevel="3" SuppressStartupBanner="true" @@ -145,7 +145,7 @@ AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib" PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" StringPooling="true" - RuntimeLibrary="2" + RuntimeLibrary="0" EnableFunctionLevelLinking="true" WarningLevel="3" SuppressStartupBanner="true" Modified: python/branches/py3k-issue1717/Python/bltinmodule.c ============================================================================== --- python/branches/py3k-issue1717/Python/bltinmodule.c (original) +++ python/branches/py3k-issue1717/Python/bltinmodule.c Fri Jan 30 17:52:02 2009 @@ -1698,15 +1698,14 @@ static PyObject * builtin_round(PyObject *self, PyObject *args, PyObject *kwds) { -#define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */ static PyObject *round_str = NULL; - int ndigits = UNDEF_NDIGITS; + PyObject *ndigits = NULL; static char *kwlist[] = {"number", "ndigits", 0}; PyObject *number, *round; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:round", - kwlist, &number, &ndigits)) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:round", + kwlist, &number, &ndigits)) + return NULL; if (Py_TYPE(number)->tp_dict == NULL) { if (PyType_Ready(Py_TYPE(number)) < 0) @@ -1727,15 +1726,14 @@ return NULL; } - if (ndigits == UNDEF_NDIGITS) - return PyObject_CallFunction(round, "O", number); + if (ndigits == NULL) + return PyObject_CallFunction(round, "O", number); else - return PyObject_CallFunction(round, "Oi", number, ndigits); -#undef UNDEF_NDIGITS + return PyObject_CallFunction(round, "OO", number, ndigits); } PyDoc_STRVAR(round_doc, -"round(number[, ndigits]) -> floating point number\n\ +"round(number[, ndigits]) -> number\n\ \n\ Round a number to a given precision in decimal digits (default 0 digits).\n\ This returns an int when called with one argument, otherwise the\n\ Modified: python/branches/py3k-issue1717/Python/import.c ============================================================================== --- python/branches/py3k-issue1717/Python/import.c (original) +++ python/branches/py3k-issue1717/Python/import.c Fri Jan 30 17:52:02 2009 @@ -2894,12 +2894,14 @@ imp_find_module(PyObject *self, PyObject *args) { char *name; - PyObject *path = NULL; + PyObject *ret, *path = NULL; if (!PyArg_ParseTuple(args, "es|O:find_module", Py_FileSystemDefaultEncoding, &name, &path)) return NULL; - return call_find_module(name, path); + ret = call_find_module(name, path); + PyMem_Free(name); + return ret; } static PyObject *
participants (1)
-
mark.dickinson