From nnorwitz at gmail.com Fri Oct 1 00:48:56 2010 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 30 Sep 2010 18:48:56 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20100930224856.GA5689@kbk-i386-bb.dyndns.org> More important issues: ---------------------- test_bz2 leaked [-84, 0, 0] references, sum=-84 Less important issues: ---------------------- test_threadsignals leaked [0, 0, -8] references, sum=-8 From python-checkins at python.org Fri Oct 1 04:08:02 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 1 Oct 2010 04:08:02 +0200 (CEST) Subject: [Python-checkins] r85130 - python/branches/py3k/Lib/email/message.py Message-ID: <20101001020802.5ADF9EEA10@mail.python.org> Author: r.david.murray Date: Fri Oct 1 04:08:02 2010 New Revision: 85130 Log: Fix a couple spelling errors in comments and delete redundant __len__ def. Modified: python/branches/py3k/Lib/email/message.py Modified: python/branches/py3k/Lib/email/message.py ============================================================================== --- python/branches/py3k/Lib/email/message.py (original) +++ python/branches/py3k/Lib/email/message.py Fri Oct 1 04:08:02 2010 @@ -98,7 +98,7 @@ objects, otherwise it is a string. Message objects implement part of the `mapping' interface, which assumes - there is exactly one occurrance of the header per message. Some headers + there is exactly one occurrence of the header per message. Some headers do in fact appear multiple times (e.g. Received) and for those headers, you must use the explicit API to set or get all the headers. Not all of the mapping methods are implemented. @@ -290,7 +290,7 @@ Return None if the header is missing instead of raising an exception. Note that if the header appeared multiple times, exactly which - occurrance gets returned is undefined. Use get_all() to get all + occurrence gets returned is undefined. Use get_all() to get all the values matching a header field name. """ return self.get(name) @@ -322,9 +322,6 @@ for field, value in self._headers: yield field - def __len__(self): - return len(self._headers) - def keys(self): """Return a list of all the message's header field names. From solipsis at pitrou.net Fri Oct 1 04:50:31 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 01 Oct 2010 04:50:31 +0200 Subject: [Python-checkins] Daily py3k reference leaks (r85125): sum=0 Message-ID: py3k results for svn r85125 (hg cset 0aecf0d22e42) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflognYd9A3', '-x'] From python-checkins at python.org Fri Oct 1 07:38:10 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 1 Oct 2010 07:38:10 +0200 (CEST) Subject: [Python-checkins] r85132 - python/branches/py3k/Doc/c-api/buffer.rst Message-ID: <20101001053810.F3C7FDB83@mail.python.org> Author: georg.brandl Date: Fri Oct 1 07:38:10 2010 New Revision: 85132 Log: Fix weird markup that caused latex to fail. 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 Fri Oct 1 07:38:10 2010 @@ -190,98 +190,96 @@ values. On error, -1 is returned and an exception is raised; the *view* is left in an undefined state. - The following table gives possible values to the *flags* arguments. + The following are the possible values to the *flags* arguments. - +------------------------------+---------------------------------------------------+ - | Flag | Description | - +==============================+===================================================+ - | .. cmacro:: PyBUF_SIMPLE | This is the default flag. The returned buffer | - | | exposes a read-only memory area. The format of | - | | data is assumed to be raw unsigned bytes, without | - | | any particular structure. This is a "stand-alone"| - | | flag constant. It | - | | never needs to be '|'d to the others. The exporter| - | | will raise an error if it cannot provide such a | - | | contiguous buffer of bytes. | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_WRITABLE | Like :cmacro:`PyBUF_SIMPLE`, but the returned | - | | buffer is writable. If the exporter doesn't | - | | support | - | | writable buffers, an error is raised. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_STRIDES | This implies :cmacro:`PyBUF_ND`. The returned | - | | buffer must provide strides information (i.e. the | - | | strides cannot be NULL). This would be used when | - | | the consumer can handle strided, discontiguous | - | | arrays. Handling strides automatically assumes | - | | you can handle shape. The exporter can raise an | - | | error if a strided representation of the data is | - | | not possible (i.e. without the suboffsets). | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_ND | The returned buffer must provide shape | - | | information. The memory will be assumed C-style | - | | contiguous (last dimension varies the | - | | fastest). The exporter may raise an error if it | - | | cannot provide this kind of contiguous buffer. If | - | | this is not given then shape will be *NULL*. | - | | | - +------------------------------+---------------------------------------------------+ - |.. cmacro:: PyBUF_C_CONTIGUOUS| These flags indicate that the contiguity returned | - | PyBUF_F_CONTIGUOUS| buffer must be respectively, C-contiguous (last | - | PyBUF_ANY_CONTIGUOUS| dimension varies the fastest), Fortran contiguous | - | | (first dimension varies the fastest) or either | - | | one. All of these flags imply | - | | :cmacro:`PyBUF_STRIDES` and guarantee that the | - | | strides buffer info structure will be filled in | - | | correctly. | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_INDIRECT | This flag indicates the returned buffer must have | - | | suboffsets information (which can be NULL if no | - | | suboffsets are needed). This can be used when | - | | the consumer can handle indirect array | - | | referencing implied by these suboffsets. This | - | | implies :cmacro:`PyBUF_STRIDES`. | - | | | - | | | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_FORMAT | The returned buffer must have true format | - | | information if this flag is provided. This would | - | | be used when the consumer is going to be checking | - | | for what 'kind' of data is actually stored. An | - | | exporter should always be able to provide this | - | | information if requested. If format is not | - | | explicitly requested then the format must be | - | | returned as *NULL* (which means ``'B'``, or | - | | unsigned bytes) | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_STRIDED | This is equivalent to ``(PyBUF_STRIDES | | - | | PyBUF_WRITABLE)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_STRIDED_RO | This is equivalent to ``(PyBUF_STRIDES)``. | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_RECORDS | This is equivalent to ``(PyBUF_STRIDES | | - | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_RECORDS_RO | This is equivalent to ``(PyBUF_STRIDES | | - | | PyBUF_FORMAT)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_FULL | This is equivalent to ``(PyBUF_INDIRECT | | - | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_FULL_RO | This is equivalent to ``(PyBUF_INDIRECT | | - | | PyBUF_FORMAT)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_CONTIG | This is equivalent to ``(PyBUF_ND | | - | | PyBUF_WRITABLE)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_CONTIG_RO | This is equivalent to ``(PyBUF_ND)``. | - | | | - +------------------------------+---------------------------------------------------+ + .. cmacro:: PyBUF_SIMPLE + + This is the default flag. The returned buffer exposes a read-only + memory area. The format of data is assumed to be raw unsigned bytes, + without any particular structure. This is a "stand-alone" flag + constant. It never needs to be '|'d to the others. The exporter will + raise an error if it cannot provide such a contiguous buffer of bytes. + + .. cmacro:: PyBUF_WRITABLE + + Like :cmacro:`PyBUF_SIMPLE`, but the returned buffer is writable. If + the exporter doesn't support writable buffers, an error is raised. + + .. cmacro:: PyBUF_STRIDES + + This implies :cmacro:`PyBUF_ND`. The returned buffer must provide + strides information (i.e. the strides cannot be NULL). This would be + used when the consumer can handle strided, discontiguous arrays. + Handling strides automatically assumes you can handle shape. The + exporter can raise an error if a strided representation of the data is + not possible (i.e. without the suboffsets). + + .. cmacro:: PyBUF_ND + + The returned buffer must provide shape information. The memory will be + assumed C-style contiguous (last dimension varies the fastest). The + exporter may raise an error if it cannot provide this kind of + contiguous buffer. If this is not given then shape will be *NULL*. + + .. cmacro:: PyBUF_C_CONTIGUOUS + PyBUF_F_CONTIGUOUS + PyBUF_ANY_CONTIGUOUS + + These flags indicate that the contiguity returned buffer must be + respectively, C-contiguous (last dimension varies the fastest), Fortran + contiguous (first dimension varies the fastest) or either one. All of + these flags imply :cmacro:`PyBUF_STRIDES` and guarantee that the + strides buffer info structure will be filled in correctly. + + .. cmacro:: PyBUF_INDIRECT + + This flag indicates the returned buffer must have suboffsets + information (which can be NULL if no suboffsets are needed). This can + be used when the consumer can handle indirect array referencing implied + by these suboffsets. This implies :cmacro:`PyBUF_STRIDES`. + + .. cmacro:: PyBUF_FORMAT + + The returned buffer must have true format information if this flag is + provided. This would be used when the consumer is going to be checking + for what 'kind' of data is actually stored. An exporter should always + be able to provide this information if requested. If format is not + explicitly requested then the format must be returned as *NULL* (which + means ``'B'``, or unsigned bytes). + + .. cmacro:: PyBUF_STRIDED + + This is equivalent to ``(PyBUF_STRIDES | PyBUF_WRITABLE)``. + + .. cmacro:: PyBUF_STRIDED_RO + + This is equivalent to ``(PyBUF_STRIDES)``. + + .. cmacro:: PyBUF_RECORDS + + This is equivalent to ``(PyBUF_STRIDES | PyBUF_FORMAT | + PyBUF_WRITABLE)``. + + .. cmacro:: PyBUF_RECORDS_RO + + This is equivalent to ``(PyBUF_STRIDES | PyBUF_FORMAT)``. + + .. cmacro:: PyBUF_FULL + + This is equivalent to ``(PyBUF_INDIRECT | PyBUF_FORMAT | + PyBUF_WRITABLE)``. + + .. cmacro:: PyBUF_FULL_RO + + This is equivalent to ``(PyBUF_INDIRECT | PyBUF_FORMAT)``. + + .. cmacro:: PyBUF_CONTIG + + This is equivalent to ``(PyBUF_ND | PyBUF_WRITABLE)``. + + .. cmacro:: PyBUF_CONTIG_RO + + This is equivalent to ``(PyBUF_ND)``. .. cfunction:: void PyBuffer_Release(Py_buffer *view) From python-checkins at python.org Fri Oct 1 07:41:48 2010 From: python-checkins at python.org (georg.brandl) Date: Fri, 1 Oct 2010 07:41:48 +0200 (CEST) Subject: [Python-checkins] r85133 - in python/branches/release31-maint: Doc/c-api/buffer.rst Message-ID: <20101001054148.3545FEE9D1@mail.python.org> Author: georg.brandl Date: Fri Oct 1 07:41:48 2010 New Revision: 85133 Log: Merged revisions 85132 via svnmerge from svn+ssh://svn.python.org/python/branches/py3k ........ r85132 | georg.brandl | 2010-10-01 07:38:10 +0200 (Fr, 01 Okt 2010) | 1 line Fix weird markup that caused latex to fail. ........ 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 Fri Oct 1 07:41:48 2010 @@ -190,98 +190,96 @@ values. On error, -1 is returned and an exception is raised; the *view* is left in an undefined state. - The following table gives possible values to the *flags* arguments. + The following are the possible values to the *flags* arguments. - +------------------------------+---------------------------------------------------+ - | Flag | Description | - +==============================+===================================================+ - | .. cmacro:: PyBUF_SIMPLE | This is the default flag. The returned buffer | - | | exposes a read-only memory area. The format of | - | | data is assumed to be raw unsigned bytes, without | - | | any particular structure. This is a "stand-alone"| - | | flag constant. It | - | | never needs to be '|'d to the others. The exporter| - | | will raise an error if it cannot provide such a | - | | contiguous buffer of bytes. | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_WRITABLE | Like :cmacro:`PyBUF_SIMPLE`, but the returned | - | | buffer is writable. If the exporter doesn't | - | | support | - | | writable buffers, an error is raised. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_STRIDES | This implies :cmacro:`PyBUF_ND`. The returned | - | | buffer must provide strides information (i.e. the | - | | strides cannot be NULL). This would be used when | - | | the consumer can handle strided, discontiguous | - | | arrays. Handling strides automatically assumes | - | | you can handle shape. The exporter can raise an | - | | error if a strided representation of the data is | - | | not possible (i.e. without the suboffsets). | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_ND | The returned buffer must provide shape | - | | information. The memory will be assumed C-style | - | | contiguous (last dimension varies the | - | | fastest). The exporter may raise an error if it | - | | cannot provide this kind of contiguous buffer. If | - | | this is not given then shape will be *NULL*. | - | | | - +------------------------------+---------------------------------------------------+ - |.. cmacro:: PyBUF_C_CONTIGUOUS| These flags indicate that the contiguity returned | - | PyBUF_F_CONTIGUOUS| buffer must be respectively, C-contiguous (last | - | PyBUF_ANY_CONTIGUOUS| dimension varies the fastest), Fortran contiguous | - | | (first dimension varies the fastest) or either | - | | one. All of these flags imply | - | | :cmacro:`PyBUF_STRIDES` and guarantee that the | - | | strides buffer info structure will be filled in | - | | correctly. | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_INDIRECT | This flag indicates the returned buffer must have | - | | suboffsets information (which can be NULL if no | - | | suboffsets are needed). This can be used when | - | | the consumer can handle indirect array | - | | referencing implied by these suboffsets. This | - | | implies :cmacro:`PyBUF_STRIDES`. | - | | | - | | | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_FORMAT | The returned buffer must have true format | - | | information if this flag is provided. This would | - | | be used when the consumer is going to be checking | - | | for what 'kind' of data is actually stored. An | - | | exporter should always be able to provide this | - | | information if requested. If format is not | - | | explicitly requested then the format must be | - | | returned as *NULL* (which means ``'B'``, or | - | | unsigned bytes) | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_STRIDED | This is equivalent to ``(PyBUF_STRIDES | | - | | PyBUF_WRITABLE)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_STRIDED_RO | This is equivalent to ``(PyBUF_STRIDES)``. | - | | | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_RECORDS | This is equivalent to ``(PyBUF_STRIDES | | - | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_RECORDS_RO | This is equivalent to ``(PyBUF_STRIDES | | - | | PyBUF_FORMAT)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_FULL | This is equivalent to ``(PyBUF_INDIRECT | | - | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_FULL_RO | This is equivalent to ``(PyBUF_INDIRECT | | - | | PyBUF_FORMAT)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_CONTIG | This is equivalent to ``(PyBUF_ND | | - | | PyBUF_WRITABLE)``. | - +------------------------------+---------------------------------------------------+ - | .. cmacro:: PyBUF_CONTIG_RO | This is equivalent to ``(PyBUF_ND)``. | - | | | - +------------------------------+---------------------------------------------------+ + .. cmacro:: PyBUF_SIMPLE + + This is the default flag. The returned buffer exposes a read-only + memory area. The format of data is assumed to be raw unsigned bytes, + without any particular structure. This is a "stand-alone" flag + constant. It never needs to be '|'d to the others. The exporter will + raise an error if it cannot provide such a contiguous buffer of bytes. + + .. cmacro:: PyBUF_WRITABLE + + Like :cmacro:`PyBUF_SIMPLE`, but the returned buffer is writable. If + the exporter doesn't support writable buffers, an error is raised. + + .. cmacro:: PyBUF_STRIDES + + This implies :cmacro:`PyBUF_ND`. The returned buffer must provide + strides information (i.e. the strides cannot be NULL). This would be + used when the consumer can handle strided, discontiguous arrays. + Handling strides automatically assumes you can handle shape. The + exporter can raise an error if a strided representation of the data is + not possible (i.e. without the suboffsets). + + .. cmacro:: PyBUF_ND + + The returned buffer must provide shape information. The memory will be + assumed C-style contiguous (last dimension varies the fastest). The + exporter may raise an error if it cannot provide this kind of + contiguous buffer. If this is not given then shape will be *NULL*. + + .. cmacro:: PyBUF_C_CONTIGUOUS + PyBUF_F_CONTIGUOUS + PyBUF_ANY_CONTIGUOUS + + These flags indicate that the contiguity returned buffer must be + respectively, C-contiguous (last dimension varies the fastest), Fortran + contiguous (first dimension varies the fastest) or either one. All of + these flags imply :cmacro:`PyBUF_STRIDES` and guarantee that the + strides buffer info structure will be filled in correctly. + + .. cmacro:: PyBUF_INDIRECT + + This flag indicates the returned buffer must have suboffsets + information (which can be NULL if no suboffsets are needed). This can + be used when the consumer can handle indirect array referencing implied + by these suboffsets. This implies :cmacro:`PyBUF_STRIDES`. + + .. cmacro:: PyBUF_FORMAT + + The returned buffer must have true format information if this flag is + provided. This would be used when the consumer is going to be checking + for what 'kind' of data is actually stored. An exporter should always + be able to provide this information if requested. If format is not + explicitly requested then the format must be returned as *NULL* (which + means ``'B'``, or unsigned bytes). + + .. cmacro:: PyBUF_STRIDED + + This is equivalent to ``(PyBUF_STRIDES | PyBUF_WRITABLE)``. + + .. cmacro:: PyBUF_STRIDED_RO + + This is equivalent to ``(PyBUF_STRIDES)``. + + .. cmacro:: PyBUF_RECORDS + + This is equivalent to ``(PyBUF_STRIDES | PyBUF_FORMAT | + PyBUF_WRITABLE)``. + + .. cmacro:: PyBUF_RECORDS_RO + + This is equivalent to ``(PyBUF_STRIDES | PyBUF_FORMAT)``. + + .. cmacro:: PyBUF_FULL + + This is equivalent to ``(PyBUF_INDIRECT | PyBUF_FORMAT | + PyBUF_WRITABLE)``. + + .. cmacro:: PyBUF_FULL_RO + + This is equivalent to ``(PyBUF_INDIRECT | PyBUF_FORMAT)``. + + .. cmacro:: PyBUF_CONTIG + + This is equivalent to ``(PyBUF_ND | PyBUF_WRITABLE)``. + + .. cmacro:: PyBUF_CONTIG_RO + + This is equivalent to ``(PyBUF_ND)``. .. cfunction:: void PyBuffer_Release(Py_buffer *view) From python-checkins at python.org Fri Oct 1 10:03:11 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 1 Oct 2010 10:03:11 +0200 (CEST) Subject: [Python-checkins] r85134 - tracker/instances/python-dev/lib/identify_patch.py Message-ID: <20101001080311.6304BEE985@mail.python.org> Author: martin.v.loewis Date: Fri Oct 1 10:03:11 2010 New Revision: 85134 Log: Add table to map svn revno to branch Added: tracker/instances/python-dev/lib/identify_patch.py (contents, props changed) Added: tracker/instances/python-dev/lib/identify_patch.py ============================================================================== --- (empty file) +++ tracker/instances/python-dev/lib/identify_patch.py Fri Oct 1 10:03:11 2010 @@ -0,0 +1,68 @@ +import subprocess +from xml.etree import ElementTree + +def find_branch(db, rev): + c = db.cursor + c.execute('select branch from svnbranch where rev=%s', (rev,)) + branch = c.fetchone() + if branch: + return branch[0] + # may need to cache more revisions + return fill_revs(db, lookfor=rev) + +def fill_revs(db, lookfor=None): + result = None + c = db.cursor + c.execute('select max(rev) from svnbranch') + start = c.fetchone()[0] + if not start: + start = 1 + else: + start = start+1 + p = subprocess.Popen(['svn', 'log', '-r%s:HEAD' % start, '--xml', '-v', + 'http://svn.python.org/projects'], + stdout = subprocess.PIPE, + stderr = open('/dev/null', 'w')) + data = p.stdout.read() + if p.wait() != 0: + # svn log failed + return None + xml = ElementTree.fromstring(data) + for entry in xml.findall('logentry'): + rev = int(entry.get('revision')) + paths = [p.text for p in entry.findall('paths/path')] + if not paths: + continue + path = paths[0] + if (not path.startswith('/python') or + # The count may be smaller on the revision that created /python + # or the branch + path.count('/')<3): + continue + branch = path[len('/python'):] + if branch.startswith('/trunk'): + branch = '/trunk' + else: + d1, d2 = branch.split('/', 3)[1:3] + branch = '/'+d1+'/'+d2 + ppath = '/python'+branch + for p in paths: + if not p.startswith(ppath): + # inconsistent commit + break + else: + c.execute('insert into svnbranch(rev, branch) values(%s, %s)', + (rev, branch)) + if lookfor == rev: + result = branch + db.commit() + return branch + +if __name__=='__main__': + # manual setup: + # create table svnbranch(rev integer primary key, branch text); + # then run this once in the instance directory + import roundup.instance + tracker = roundup.instance.open('.') + db = tracker.open('admin') + fill_revs(db) From python-checkins at python.org Fri Oct 1 12:40:50 2010 From: python-checkins at python.org (hirokazu.yamamoto) Date: Fri, 1 Oct 2010 12:40:50 +0200 (CEST) Subject: [Python-checkins] r85135 - python/branches/py3k/PCbuild/readme.txt Message-ID: <20101001104050.08391EE985@mail.python.org> Author: hirokazu.yamamoto Date: Fri Oct 1 12:40:49 2010 New Revision: 85135 Log: Cosmetic fix for PCBuild/readme.txt. Modified: python/branches/py3k/PCbuild/readme.txt Modified: python/branches/py3k/PCbuild/readme.txt ============================================================================== --- python/branches/py3k/PCbuild/readme.txt (original) +++ python/branches/py3k/PCbuild/readme.txt Fri Oct 1 12:40:49 2010 @@ -55,7 +55,7 @@ Visual C++ 6.0 PC/VS7.1/ Visual Studio 2003 (7.1) -PCbuild8/ +PC/VS8.0/ Visual Studio 2005 (8.0) From python-checkins at python.org Fri Oct 1 12:48:47 2010 From: python-checkins at python.org (hirokazu.yamamoto) Date: Fri, 1 Oct 2010 12:48:47 +0200 (CEST) Subject: [Python-checkins] r85136 - python/branches/release27-maint/PCbuild/build_ssl.py Message-ID: <20101001104847.9F2D7EE9D7@mail.python.org> Author: hirokazu.yamamoto Date: Fri Oct 1 12:48:47 2010 New Revision: 85136 Log: Cosmetic fix to use print function. Modified: python/branches/release27-maint/PCbuild/build_ssl.py Modified: python/branches/release27-maint/PCbuild/build_ssl.py ============================================================================== --- python/branches/release27-maint/PCbuild/build_ssl.py (original) +++ python/branches/release27-maint/PCbuild/build_ssl.py Fri Oct 1 12:48:47 2010 @@ -1,4 +1,4 @@ -from __future__ import with_statement +from __future__ import with_statement, print_function # Script for building the _ssl and _hashlib modules for Windows. # Uses Perl to setup the OpenSSL environment correctly # and build OpenSSL, then invokes a simple nmake session From python-checkins at python.org Fri Oct 1 16:18:49 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 1 Oct 2010 16:18:49 +0200 (CEST) Subject: [Python-checkins] r85137 - in python/branches/py3k: Lib/test/test_time.py Misc/ACKS Misc/NEWS Modules/timemodule.c Message-ID: <20101001141849.C1B30FD35@mail.python.org> Author: alexander.belopolsky Date: Fri Oct 1 16:18:49 2010 New Revision: 85137 Log: Issue #6608: time.asctime is now checking struct tm fields its input before passing it to the system asctime. Patch by MunSic Jeong. Modified: python/branches/py3k/Lib/test/test_time.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/timemodule.c Modified: python/branches/py3k/Lib/test/test_time.py ============================================================================== --- python/branches/py3k/Lib/test/test_time.py (original) +++ python/branches/py3k/Lib/test/test_time.py Fri Oct 1 16:18:49 2010 @@ -37,57 +37,60 @@ except ValueError: self.fail('conversion specifier: %r failed.' % format) - def test_strftime_bounds_checking(self): + def _bounds_checking(self, func=time.strftime): # Make sure that strftime() checks the bounds of the various parts #of the time tuple (0 is valid for *all* values). # Check year [1900, max(int)] - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1899, 1, 1, 0, 0, 0, 0, 1, -1)) if time.accept2dyear: - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (-1, 1, 1, 0, 0, 0, 0, 1, -1)) - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (100, 1, 1, 0, 0, 0, 0, 1, -1)) # Check month [1, 12] + zero support - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, -1, 1, 0, 0, 0, 0, 1, -1)) - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 13, 1, 0, 0, 0, 0, 1, -1)) # Check day of month [1, 31] + zero support - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, -1, 0, 0, 0, 0, 1, -1)) - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 32, 0, 0, 0, 0, 1, -1)) # Check hour [0, 23] - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 1, -1, 0, 0, 0, 1, -1)) - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 1, 24, 0, 0, 0, 1, -1)) # Check minute [0, 59] - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 1, 0, -1, 0, 0, 1, -1)) - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 1, 0, 60, 0, 0, 1, -1)) # Check second [0, 61] - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 1, 0, 0, -1, 0, 1, -1)) # C99 only requires allowing for one leap second, but Python's docs say # allow two leap seconds (0..61) - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 1, 0, 0, 62, 0, 1, -1)) # No check for upper-bound day of week; # value forced into range by a ``% 7`` calculation. # Start check at -2 since gettmarg() increments value before taking # modulo. - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 1, 0, 0, 0, -2, 1, -1)) # Check day of the year [1, 366] + zero support - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 1, 0, 0, 0, 0, -1, -1)) - self.assertRaises(ValueError, time.strftime, '', + self.assertRaises(ValueError, func, (1900, 1, 1, 0, 0, 0, 0, 367, -1)) + def test_strftime_bounding_check(self): + self._bounds_checking(lambda tup: time.strftime('', tup)) + def test_default_values_for_zero(self): # Make sure that using all zeros uses the proper default values. # No test for daylight savings since strftime() does not change output @@ -120,6 +123,9 @@ time.asctime(time.gmtime(self.t)) self.assertRaises(TypeError, time.asctime, 0) + def test_asctime_bounding_check(self): + self._bounds_checking(time.asctime) + def test_tzset(self): if not hasattr(time, "tzset"): return # Can't test this; don't want the test suite to fail Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Fri Oct 1 16:18:49 2010 @@ -405,7 +405,7 @@ Bill Janssen Drew Jenkins Flemming Kj?r Jensen -Jiba +MunSic Jeong Orjan Johansen Fredrik Johansson Gregory K. Johnson @@ -462,6 +462,7 @@ Andrew Kuchling Vladimir Kushnir Cameron Laird +Jean-Baptiste "Jiba" Lamy Torsten Landschoff ?ukasz Langa Tino Lange Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Oct 1 16:18:49 2010 @@ -410,6 +410,9 @@ Extensions ---------- +- Issue #6608: time.asctime is now checking struct tm fields its input + before passing it to the system asctime. Patch by MunSic Jeong. + - Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file descriptor is provided. Patch by Pascal Chambon. Modified: python/branches/py3k/Modules/timemodule.c ============================================================================== --- python/branches/py3k/Modules/timemodule.c (original) +++ python/branches/py3k/Modules/timemodule.c Fri Oct 1 16:18:49 2010 @@ -315,6 +315,9 @@ Convert seconds since the Epoch to a time tuple expressing local time.\n\ When 'seconds' is not passed in, convert the current time instead."); +/* Convert 9-item tuple to tm structure. Return 1 on success, set + * an exception and return 0 on error. + */ static int gettmarg(PyObject *args, struct tm *p) { @@ -377,6 +380,76 @@ return 1; } +/* Check values of the struct tm fields before it is passed to strftime() and + * asctime(). Return 1 if all values are valid, otherwise set an exception + * and returns 0. + */ +static int +checktm(struct tm* buf) +{ + /* Checks added to make sure strftime() and asctime() does not crash Python by + indexing blindly into some array for a textual representation + by some bad index (fixes bug #897625 and #6608). + + Also support values of zero from Python code for arguments in which + that is out of range by forcing that value to the lowest value that + is valid (fixed bug #1520914). + + Valid ranges based on what is allowed in struct tm: + + - tm_year: [0, max(int)] (1) + - tm_mon: [0, 11] (2) + - tm_mday: [1, 31] + - tm_hour: [0, 23] + - tm_min: [0, 59] + - tm_sec: [0, 60] + - tm_wday: [0, 6] (1) + - tm_yday: [0, 365] (2) + - tm_isdst: [-max(int), max(int)] + + (1) gettmarg() handles bounds-checking. + (2) Python's acceptable range is one greater than the range in C, + thus need to check against automatic decrement by gettmarg(). + */ + if (buf->tm_mon == -1) + buf->tm_mon = 0; + else if (buf->tm_mon < 0 || buf->tm_mon > 11) { + PyErr_SetString(PyExc_ValueError, "month out of range"); + return 0; + } + if (buf->tm_mday == 0) + buf->tm_mday = 1; + else if (buf->tm_mday < 0 || buf->tm_mday > 31) { + PyErr_SetString(PyExc_ValueError, "day of month out of range"); + return 0; + } + if (buf->tm_hour < 0 || buf->tm_hour > 23) { + PyErr_SetString(PyExc_ValueError, "hour out of range"); + return 0; + } + if (buf->tm_min < 0 || buf->tm_min > 59) { + PyErr_SetString(PyExc_ValueError, "minute out of range"); + return 0; + } + if (buf->tm_sec < 0 || buf->tm_sec > 61) { + PyErr_SetString(PyExc_ValueError, "seconds out of range"); + return 0; + } + /* tm_wday does not need checking of its upper-bound since taking + ``% 7`` in gettmarg() automatically restricts the range. */ + if (buf->tm_wday < 0) { + PyErr_SetString(PyExc_ValueError, "day of week out of range"); + return 0; + } + if (buf->tm_yday == -1) + buf->tm_yday = 0; + else if (buf->tm_yday < 0 || buf->tm_yday > 365) { + PyErr_SetString(PyExc_ValueError, "day of year out of range"); + return 0; + } + return 1; +} + #ifdef HAVE_STRFTIME #ifdef HAVE_WCSFTIME #define time_char wchar_t @@ -415,69 +488,10 @@ if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); - } else if (!gettmarg(tup, &buf)) - return NULL; - - /* Checks added to make sure strftime() does not crash Python by - indexing blindly into some array for a textual representation - by some bad index (fixes bug #897625). - - Also support values of zero from Python code for arguments in which - that is out of range by forcing that value to the lowest value that - is valid (fixed bug #1520914). - - Valid ranges based on what is allowed in struct tm: - - - tm_year: [0, max(int)] (1) - - tm_mon: [0, 11] (2) - - tm_mday: [1, 31] - - tm_hour: [0, 23] - - tm_min: [0, 59] - - tm_sec: [0, 60] - - tm_wday: [0, 6] (1) - - tm_yday: [0, 365] (2) - - tm_isdst: [-max(int), max(int)] - - (1) gettmarg() handles bounds-checking. - (2) Python's acceptable range is one greater than the range in C, - thus need to check against automatic decrement by gettmarg(). - */ - if (buf.tm_mon == -1) - buf.tm_mon = 0; - else if (buf.tm_mon < 0 || buf.tm_mon > 11) { - PyErr_SetString(PyExc_ValueError, "month out of range"); - return NULL; - } - if (buf.tm_mday == 0) - buf.tm_mday = 1; - else if (buf.tm_mday < 0 || buf.tm_mday > 31) { - PyErr_SetString(PyExc_ValueError, "day of month out of range"); - return NULL; - } - if (buf.tm_hour < 0 || buf.tm_hour > 23) { - PyErr_SetString(PyExc_ValueError, "hour out of range"); - return NULL; - } - if (buf.tm_min < 0 || buf.tm_min > 59) { - PyErr_SetString(PyExc_ValueError, "minute out of range"); - return NULL; } - if (buf.tm_sec < 0 || buf.tm_sec > 61) { - PyErr_SetString(PyExc_ValueError, "seconds out of range"); + else if (!gettmarg(tup, &buf) || !checktm(&buf)) return NULL; - } - /* tm_wday does not need checking of its upper-bound since taking - ``% 7`` in gettmarg() automatically restricts the range. */ - if (buf.tm_wday < 0) { - PyErr_SetString(PyExc_ValueError, "day of week out of range"); - return NULL; - } - if (buf.tm_yday == -1) - buf.tm_yday = 0; - else if (buf.tm_yday < 0 || buf.tm_yday > 365) { - PyErr_SetString(PyExc_ValueError, "day of year out of range"); - return NULL; - } + /* Normalize tm_isdst just in case someone foolishly implements %Z based on the assumption that tm_isdst falls within the range of [-1, 1] */ @@ -603,7 +617,7 @@ if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); - } else if (!gettmarg(tup, &buf)) + } else if (!gettmarg(tup, &buf) || !checktm(&buf)) return NULL; p = asctime(&buf); if (p[24] == '\n') From python-checkins at python.org Fri Oct 1 16:26:35 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 1 Oct 2010 16:26:35 +0200 (CEST) Subject: [Python-checkins] r85138 - python/branches/release27-maint Message-ID: <20101001142635.97393EE988@mail.python.org> Author: alexander.belopolsky Date: Fri Oct 1 16:26:35 2010 New Revision: 85138 Log: Blocked revisions 85137 via svnmerge ........ r85137 | alexander.belopolsky | 2010-10-01 10:18:49 -0400 (Fri, 01 Oct 2010) | 3 lines Issue #6608: time.asctime is now checking struct tm fields its input before passing it to the system asctime. Patch by MunSic Jeong. ........ Modified: python/branches/release27-maint/ (props changed) From python-checkins at python.org Fri Oct 1 16:32:26 2010 From: python-checkins at python.org (alexander.belopolsky) Date: Fri, 1 Oct 2010 16:32:26 +0200 (CEST) Subject: [Python-checkins] r85139 - python/branches/release31-maint Message-ID: <20101001143226.0A404EE9B8@mail.python.org> Author: alexander.belopolsky Date: Fri Oct 1 16:32:25 2010 New Revision: 85139 Log: Blocked revisions 85137 via svnmerge ........ r85137 | alexander.belopolsky | 2010-10-01 10:18:49 -0400 (Fri, 01 Oct 2010) | 3 lines Issue #6608: time.asctime is now checking struct tm fields its input before passing it to the system asctime. Patch by MunSic Jeong. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Fri Oct 1 16:49:25 2010 From: python-checkins at python.org (brian.curtin) Date: Fri, 1 Oct 2010 16:49:25 +0200 (CEST) Subject: [Python-checkins] r85140 - in python/branches/py3k: Lib/test/test_signal.py Misc/NEWS Modules/signalmodule.c Message-ID: <20101001144925.30A2BEEA12@mail.python.org> Author: brian.curtin Date: Fri Oct 1 16:49:24 2010 New Revision: 85140 Log: Fix #10003. Add SIGBREAK to the set of valid signals on Windows. This fixes a regression noticed by bzr, introduced by issue #9324. Modified: python/branches/py3k/Lib/test/test_signal.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/signalmodule.c 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 Fri Oct 1 16:49:24 2010 @@ -212,13 +212,13 @@ @unittest.skipUnless(sys.platform == "win32", "Windows specific") class WindowsSignalTests(unittest.TestCase): def test_issue9324(self): + # Updated for issue #10003, adding SIGBREAK handler = lambda x, y: None - signal.signal(signal.SIGABRT, handler) - signal.signal(signal.SIGFPE, handler) - signal.signal(signal.SIGILL, handler) - signal.signal(signal.SIGINT, handler) - signal.signal(signal.SIGSEGV, handler) - signal.signal(signal.SIGTERM, handler) + for sig in (signal.SIGABRT, signal.SIGBREAK, signal.SIGFPE, + signal.SIGILL, signal.SIGINT, signal.SIGSEGV, + signal.SIGTERM): + # Set and then reset a handler for signals that work on windows + signal.signal(sig, signal.signal(sig, handler)) with self.assertRaises(ValueError): signal.signal(-1, handler) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Oct 1 16:49:24 2010 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #10003: Allow handling of SIGBREAK on Windows. Fixes a regression + introduced by issue #9324. + - Issue #9979: Create function PyUnicode_AsWideCharString(). - Issue #7397: Mention that importlib.import_module() is probably what someone Modified: python/branches/py3k/Modules/signalmodule.c ============================================================================== --- python/branches/py3k/Modules/signalmodule.c (original) +++ python/branches/py3k/Modules/signalmodule.c Fri Oct 1 16:49:24 2010 @@ -261,6 +261,11 @@ /* Validate that sig_num is one of the allowable signals */ switch (sig_num) { case SIGABRT: break; +#ifdef SIGBREAK + /* Issue #10003: SIGBREAK is not documented as permitted, but works + and corresponds to CTRL_BREAK_EVENT. */ + case SIGBREAK: break; +#endif case SIGFPE: break; case SIGILL: break; case SIGINT: break; From python-checkins at python.org Fri Oct 1 17:09:53 2010 From: python-checkins at python.org (brian.curtin) Date: Fri, 1 Oct 2010 17:09:53 +0200 (CEST) Subject: [Python-checkins] r85141 - in python/branches/release31-maint: Lib/test/test_signal.py Misc/NEWS Modules/signalmodule.c Message-ID: <20101001150953.C25F2EE9AC@mail.python.org> Author: brian.curtin Date: Fri Oct 1 17:09:53 2010 New Revision: 85141 Log: Merged revisions 85140 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85140 | brian.curtin | 2010-10-01 09:49:24 -0500 (Fri, 01 Oct 2010) | 4 lines Fix #10003. Add SIGBREAK to the set of valid signals on Windows. This fixes a regression noticed by bzr, introduced by issue #9324. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_signal.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/signalmodule.c Modified: python/branches/release31-maint/Lib/test/test_signal.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_signal.py (original) +++ python/branches/release31-maint/Lib/test/test_signal.py Fri Oct 1 17:09:53 2010 @@ -212,13 +212,13 @@ @unittest.skipUnless(sys.platform == "win32", "Windows specific") class WindowsSignalTests(unittest.TestCase): def test_issue9324(self): + # Updated for issue #10003, adding SIGBREAK handler = lambda x, y: None - signal.signal(signal.SIGABRT, handler) - signal.signal(signal.SIGFPE, handler) - signal.signal(signal.SIGILL, handler) - signal.signal(signal.SIGINT, handler) - signal.signal(signal.SIGSEGV, handler) - signal.signal(signal.SIGTERM, handler) + for sig in (signal.SIGABRT, signal.SIGBREAK, signal.SIGFPE, + signal.SIGILL, signal.SIGINT, signal.SIGSEGV, + signal.SIGTERM): + # Set and then reset a handler for signals that work on windows + signal.signal(sig, signal.signal(sig, handler)) with self.assertRaises(ValueError): signal.signal(-1, handler) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Oct 1 17:09:53 2010 @@ -523,6 +523,9 @@ Extension Modules ----------------- +- Issue #10003: Allow handling of SIGBREAK on Windows. Fixes a regression + introduced by issue #9324. + - Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file descriptor is provided. Patch by Pascal Chambon. Modified: python/branches/release31-maint/Modules/signalmodule.c ============================================================================== --- python/branches/release31-maint/Modules/signalmodule.c (original) +++ python/branches/release31-maint/Modules/signalmodule.c Fri Oct 1 17:09:53 2010 @@ -258,6 +258,11 @@ /* Validate that sig_num is one of the allowable signals */ switch (sig_num) { case SIGABRT: break; +#ifdef SIGBREAK + /* Issue #10003: SIGBREAK is not documented as permitted, but works + and corresponds to CTRL_BREAK_EVENT. */ + case SIGBREAK: break; +#endif case SIGFPE: break; case SIGILL: break; case SIGINT: break; From python-checkins at python.org Fri Oct 1 17:40:20 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 1 Oct 2010 17:40:20 +0200 (CEST) Subject: [Python-checkins] r85142 - in python/branches/py3k: Lib/email/quoprimime.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20101001154020.EEB68EEA17@mail.python.org> Author: r.david.murray Date: Fri Oct 1 17:40:20 2010 New Revision: 85142 Log: #10004: in Q encoded word ignore '=xx' when xx is not valid hex. Bug report and fix by Thomas Guettler. Modified: python/branches/py3k/Lib/email/quoprimime.py python/branches/py3k/Lib/email/test/test_email.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/email/quoprimime.py ============================================================================== --- python/branches/py3k/Lib/email/quoprimime.py (original) +++ python/branches/py3k/Lib/email/quoprimime.py Fri Oct 1 17:40:20 2010 @@ -294,4 +294,4 @@ the high level email.header class for that functionality. """ s = s.replace('_', ' ') - return re.sub(r'=\w{2}', _unquote_match, s, re.ASCII) + return re.sub(r'=[a-fA-F0-9]{2}', _unquote_match, s, re.ASCII) 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 Oct 1 17:40:20 2010 @@ -1659,6 +1659,12 @@ dh = decode_header(s % q) self.assertEqual(dh, [(a, 'iso-8859-1')]) + def test_rfc2047_Q_invalid_digits(self): + # issue 10004. + s = '=?iso-8659-1?Q?andr=e9=zz?=' + self.assertEqual(decode_header(s), + [(b'andr\xe9=zz', 'iso-8659-1')]) + # Test the MIMEMessage class class TestMIMEMessage(TestEmailBase): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Oct 1 17:40:20 2010 @@ -79,6 +79,9 @@ Library ------- +- Issue #10004: quoprimime no longer generates a traceback when confronted + with invalid characters after '=' in a Q-encoded word. + - Issue #1491: BaseHTTPServer nows send a 100 Continue response before sending a 200 OK for the Expect: 100-continue request header. From python-checkins at python.org Fri Oct 1 17:45:48 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 1 Oct 2010 17:45:48 +0200 (CEST) Subject: [Python-checkins] r85143 - in python/branches/release31-maint: Lib/email/quoprimime.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20101001154548.4C096FE63@mail.python.org> Author: r.david.murray Date: Fri Oct 1 17:45:48 2010 New Revision: 85143 Log: Merged revisions 85142 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85142 | r.david.murray | 2010-10-01 11:40:20 -0400 (Fri, 01 Oct 2010) | 5 lines #10004: in Q encoded word ignore '=xx' when xx is not valid hex. Bug report and fix by Thomas Guettler. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/email/quoprimime.py python/branches/release31-maint/Lib/email/test/test_email.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/email/quoprimime.py ============================================================================== --- python/branches/release31-maint/Lib/email/quoprimime.py (original) +++ python/branches/release31-maint/Lib/email/quoprimime.py Fri Oct 1 17:45:48 2010 @@ -294,4 +294,4 @@ the high level email.Header class for that functionality. """ s = s.replace('_', ' ') - return re.sub(r'=\w{2}', _unquote_match, s, re.ASCII) + return re.sub(r'=[a-fA-F0-9]{2}', _unquote_match, s, re.ASCII) 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 Oct 1 17:45:48 2010 @@ -1655,6 +1655,12 @@ dh = decode_header(s % q) self.assertEqual(dh, [(a, 'iso-8859-1')]) + def test_rfc2047_Q_invalid_digits(self): + # issue 10004. + s = '=?iso-8659-1?Q?andr=e9=zz?=' + self.assertEqual(decode_header(s), + [(b'andr\xe9=zz', 'iso-8659-1')]) + # Test the MIMEMessage class class TestMIMEMessage(TestEmailBase): Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Oct 1 17:45:48 2010 @@ -121,6 +121,9 @@ Library ------- +- Issue #10004: quoprimime no longer generates a traceback when confronted + with invalid characters after '=' in a Q-encoded word. + - Issue #9950: Fix socket.sendall() crash or misbehaviour when a signal is received. Now sendall() properly calls signal handlers if necessary, and retries sending if these returned successfully, including on sockets From python-checkins at python.org Fri Oct 1 17:48:49 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 1 Oct 2010 17:48:49 +0200 (CEST) Subject: [Python-checkins] r85144 - in python/branches/release27-maint: Lib/email/quoprimime.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20101001154849.6D367FE63@mail.python.org> Author: r.david.murray Date: Fri Oct 1 17:48:49 2010 New Revision: 85144 Log: Merged revisions 85142 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85142 | r.david.murray | 2010-10-01 11:40:20 -0400 (Fri, 01 Oct 2010) | 5 lines #10004: in Q encoded word ignore '=xx' when xx is not valid hex. Bug report and fix by Thomas Guettler. ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Lib/email/quoprimime.py python/branches/release27-maint/Lib/email/test/test_email.py python/branches/release27-maint/Misc/NEWS Modified: python/branches/release27-maint/Lib/email/quoprimime.py ============================================================================== --- python/branches/release27-maint/Lib/email/quoprimime.py (original) +++ python/branches/release27-maint/Lib/email/quoprimime.py Fri Oct 1 17:48:49 2010 @@ -333,4 +333,4 @@ the high level email.header class for that functionality. """ s = s.replace('_', ' ') - return re.sub(r'=\w{2}', _unquote_match, s) + return re.sub(r'=[a-fA-F0-9]{2}', _unquote_match, s) Modified: python/branches/release27-maint/Lib/email/test/test_email.py ============================================================================== --- python/branches/release27-maint/Lib/email/test/test_email.py (original) +++ python/branches/release27-maint/Lib/email/test/test_email.py Fri Oct 1 17:48:49 2010 @@ -1621,6 +1621,12 @@ dh = decode_header(s % q) self.assertEqual(dh, [(a, 'iso-8859-1')]) + def test_rfc2047_Q_invalid_digits(self): + # issue 10004. + s = '=?iso-8659-1?Q?andr=e9=zz?=' + self.assertEqual(decode_header(s), + [(b'andr\xe9=zz', 'iso-8659-1')]) + # Test the MIMEMessage class class TestMIMEMessage(TestEmailBase): Modified: python/branches/release27-maint/Misc/NEWS ============================================================================== --- python/branches/release27-maint/Misc/NEWS (original) +++ python/branches/release27-maint/Misc/NEWS Fri Oct 1 17:48:49 2010 @@ -48,6 +48,9 @@ Library ------- +- Issue #10004: quoprimime no longer generates a traceback when confronted + with invalid characters after '=' in a Q-encoded word. + - Issue #9950: Fix socket.sendall() crash or misbehaviour when a signal is received. Now sendall() properly calls signal handlers if necessary, and retries sending if these returned successfully, including on sockets From python-checkins at python.org Fri Oct 1 18:44:03 2010 From: python-checkins at python.org (brian.curtin) Date: Fri, 1 Oct 2010 18:44:03 +0200 (CEST) Subject: [Python-checkins] r85145 - in python/branches/release27-maint: Lib/test/test_signal.py Misc/NEWS Modules/signalmodule.c Message-ID: <20101001164403.7AA88EE9A4@mail.python.org> Author: brian.curtin Date: Fri Oct 1 18:44:03 2010 New Revision: 85145 Log: Merged revisions 85140 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85140 | brian.curtin | 2010-10-01 09:49:24 -0500 (Fri, 01 Oct 2010) | 4 lines Fix #10003. Add SIGBREAK to the set of valid signals on Windows. This fixes a regression noticed by bzr, introduced by issue #9324. ........ Modified: python/branches/release27-maint/Lib/test/test_signal.py python/branches/release27-maint/Misc/NEWS python/branches/release27-maint/Modules/signalmodule.c Modified: python/branches/release27-maint/Lib/test/test_signal.py ============================================================================== --- python/branches/release27-maint/Lib/test/test_signal.py (original) +++ python/branches/release27-maint/Lib/test/test_signal.py Fri Oct 1 18:44:03 2010 @@ -212,13 +212,13 @@ @unittest.skipUnless(sys.platform == "win32", "Windows specific") class WindowsSignalTests(unittest.TestCase): def test_issue9324(self): + # Updated for issue #10003, adding SIGBREAK handler = lambda x, y: None - signal.signal(signal.SIGABRT, handler) - signal.signal(signal.SIGFPE, handler) - signal.signal(signal.SIGILL, handler) - signal.signal(signal.SIGINT, handler) - signal.signal(signal.SIGSEGV, handler) - signal.signal(signal.SIGTERM, handler) + for sig in (signal.SIGABRT, signal.SIGBREAK, signal.SIGFPE, + signal.SIGILL, signal.SIGINT, signal.SIGSEGV, + signal.SIGTERM): + # Set and then reset a handler for signals that work on windows + signal.signal(sig, signal.signal(sig, handler)) with self.assertRaises(ValueError): signal.signal(-1, handler) Modified: python/branches/release27-maint/Misc/NEWS ============================================================================== --- python/branches/release27-maint/Misc/NEWS (original) +++ python/branches/release27-maint/Misc/NEWS Fri Oct 1 18:44:03 2010 @@ -299,6 +299,9 @@ Extension Modules ----------------- +- Issue #10003: Allow handling of SIGBREAK on Windows. Fixes a regression + introduced by issue #9324. + - Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file descriptor is provided. Patch by Pascal Chambon. Modified: python/branches/release27-maint/Modules/signalmodule.c ============================================================================== --- python/branches/release27-maint/Modules/signalmodule.c (original) +++ python/branches/release27-maint/Modules/signalmodule.c Fri Oct 1 18:44:03 2010 @@ -261,6 +261,11 @@ /* Validate that sig_num is one of the allowable signals */ switch (sig_num) { case SIGABRT: break; +#ifdef SIGBREAK + /* Issue #10003: SIGBREAK is not documented as permitted, but works + and corresponds to CTRL_BREAK_EVENT. */ + case SIGBREAK: break; +#endif case SIGFPE: break; case SIGILL: break; case SIGINT: break; From python-checkins at python.org Fri Oct 1 22:38:33 2010 From: python-checkins at python.org (r.david.murray) Date: Fri, 1 Oct 2010 22:38:33 +0200 (CEST) Subject: [Python-checkins] r85146 - python/branches/py3k/Lib/email/generator.py Message-ID: <20101001203833.BD875EEA01@mail.python.org> Author: r.david.murray Date: Fri Oct 1 22:38:33 2010 New Revision: 85146 Log: Fix docstring typo. Modified: python/branches/py3k/Lib/email/generator.py Modified: python/branches/py3k/Lib/email/generator.py ============================================================================== --- python/branches/py3k/Lib/email/generator.py (original) +++ python/branches/py3k/Lib/email/generator.py Fri Oct 1 22:38:33 2010 @@ -270,7 +270,7 @@ _FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]' class DecodedGenerator(Generator): - """Generator a text representation of a message. + """Generates a text representation of a message. Like the Generator base class, except that non-text parts are substituted with a format string representing the part. From python-checkins at python.org Fri Oct 1 22:55:51 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 1 Oct 2010 22:55:51 +0200 (CEST) Subject: [Python-checkins] r85147 - in tracker/instances/python-dev: detectors/patches.py html/file.item.html lib/identify_patch.py schema.py Message-ID: <20101001205551.F3814EE9A5@mail.python.org> Author: martin.v.loewis Date: Fri Oct 1 22:55:51 2010 New Revision: 85147 Log: Add branch identification to files. Modified: tracker/instances/python-dev/detectors/patches.py tracker/instances/python-dev/html/file.item.html tracker/instances/python-dev/lib/identify_patch.py tracker/instances/python-dev/schema.py Modified: tracker/instances/python-dev/detectors/patches.py ============================================================================== --- tracker/instances/python-dev/detectors/patches.py (original) +++ tracker/instances/python-dev/detectors/patches.py Fri Oct 1 22:55:51 2010 @@ -4,6 +4,7 @@ # the "patch" keyword should get set automatically. import posixpath +import identify_patch patchtypes = ('.diff', '.patch') sourcetypes = ('.diff', '.patch', '.py') @@ -40,7 +41,19 @@ if patchid not in newvalues['keywords']: newvalues['keywords'].append(patchid) +def patches_branch(db, cl, nodeid, oldvalues): + # there shouldn't be old values + assert not oldvalues + if not ispatch(cl.get(nodeid, 'name'), patchtypes): + return + revno, branch = identify_patch.identify(db, cl.get(nodeid, 'content')) + if revno: + cl.set(nodeid, revision=str(revno)) + if branch: + cl.set(nodeid, branch=branch) + def init(db): db.file.audit('create', patches_text_plain) + db.file.react('create', patches_branch) db.issue.audit('create', patches_keyword) db.issue.audit('set', patches_keyword) Modified: tracker/instances/python-dev/html/file.item.html ============================================================================== --- tracker/instances/python-dev/html/file.item.html (original) +++ tracker/instances/python-dev/html/file.item.html Fri Oct 1 22:55:51 2010 @@ -34,6 +34,12 @@ for security reasons, it's not permitted to set content type to text/html. + Tracker Branch + + + Tracker Revision + + SpamBayes Score Modified: tracker/instances/python-dev/lib/identify_patch.py ============================================================================== --- tracker/instances/python-dev/lib/identify_patch.py (original) +++ tracker/instances/python-dev/lib/identify_patch.py Fri Oct 1 22:55:51 2010 @@ -1,7 +1,17 @@ -import subprocess +import subprocess, re from xml.etree import ElementTree +def identify(db, patch): + """Return revision number and branch of a patch; + either value may become None.""" + m = re.search('---.* ([0-9]+)', patch) + if not m: + return None, None + rev = int(m.group(1)) + return rev, find_branch(db, rev) + def find_branch(db, rev): + """Return the branch name for a given revision, or None.""" c = db.cursor c.execute('select branch from svnbranch where rev=%s', (rev,)) branch = c.fetchone() @@ -11,6 +21,8 @@ return fill_revs(db, lookfor=rev) def fill_revs(db, lookfor=None): + """Initialize/update svnbranch table. If lookfor is given, + return its branch, or None if that cannot be determined.""" result = None c = db.cursor c.execute('select max(rev) from svnbranch') @@ -19,6 +31,9 @@ start = 1 else: start = start+1 + if lookfor and lookfor < start: + # revision is not in database + return None p = subprocess.Popen(['svn', 'log', '-r%s:HEAD' % start, '--xml', '-v', 'http://svn.python.org/projects'], stdout = subprocess.PIPE, Modified: tracker/instances/python-dev/schema.py ============================================================================== --- tracker/instances/python-dev/schema.py (original) +++ tracker/instances/python-dev/schema.py Fri Oct 1 22:55:51 2010 @@ -130,10 +130,16 @@ spambayes_misclassified=Boolean(),) file = FileClass(db, "file", - name=String(), - description=String(indexme='yes'), - spambayes_score=Number(), - spambayes_misclassified=Boolean(),) + name=String(), + description=String(indexme='yes'), + spambayes_score=Number(), + spambayes_misclassified=Boolean(), + # filled out if this is a patch + revision=String(), + branch=String(), + # filled out if a corresponding Rietveld + # patchset exists for the issue + patchset=String(),) # IssueClass automatically gets these properties in addition to the Class ones: # title = String() From python-checkins at python.org Fri Oct 1 23:04:36 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 1 Oct 2010 23:04:36 +0200 (CEST) Subject: [Python-checkins] r85148 - tracker/instances/python-dev/lib/identify_patch.py Message-ID: <20101001210436.9F4E2EE9A9@mail.python.org> Author: martin.v.loewis Date: Fri Oct 1 23:04:36 2010 New Revision: 85148 Log: Convert to cron job. Modified: tracker/instances/python-dev/lib/identify_patch.py (contents, props changed) Modified: tracker/instances/python-dev/lib/identify_patch.py ============================================================================== --- tracker/instances/python-dev/lib/identify_patch.py (original) +++ tracker/instances/python-dev/lib/identify_patch.py Fri Oct 1 23:04:36 2010 @@ -1,4 +1,5 @@ -import subprocess, re +#!/usr/bin/python +import subprocess, re, sys from xml.etree import ElementTree def identify(db, patch): @@ -73,10 +74,12 @@ db.commit() return branch +# this runs as a cron job every 30min if __name__=='__main__': # manual setup: # create table svnbranch(rev integer primary key, branch text); # then run this once in the instance directory + sys.path.append('/home/roundup/roundup/lib/python2.5/site-packages') import roundup.instance tracker = roundup.instance.open('.') db = tracker.open('admin') From python-checkins at python.org Fri Oct 1 23:08:31 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 1 Oct 2010 23:08:31 +0200 (CEST) Subject: [Python-checkins] r85149 - tracker/instances/python-dev/lib/identify_patch.py Message-ID: <20101001210831.358E8EE9DE@mail.python.org> Author: martin.v.loewis Date: Fri Oct 1 23:08:31 2010 New Revision: 85149 Log: Fix path. Modified: tracker/instances/python-dev/lib/identify_patch.py Modified: tracker/instances/python-dev/lib/identify_patch.py ============================================================================== --- tracker/instances/python-dev/lib/identify_patch.py (original) +++ tracker/instances/python-dev/lib/identify_patch.py Fri Oct 1 23:08:31 2010 @@ -79,7 +79,7 @@ # manual setup: # create table svnbranch(rev integer primary key, branch text); # then run this once in the instance directory - sys.path.append('/home/roundup/roundup/lib/python2.5/site-packages') + sys.path.append('/home/roundup/lib/python2.5/site-packages') import roundup.instance tracker = roundup.instance.open('.') db = tracker.open('admin') From python-checkins at python.org Fri Oct 1 23:10:44 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 1 Oct 2010 23:10:44 +0200 (CEST) Subject: [Python-checkins] r85150 - tracker/instances/python-dev/lib/identify_patch.py Message-ID: <20101001211044.49F53EE9FF@mail.python.org> Author: martin.v.loewis Date: Fri Oct 1 23:10:44 2010 New Revision: 85150 Log: Fix typo Modified: tracker/instances/python-dev/lib/identify_patch.py Modified: tracker/instances/python-dev/lib/identify_patch.py ============================================================================== --- tracker/instances/python-dev/lib/identify_patch.py (original) +++ tracker/instances/python-dev/lib/identify_patch.py Fri Oct 1 23:10:44 2010 @@ -72,7 +72,7 @@ if lookfor == rev: result = branch db.commit() - return branch + return result # this runs as a cron job every 30min if __name__=='__main__': From python-checkins at python.org Fri Oct 1 23:36:37 2010 From: python-checkins at python.org (tarek.ziade) Date: Fri, 01 Oct 2010 23:36:37 +0200 Subject: [Python-checkins] distutils2: added support for more metadata and files Message-ID: tarek.ziade pushed c7e47ada3eec to distutils2: http://hg.python.org/distutils2/rev/c7e47ada3eec changeset: 691:c7e47ada3eec tag: tip user: Tarek Ziade date: Fri Oct 01 23:36:27 2010 +0200 summary: added support for more metadata and files files: distutils2/config.py, distutils2/metadata.py, distutils2/tests/test_config.py diff --git a/distutils2/config.py b/distutils2/config.py --- a/distutils2/config.py +++ b/distutils2/config.py @@ -75,16 +75,58 @@ # XXX return value + def _multiline(self, value): + if '\n' in value: + value = [v for v in + [v.strip() for v in value.split('\n')] + if v != ''] + return value + def _read_metadata(self, parser): if parser.has_option('global', 'setup_hook'): self.setup_hook = parser.get('global', 'setup_hook') metadata = self.dist.metadata + # setting the metadata values if 'metadata' in parser.sections(): for key, value in parser.items('metadata'): + key = key.replace('_', '-') + value = self._multiline(value) + if key == 'project-url': + value = [(label.strip(), url.strip()) + for label, url in + [v.split(',') for v in value]] if metadata.is_metadata_field(key): metadata[key] = self._convert_metadata(key, value) + if 'files' in parser.sections(): + files = dict([(key, self._multiline(value)) + for key, value in parser.items('files')]) + self.dist.packages = files.get('packages', []) + self.dist.py_modules = files.get('py_modules', []) + if isinstance(self.dist.py_modules, str): + self.dist.py_modules = [self.dist.py_modules] + self.dist.scripts = files.get('scripts', []) + + self.dist.package_data = {} + for data in files.get('package_data', []): + data = data.split('=') + if len(data) != 2: + continue + key, value = data + self.dist.package_data[key.strip()] = value.strip() + + self.dist.data_files = [] + for data in files.get('data_files', []): + data = data.split('=') + if len(data) != 2: + continue + key, value = data + values = [v.strip() for v in value.split(',')] + self.dist.data_files.append((key, values)) + + # manifest template + # XXX see later def parse_config_files(self, filenames=None): if filenames is None: diff --git a/distutils2/metadata.py b/distutils2/metadata.py --- a/distutils2/metadata.py +++ b/distutils2/metadata.py @@ -368,7 +368,7 @@ if ((name in _ELEMENTSFIELD or name == 'Platform') and not isinstance(value, (list, tuple))): if isinstance(value, str): - value = value.split(',') + value = [v.strip() for v in value.split(',')] else: value = [] elif (name in _LISTFIELDS and diff --git a/distutils2/tests/test_config.py b/distutils2/tests/test_config.py --- a/distutils2/tests/test_config.py +++ b/distutils2/tests/test_config.py @@ -1,3 +1,4 @@ +# -*- encoding: utf8 -*- """Tests for distutils.config.""" import sys import os @@ -9,9 +10,67 @@ SETUP_CFG = """ [metadata] -version = 1.0 -author = tarek -author_email = tarek at ziade.org +name = RestingParrot +version = 0.6.4 +author = Carl Meyer +author_email = carl at oddbird.net +maintainer = ??ric Araujo +maintainer_email = merwok at netwok.org +summary = A sample project demonstrating distutils2 packaging +description = README +keywords = distutils2, packaging, sample project + +classifier = + Development Status :: 4 - Beta + Environment :: Console (Text Based) + Environment :: X11 Applications :: GTK; python_version < '3' + License :: OSI Approved :: MIT License + Programming Language :: Python + Programming Language :: Python :: 2 + Programming Language :: Python :: 3 + +requires_python = >=2.4, <3.2 + +requires_dist = + PetShoppe + MichaelPalin (> 1.1) + pywin32; sys.platform == 'win32' + pysqlite2; python_version < '2.5' + inotify (0.0.1); sys.platform == 'linux2' + +requires_external = libxml2 + +provides_dist = distutils2-sample-project (0.2) + unittest2-sample-project + +project_url = + Main repository, http://bitbucket.org/carljm/sample-distutils2-project + Fork in progress, http://bitbucket.org/Merwok/sample-distutils2-project + +[files] +packages = one + two + three +py_modules = haven + +scripts = + script1.py + scripts/find-coconuts + bin/taunt + +package_data = + cheese = data/templates/* + +data_files = + bitmaps = bm/b1.gif, bm/b2.gif + config = cfg/data.cfg + /etc/init.d = init-script + +# Replaces MANIFEST.in +sdist_extra = + include THANKS HACKING + recursive-include examples *.txt *.py + prune examples/sample?/build """ class ConfigTestCase(support.TempdirManager, @@ -39,9 +98,45 @@ sys.argv[:] = old_args # check what was done - self.assertEqual(dist.metadata['Author'], 'tarek') - self.assertEqual(dist.metadata['Author-Email'], 'tarek at ziade.org') - self.assertEqual(dist.metadata['Version'], '1.0') + self.assertEqual(dist.metadata['Author'], 'Carl Meyer') + self.assertEqual(dist.metadata['Author-Email'], 'carl at oddbird.net') + self.assertEqual(dist.metadata['Version'], '0.6.4') + + wanted = ['Development Status :: 4 - Beta', + 'Environment :: Console (Text Based)', + "Environment :: X11 Applications :: GTK; python_version < '3'", + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3'] + self.assertEqual(dist.metadata['Classifier'], wanted) + + wanted = ['distutils2', 'packaging', 'sample project'] + self.assertEqual(dist.metadata['Keywords'], wanted) + + self.assertEqual(dist.metadata['Requires-Python'], '>=2.4, <3.2') + + wanted = ['PetShoppe', + 'MichaelPalin (> 1.1)', + "pywin32; sys.platform == 'win32'", + "pysqlite2; python_version < '2.5'", + "inotify (0.0.1); sys.platform == 'linux2'"] + + self.assertEqual(dist.metadata['Requires-Dist'], wanted) + urls = [('Main repository', + 'http://bitbucket.org/carljm/sample-distutils2-project'), + ('Fork in progress', + 'http://bitbucket.org/Merwok/sample-distutils2-project')] + self.assertEqual(dist.metadata['Project-Url'], urls) + + + self.assertEqual(dist.packages, ['one', 'two', 'three']) + self.assertEqual(dist.py_modules, ['haven']) + self.assertEqual(dist.package_data, {'cheese': 'data/templates/*'}) + self.assertEqual(dist.data_files, + [('bitmaps ', ['bm/b1.gif', 'bm/b2.gif']), + ('config ', ['cfg/data.cfg']), + ('/etc/init.d ', ['init-script'])]) def test_suite(): -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Fri Oct 1 23:40:04 2010 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 1 Oct 2010 23:40:04 +0200 (CEST) Subject: [Python-checkins] r85151 - in tracker/instances/python-dev: lib/identify_patch.py scripts/fillrevs Message-ID: <20101001214004.4B122FD82@mail.python.org> Author: martin.v.loewis Date: Fri Oct 1 23:40:04 2010 New Revision: 85151 Log: Add script to fill out revision information. Added: tracker/instances/python-dev/scripts/fillrevs (contents, props changed) Modified: tracker/instances/python-dev/lib/identify_patch.py Modified: tracker/instances/python-dev/lib/identify_patch.py ============================================================================== --- tracker/instances/python-dev/lib/identify_patch.py (original) +++ tracker/instances/python-dev/lib/identify_patch.py Fri Oct 1 23:40:04 2010 @@ -5,7 +5,7 @@ def identify(db, patch): """Return revision number and branch of a patch; either value may become None.""" - m = re.search('---.* ([0-9]+)', patch) + m = re.search(r'---.* ([0-9]+)\)', patch) if not m: return None, None rev = int(m.group(1)) Added: tracker/instances/python-dev/scripts/fillrevs ============================================================================== --- (empty file) +++ tracker/instances/python-dev/scripts/fillrevs Fri Oct 1 23:40:04 2010 @@ -0,0 +1,19 @@ +#!/usr/bin/python +# Fill branch information for all file objects where it's missing +import identify_patch +import roundup.instance +tracker = roundup.instance.open('.') +db = tracker.open('admin') + +for fileid in db.file.list(): + fname = db.file.get(fileid, 'name') + if fname.endswith('.patch') or fname.endswith('.diff'): + if db.file.get(fileid, 'revision'): + continue + data = db.file.get(fileid, 'content') + revid, branch = identify_patch.identify(db, data) + if revid: + db.file.set_inner(fileid, revision=str(revid)) + if branch: + db.file.set_inner(fileid, branch=branch) + db.commit() From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Branch merge Message-ID: tarek.ziade pushed 4ddf7feadf0f to distutils2: http://hg.python.org/distutils2/rev/4ddf7feadf0f changeset: 693:4ddf7feadf0f parent: 665:d8ae6395397e parent: 692:6f7d4343e99b user: ?ric Araujo date: Mon Sep 06 06:32:30 2010 +0200 summary: Branch merge files: diff --git a/src/DEVNOTES.txt b/src/DEVNOTES.txt --- a/src/DEVNOTES.txt +++ b/src/DEVNOTES.txt @@ -7,8 +7,3 @@ - Always run tests.sh before you push a change. This implies that you have all Python versions installed from 2.4 to 2.7. - -- With Python 2.4, if you want to run tests with runtests.py, or run - just one test directly, be sure to run python2.4 setup.py build_ext - first, else tests won't find _hashlib or _md5. When using tests.sh, - build_ext is automatically done. diff --git a/src/runtests-cov.py b/src/runtests-cov.py --- a/src/runtests-cov.py +++ b/src/runtests-cov.py @@ -133,4 +133,10 @@ except ImportError: sys.stderr.write('Error: You have to install unittest2') sys.exit(1) + if sys.version < '2.5': + try: + from distutils2._backport import hashlib + except ImportError: + import subprocess + subprocess.call([sys.executable, 'setup.py', 'build_ext']) sys.exit(test_main()) diff --git a/src/runtests.py b/src/runtests.py --- a/src/runtests.py +++ b/src/runtests.py @@ -33,4 +33,10 @@ except ImportError: sys.stderr.write('Error: You have to install unittest2') sys.exit(1) + if sys.version < '2.5': + try: + from distutils2._backport import hashlib + except ImportError: + import subprocess + subprocess.call([sys.executable, 'setup.py', 'build_ext']) sys.exit(test_main()) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Automatically build _hashlib in runtests*.py for 2.4 Message-ID: tarek.ziade pushed 6f7d4343e99b to distutils2: http://hg.python.org/distutils2/rev/6f7d4343e99b changeset: 692:6f7d4343e99b parent: 661:d7a0ac3abdbe user: ?ric Araujo date: Mon Aug 30 04:25:43 2010 +0200 summary: Automatically build _hashlib in runtests*.py for 2.4 files: src/DEVNOTES.txt, src/runtests-cov.py, src/runtests.py diff --git a/src/DEVNOTES.txt b/src/DEVNOTES.txt --- a/src/DEVNOTES.txt +++ b/src/DEVNOTES.txt @@ -7,8 +7,3 @@ - Always run tests.sh before you push a change. This implies that you have all Python versions installed from 2.4 to 2.7. - -- With Python 2.4, if you want to run tests with runtests.py, or run - just one test directly, be sure to run python2.4 setup.py build_ext - first, else tests won't find _hashlib or _md5. When using tests.sh, - build_ext is automatically done. diff --git a/src/runtests-cov.py b/src/runtests-cov.py --- a/src/runtests-cov.py +++ b/src/runtests-cov.py @@ -133,4 +133,10 @@ except ImportError: sys.stderr.write('Error: You have to install unittest2') sys.exit(1) + if sys.version < '2.5': + try: + from distutils2._backport import hashlib + except ImportError: + import subprocess + subprocess.call([sys.executable, 'setup.py', 'build_ext']) sys.exit(test_main()) diff --git a/src/runtests.py b/src/runtests.py --- a/src/runtests.py +++ b/src/runtests.py @@ -33,4 +33,10 @@ except ImportError: sys.stderr.write('Error: You have to install unittest2') sys.exit(1) + if sys.version < '2.5': + try: + from distutils2._backport import hashlib + except ImportError: + import subprocess + subprocess.call([sys.executable, 'setup.py', 'build_ext']) sys.exit(test_main()) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Remove spurious output with runtests.py (+ modernize test_config) Message-ID: tarek.ziade pushed efe244b78376 to distutils2: http://hg.python.org/distutils2/rev/efe244b78376 changeset: 696:efe244b78376 user: ?ric Araujo date: Tue Sep 28 11:27:08 2010 +0200 summary: Remove spurious output with runtests.py (+ modernize test_config) files: distutils2/tests/test_config.py, distutils2/tests/test_register.py, distutils2/tests/test_test.py diff --git a/distutils2/tests/test_config.py b/distutils2/tests/test_config.py --- a/distutils2/tests/test_config.py +++ b/distutils2/tests/test_config.py @@ -1,8 +1,9 @@ """Tests for distutils.config.""" +import os import sys -import os -import copy +from StringIO import StringIO +from distutils2.core import setup from distutils2.tests import support, run_unittest from distutils2.tests.support import unittest @@ -17,26 +18,23 @@ class ConfigTestCase(support.TempdirManager, unittest.TestCase): + def setUp(self): + super(ConfigTestCase, self).setUp() + self.addCleanup(setattr, sys, 'argv', sys.argv) + self.addCleanup(setattr, sys, 'stdout', sys.stdout) + self.addCleanup(os.chdir, os.getcwd()) + def test_config(self): tempdir = self.mkdtemp() - setup_cfg = os.path.join(tempdir, 'setup.cfg') - f = open(setup_cfg, 'w') - try: - f.write(SETUP_CFG) - finally: - f.close() + os.chdir(tempdir) + self.write_file('setup.cfg', SETUP_CFG) - # trying to load the metadata now - old_args = copy.copy(sys.argv) + # try to load the metadata now + sys.stdout = StringIO() sys.argv[:] = ['setup.py', '--version'] - old_wd = os.getcwd() - os.chdir(tempdir) - try: - from distutils2.core import setup - dist = setup() - finally: - os.chdir(old_wd) - sys.argv[:] = old_args + dist = setup() + # sanity check + self.assertEqual(sys.stdout.getvalue(), '1.0' + os.linesep) # check what was done self.assertEqual(dist.metadata['Author'], 'tarek') diff --git a/distutils2/tests/test_register.py b/distutils2/tests/test_register.py --- a/distutils2/tests/test_register.py +++ b/distutils2/tests/test_register.py @@ -68,7 +68,7 @@ return 'xxx' class RegisterTestCase(support.TempdirManager, support.EnvironGuard, - unittest.TestCase): + support.LoggingCatcher, unittest.TestCase): def setUp(self): super(RegisterTestCase, self).setUp() diff --git a/distutils2/tests/test_test.py b/distutils2/tests/test_test.py --- a/distutils2/tests/test_test.py +++ b/distutils2/tests/test_test.py @@ -9,7 +9,7 @@ from operator import getitem, setitem, delitem from StringIO import StringIO from distutils2.core import Command -from distutils2.tests.support import unittest, TempdirManager +from distutils2.tests.support import unittest, TempdirManager, LoggingCatcher from distutils2.command.test import test from distutils2.dist import Distribution @@ -29,6 +29,7 @@ here = os.path.dirname(os.path.abspath(__file__)) class TestTest(TempdirManager, + LoggingCatcher, unittest.TestCase): def setUp(self): @@ -73,7 +74,7 @@ orig_has_attr = _hasattr(obj, attr) if orig_has_attr: - orig_val = _getattr(obj, attr) + orig_val = _getattr(obj, attr) if delete is False: _setattr(obj, attr, new_val) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Branch merge Message-ID: tarek.ziade pushed 00abdfe2a4bd to distutils2: http://hg.python.org/distutils2/rev/00abdfe2a4bd changeset: 694:00abdfe2a4bd parent: 693:4ddf7feadf0f parent: 668:ea174f2c7d8e user: ?ric Araujo date: Wed Sep 08 03:25:35 2010 +0200 summary: Branch merge files: diff --git a/src/distutils2/command/build_clib.py b/src/distutils2/command/build_clib.py --- a/src/distutils2/command/build_clib.py +++ b/src/distutils2/command/build_clib.py @@ -32,9 +32,9 @@ description = "build C/C++ libraries used by Python extensions" user_options = [ - ('build-clib', 'b', + ('build-clib=', 'b', "directory to build C/C++ libraries to"), - ('build-temp', 't', + ('build-temp=', 't', "directory to put temporary build by-products"), ('debug', 'g', "compile with debugging information"), diff --git a/src/distutils2/command/upload.py b/src/distutils2/command/upload.py --- a/src/distutils2/command/upload.py +++ b/src/distutils2/command/upload.py @@ -7,7 +7,10 @@ from urllib2 import urlopen, Request, HTTPError from base64 import standard_b64encode import urlparse -import StringIO as StringIO +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO try: from hashlib import md5 except ImportError: @@ -135,7 +138,7 @@ boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = '\n--' + boundary end_boundary = sep_boundary + '--' - body = StringIO.StringIO() + body = StringIO() file_fields = ('content', 'gpg_signature') for key, values in data.items(): @@ -198,5 +201,7 @@ else: self.announce('Upload failed (%s): %s' % (status, reason), log.ERROR) + if self.show_response: - self.announce('-'*75, result.read(), '-'*75) + msg = '\n'.join(('-' * 75, result.read(), '-' * 75)) + self.announce(msg, log.INFO) diff --git a/src/distutils2/command/upload_docs.py b/src/distutils2/command/upload_docs.py --- a/src/distutils2/command/upload_docs.py +++ b/src/distutils2/command/upload_docs.py @@ -1,5 +1,13 @@ -import base64, httplib, os.path, socket, urlparse, zipfile -from cStringIO import StringIO +import os +import base64 +import httplib +import socket +import urlparse +import zipfile +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO from distutils2 import log from distutils2.command.upload import upload @@ -144,4 +152,5 @@ log.ERROR) if self.show_response: - print "\n".join(['-'*75, r.read(), '-'*75]) + msg = '\n'.join(('-' * 75, r.read(), '-' * 75)) + self.announce(msg, log.INFO) 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 @@ -280,8 +280,8 @@ finally: os.chdir(old_wd) self.assertTrue(os.path.exists(so_file)) - self.assertEqual(os.path.splitext(so_file)[-1], - sysconfig.get_config_var('SO')) + so_ext = sysconfig.get_config_var('SO') + self.assertTrue(so_file.endswith(so_ext)) so_dir = os.path.dirname(so_file) self.assertEqual(so_dir, other_tmp_dir) @@ -289,8 +289,7 @@ cmd.run() so_file = cmd.get_outputs()[0] self.assertTrue(os.path.exists(so_file)) - self.assertEqual(os.path.splitext(so_file)[-1], - sysconfig.get_config_var('SO')) + self.assertTrue(so_file.endswith(so_ext)) so_dir = os.path.dirname(so_file) self.assertEqual(so_dir, cmd.build_lib) diff --git a/src/distutils2/tests/test_upload_docs.py b/src/distutils2/tests/test_upload_docs.py --- a/src/distutils2/tests/test_upload_docs.py +++ b/src/distutils2/tests/test_upload_docs.py @@ -186,26 +186,13 @@ self.assertRaises(DistutilsOptionError, self.cmd.ensure_finalized) def test_show_response(self): - orig_stdout = sys.stdout - write_args = [] + self.prepare_command() + self.cmd.show_response = True + self.cmd.run() + record = self.logs[-1][1] - class MockStdIn(object): - def write(self, arg): - write_args.append(arg) - def flush(self): - pass - - sys.stdout = MockStdIn() - try: - self.prepare_command() - self.cmd.show_response = True - self.cmd.run() - finally: - sys.stdout = orig_stdout - - self.assertTrue(write_args[0], "should report the response") - self.assertIn(self.pypi.default_response_data + "\n", - '\n'.join(write_args)) + self.assertTrue(record, "should report the response") + self.assertIn(self.pypi.default_response_data, record) def test_suite(): return unittest.makeSuite(UploadDocsTestCase) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Fix typo (#9934) Message-ID: tarek.ziade pushed 2f460982b025 to distutils2: http://hg.python.org/distutils2/rev/2f460982b025 changeset: 695:2f460982b025 parent: 689:0b5a96454086 user: ?ric Araujo date: Mon Sep 27 21:16:58 2010 +0200 summary: Fix typo (#9934) files: docs/source/distutils/sourcedist.rst diff --git a/docs/source/distutils/sourcedist.rst b/docs/source/distutils/sourcedist.rst --- a/docs/source/distutils/sourcedist.rst +++ b/docs/source/distutils/sourcedist.rst @@ -142,7 +142,7 @@ python setup.py sdist --manifest-only -:option:`-o` is a sortcut for :option:`--manifest-only`. +:option:`-o` is a shortcut for :option:`--manifest-only`. .. _manifest_template: -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: fixed the coverage measurement so see definitions as covered for version.py and Message-ID: tarek.ziade pushed c2707cecd0a6 to distutils2: http://hg.python.org/distutils2/rev/c2707cecd0a6 changeset: 699:c2707cecd0a6 parent: 697:12c37807f046 user: Yannick Gingras date: Wed Sep 29 20:08:52 2010 -0400 summary: fixed the coverage measurement so see definitions as covered for version.py and a few others files: runtests-cov.py diff --git a/runtests-cov.py b/runtests-cov.py --- a/runtests-cov.py +++ b/runtests-cov.py @@ -136,8 +136,8 @@ if __name__ == "__main__": try: - from distutils2.tests.support import unittest + import unittest2 except ImportError: - sys.stderr.write('Error: You have to install unittest2') + sys.stderr.write('Error: You have to install unittest2\n') sys.exit(1) sys.exit(test_main()) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: made runtests-cov.py work with Coverage 3.4+ Message-ID: tarek.ziade pushed 12c37807f046 to distutils2: http://hg.python.org/distutils2/rev/12c37807f046 changeset: 697:12c37807f046 parent: 689:0b5a96454086 user: Yannick Gingras date: Tue Sep 28 18:38:18 2010 -0400 summary: made runtests-cov.py work with Coverage 3.4+ files: runtests-cov.py diff --git a/runtests-cov.py b/runtests-cov.py --- a/runtests-cov.py +++ b/runtests-cov.py @@ -83,8 +83,15 @@ # that module is also completely optional pass - cov.report(morfs, omit_prefixes=prefixes, show_missing=opts.show_missing) - + try: + cov.report(morfs, + omit_prefixes=prefixes, + show_missing=opts.show_missing) + except TypeError: + # Coverage 3.4 turned `omit_prefixes` into a list of globbing patterns + cov.report(morfs, + omit=[p+"*" for p in prefixes], + show_missing=opts.show_missing) def test_main(): opts, args = parse_opts() -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Automated merge with ssh://hg@bitbucket.org/mtlpython/distutils2 Message-ID: tarek.ziade pushed fc571d152df0 to distutils2: http://hg.python.org/distutils2/rev/fc571d152df0 changeset: 700:fc571d152df0 parent: 698:996c9c60d2b1 parent: 699:c2707cecd0a6 user: Yannick Gingras date: Wed Sep 29 20:10:12 2010 -0400 summary: Automated merge with ssh://hg at bitbucket.org/mtlpython/distutils2 files: diff --git a/runtests-cov.py b/runtests-cov.py --- a/runtests-cov.py +++ b/runtests-cov.py @@ -136,8 +136,8 @@ if __name__ == "__main__": try: - from distutils2.tests.support import unittest + import unittest2 except ImportError: - sys.stderr.write('Error: You have to install unittest2') + sys.stderr.write('Error: You have to install unittest2\n') sys.exit(1) sys.exit(test_main()) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Changed hashing behaviour for NormalizedVersion. Equal versions have the Message-ID: tarek.ziade pushed a4eaf904c096 to distutils2: http://hg.python.org/distutils2/rev/a4eaf904c096 changeset: 701:a4eaf904c096 parent: 697:12c37807f046 user: Amos Latteier date: Wed Sep 29 20:42:58 2010 -0400 summary: Changed hashing behaviour for NormalizedVersion. Equal versions have the files: distutils2/tests/test_version.py, distutils2/version.py diff --git a/distutils2/tests/test_version.py b/distutils2/tests/test_version.py --- a/distutils2/tests/test_version.py +++ b/distutils2/tests/test_version.py @@ -31,6 +31,15 @@ for v, s in self.versions: self.assertEqual(str(v), s) + def test_hash(self): + + for v, s in self.versions: + self.assertEqual(hash(v), hash(V(s))) + + versions = set([v for v,s in self.versions]) + for v, s in self.versions: + self.assertIn(v, versions) + def test_from_parts(self): for v, s in self.versions: diff --git a/distutils2/version.py b/distutils2/version.py --- a/distutils2/version.py +++ b/distutils2/version.py @@ -131,7 +131,7 @@ pad_zeros_length=0): """Parse 'N.N.N' sequences, return a list of ints. - @param s {str} 'N.N.N..." sequence to be parsed + @param s {str} 'N.N.N...' sequence to be parsed @param full_ver_str {str} The full version string from which this comes. Used for error strings. @param drop_trailing_zeros {bool} Whether to drop trailing zeros @@ -206,7 +206,8 @@ return self.__eq__(other) or self.__gt__(other) # See http://docs.python.org/reference/datamodel#object.__hash__ - __hash__ = object.__hash__ + def __hash__(self): + return hash(self.parts) def suggest_normalized_version(s): -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: merge Message-ID: tarek.ziade pushed 996c9c60d2b1 to distutils2: http://hg.python.org/distutils2/rev/996c9c60d2b1 changeset: 698:996c9c60d2b1 parent: 690:37f948f6be6c parent: 697:12c37807f046 user: mlhamel date: Wed Sep 29 19:43:01 2010 -0400 summary: merge files: diff --git a/runtests-cov.py b/runtests-cov.py --- a/runtests-cov.py +++ b/runtests-cov.py @@ -83,8 +83,15 @@ # that module is also completely optional pass - cov.report(morfs, omit_prefixes=prefixes, show_missing=opts.show_missing) - + try: + cov.report(morfs, + omit_prefixes=prefixes, + show_missing=opts.show_missing) + except TypeError: + # Coverage 3.4 turned `omit_prefixes` into a list of globbing patterns + cov.report(morfs, + omit=[p+"*" for p in prefixes], + show_missing=opts.show_missing) def test_main(): opts, args = parse_opts() -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Add test for VersionPredicate.__repr__ Message-ID: tarek.ziade pushed 2022ccd8fc7c to distutils2: http://hg.python.org/distutils2/rev/2022ccd8fc7c changeset: 702:2022ccd8fc7c user: Amos Latteier date: Wed Sep 29 20:53:32 2010 -0400 summary: Add test for VersionPredicate.__repr__ files: distutils2/tests/test_version.py diff --git a/distutils2/tests/test_version.py b/distutils2/tests/test_version.py --- a/distutils2/tests/test_version.py +++ b/distutils2/tests/test_version.py @@ -197,6 +197,10 @@ # XXX need to silent the micro version in this case #assert not VersionPredicate('Ho (<3.0,!=2.6)').match('2.6.3') + # test repr + for predicate in predicates: + self.assertEqual(str(VersionPredicate(predicate)), predicate) + def test_predicate_name(self): # Test that names are parsed the right way -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Merge. Message-ID: tarek.ziade pushed 7c48dacd3e0b to distutils2: http://hg.python.org/distutils2/rev/7c48dacd3e0b changeset: 703:7c48dacd3e0b parent: 702:2022ccd8fc7c parent: 700:fc571d152df0 user: Amos Latteier date: Wed Sep 29 20:59:25 2010 -0400 summary: Merge. files: diff --git a/distutils2/command/upload_docs.py b/distutils2/command/upload_docs.py --- a/distutils2/command/upload_docs.py +++ b/distutils2/command/upload_docs.py @@ -84,6 +84,8 @@ if self.upload_dir is None: build = self.get_finalized_command('build') self.upload_dir = os.path.join(build.build_base, "docs") + if not os.path.isdir(self.upload_dir): + self.upload_dir = os.path.join(build.build_base, "doc") self.announce('Using upload directory %s' % self.upload_dir) self.verify_upload_dir(self.upload_dir) config = read_pypirc(self.repository, self.realm) diff --git a/distutils2/tests/test_upload_docs.py b/distutils2/tests/test_upload_docs.py --- a/distutils2/tests/test_upload_docs.py +++ b/distutils2/tests/test_upload_docs.py @@ -76,6 +76,19 @@ finally: os.chdir(previous) + def test_default_uploaddir_looks_for_doc_also(self): + sandbox = self.mkdtemp() + previous = os.getcwd() + os.chdir(sandbox) + try: + os.mkdir("build") + self.prepare_sample_dir("build") + os.rename(os.path.join("build", "docs"), os.path.join("build", "doc")) + self.cmd.ensure_finalized() + self.assertEqual(self.cmd.upload_dir, os.path.join("build", "doc")) + finally: + os.chdir(previous) + def prepare_sample_dir(self, sample_dir=None): if sample_dir is None: sample_dir = self.mkdtemp() diff --git a/docs/source/distutils/newcommands.rst b/docs/source/distutils/newcommands.rst --- a/docs/source/distutils/newcommands.rst +++ b/docs/source/distutils/newcommands.rst @@ -130,8 +130,8 @@ The ``upload_docs`` command has the following options: ``--upload-dir`` - The directory to be uploaded to the repository. The default value is - ``docs`` in project root. + The directory to be uploaded to the repository. By default documentation + is searched for in ``docs`` (or ``doc``) directory in project root. ``--show-response`` Display the full response text from server; this is useful for debugging diff --git a/runtests-cov.py b/runtests-cov.py --- a/runtests-cov.py +++ b/runtests-cov.py @@ -136,8 +136,8 @@ if __name__ == "__main__": try: - from distutils2.tests.support import unittest + import unittest2 except ImportError: - sys.stderr.write('Error: You have to install unittest2') + sys.stderr.write('Error: You have to install unittest2\n') sys.exit(1) sys.exit(test_main()) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Added some more hash testing to make the intent of equal hashes clearer. Message-ID: tarek.ziade pushed 6c3bcf1c4499 to distutils2: http://hg.python.org/distutils2/rev/6c3bcf1c4499 changeset: 705:6c3bcf1c4499 user: Amos Latteier date: Wed Sep 29 22:02:26 2010 -0400 summary: Added some more hash testing to make the intent of equal hashes clearer. files: distutils2/tests/test_version.py diff --git a/distutils2/tests/test_version.py b/distutils2/tests/test_version.py --- a/distutils2/tests/test_version.py +++ b/distutils2/tests/test_version.py @@ -40,6 +40,8 @@ for v, s in self.versions: self.assertIn(v, versions) + self.assertEqual(set([V('1.0')]), set([V('1.0'), V('1.0')])) + def test_from_parts(self): for v, s in self.versions: -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Merge. Message-ID: tarek.ziade pushed 10276d4979aa to distutils2: http://hg.python.org/distutils2/rev/10276d4979aa changeset: 707:10276d4979aa parent: 706:daf17ae62195 parent: 705:6c3bcf1c4499 user: Rajiv Abraham date: Wed Sep 29 22:44:37 2010 -0400 summary: Merge. files: diff --git a/distutils2/tests/test_index_simple.py b/distutils2/tests/test_index_simple.py --- a/distutils2/tests/test_index_simple.py +++ b/distutils2/tests/test_index_simple.py @@ -20,7 +20,7 @@ urls """ if hosts is None: - hosts = (server.full_address.strip("http://"),) + hosts = (server.full_address.replace("http://", ""),) kwargs['hosts'] = hosts return Crawler(server.full_address + base_url, *args, **kwargs) diff --git a/distutils2/tests/test_version.py b/distutils2/tests/test_version.py --- a/distutils2/tests/test_version.py +++ b/distutils2/tests/test_version.py @@ -31,6 +31,17 @@ for v, s in self.versions: self.assertEqual(str(v), s) + def test_hash(self): + + for v, s in self.versions: + self.assertEqual(hash(v), hash(V(s))) + + versions = set([v for v,s in self.versions]) + for v, s in self.versions: + self.assertIn(v, versions) + + self.assertEqual(set([V('1.0')]), set([V('1.0'), V('1.0')])) + def test_from_parts(self): for v, s in self.versions: @@ -188,6 +199,10 @@ # XXX need to silent the micro version in this case #assert not VersionPredicate('Ho (<3.0,!=2.6)').match('2.6.3') + # test repr + for predicate in predicates: + self.assertEqual(str(VersionPredicate(predicate)), predicate) + def test_predicate_name(self): # Test that names are parsed the right way diff --git a/distutils2/version.py b/distutils2/version.py --- a/distutils2/version.py +++ b/distutils2/version.py @@ -131,7 +131,7 @@ pad_zeros_length=0): """Parse 'N.N.N' sequences, return a list of ints. - @param s {str} 'N.N.N..." sequence to be parsed + @param s {str} 'N.N.N...' sequence to be parsed @param full_ver_str {str} The full version string from which this comes. Used for error strings. @param drop_trailing_zeros {bool} Whether to drop trailing zeros @@ -206,7 +206,8 @@ return self.__eq__(other) or self.__gt__(other) # See http://docs.python.org/reference/datamodel#object.__hash__ - __hash__ = object.__hash__ + def __hash__(self): + return hash(self.parts) def suggest_normalized_version(s): -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Fixed issue with striping of hostname in test_index_simple.py Message-ID: tarek.ziade pushed 2df39aaf6833 to distutils2: http://hg.python.org/distutils2/rev/2df39aaf6833 changeset: 704:2df39aaf6833 user: Mathieu Perreault date: Wed Sep 29 21:50:06 2010 -0400 summary: Fixed issue with striping of hostname in test_index_simple.py files: distutils2/tests/test_index_simple.py diff --git a/distutils2/tests/test_index_simple.py b/distutils2/tests/test_index_simple.py --- a/distutils2/tests/test_index_simple.py +++ b/distutils2/tests/test_index_simple.py @@ -20,7 +20,7 @@ urls """ if hosts is None: - hosts = (server.full_address.strip("http://"),) + hosts = (server.full_address.replace("http://", ""),) kwargs['hosts'] = hosts return Crawler(server.full_address + base_url, *args, **kwargs) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Corrected reference to msvccompiler in the 'from' statement Message-ID: tarek.ziade pushed daf17ae62195 to distutils2: http://hg.python.org/distutils2/rev/daf17ae62195 changeset: 706:daf17ae62195 parent: 700:fc571d152df0 user: Rajiv Abraham date: Wed Sep 29 22:37:51 2010 -0400 summary: Corrected reference to msvccompiler in the 'from' statement files: distutils2/command/bdist_msi.py, distutils2/command/build_ext.py, distutils2/compiler/msvccompiler.py diff --git a/distutils2/command/bdist_msi.py b/distutils2/command/bdist_msi.py --- a/distutils2/command/bdist_msi.py +++ b/distutils2/command/bdist_msi.py @@ -10,11 +10,11 @@ from sysconfig import get_python_version from distutils2.core import Command -from distutils2.dir_util import remove_tree from distutils2.version import StrictVersion from distutils2.errors import DistutilsOptionError from distutils2 import log from distutils2.util import get_platform +from distutils2._backport.shutil import rmtree import msilib from msilib import schema, sequence, text @@ -259,7 +259,10 @@ self.distribution.dist_files.append(tup) if not self.keep_temp: - remove_tree(self.bdist_dir, dry_run=self.dry_run) + if self.dry_run: + pass # XXX + else: + rmtree(self.bdist_dir) def add_files(self): db = self.db diff --git a/distutils2/command/build_ext.py b/distutils2/command/build_ext.py --- a/distutils2/command/build_ext.py +++ b/distutils2/command/build_ext.py @@ -31,7 +31,7 @@ HAS_USER_SITE = True if os.name == 'nt': - from distutils2.msvccompiler import get_build_version + from distutils2.compiler.msvccompiler import get_build_version MSVC_VERSION = int(get_build_version()) # An extension name is just a dot-separated list of Python NAMEs (ie. diff --git a/distutils2/compiler/msvccompiler.py b/distutils2/compiler/msvccompiler.py --- a/distutils2/compiler/msvccompiler.py +++ b/distutils2/compiler/msvccompiler.py @@ -654,6 +654,6 @@ if get_build_version() >= 8.0: log.debug("Importing new compiler from distutils.msvc9compiler") OldMSVCCompiler = MSVCCompiler - from distutils2.msvc9compiler import MSVCCompiler + from distutils2.compiler.msvc9compiler import MSVCCompiler # get_build_architecture not really relevant now we support cross-compile - from distutils2.msvc9compiler import MacroExpander + from distutils2.compiler.msvc9compiler import MacroExpander -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Automated merge with ssh://hg@bitbucket.org/mtlpython/distutils2 Message-ID: tarek.ziade pushed db86d137f3dd to distutils2: http://hg.python.org/distutils2/rev/db86d137f3dd changeset: 710:db86d137f3dd parent: 707:10276d4979aa parent: 709:7291a92d6de3 user: Derek McTavish Mounce date: Wed Sep 29 23:25:26 2010 -0400 summary: Automated merge with ssh://hg at bitbucket.org/mtlpython/distutils2 files: diff --git a/docs/source/distutils/introduction.rst b/docs/source/distutils/introduction.rst --- a/docs/source/distutils/introduction.rst +++ b/docs/source/distutils/introduction.rst @@ -4,43 +4,42 @@ An Introduction to Distutils2 ***************************** -This document covers using Distutils2 to distribute your Python modules, -concentrating on the role of developer/distributor; if you're looking for -information on installing Python modules, you should refer to the +This document covers using Distutils2 to distribute your Python modules +concentrating on the role of developer/distributor. If you're looking for +information on installing Python modules you should refer to the :ref:`install-index` chapter. Throughout this documentation, the terms "Distutils", "the Distutils" and -"Distutils2" will be used with the same meaning. +"Distutils2" will be used interchangeably. .. _distutils-concepts: Concepts & Terminology ====================== -Using the Distutils is quite simple, both for module developers and for +Using Distutils is quite simple both for module developers and for users/administrators installing third-party modules. As a developer, your responsibilities (apart from writing solid, well-documented and well-tested code, of course!) are: -* write a setup script (:file:`setup.py` by convention) +* writing a setup script (:file:`setup.py` by convention) -* (optional) write a setup configuration file +* (optional) writing a setup configuration file -* create a source distribution +* creating a source distribution -* (optional) create one or more built (binary) distributions +* (optional) creating one or more "built" (binary) distributions of your project -Each of these tasks is covered in this document. +Each of these tasks are covered in this document. -Not all module developers have access to a multitude of platforms, so it's not -always feasible to expect them to create a multitude of built distributions. It -is hoped that a class of intermediaries, called *packagers*, will arise to -address this need. Packagers will take source distributions released by module -developers, build them on one or more platforms, and release the resulting built -distributions. Thus, users on the most popular platforms will be able to -install most popular Python module distributions in the most natural way for -their platform, without having to run a single setup script or compile a line of -code. +Not all module developers have access to multiple platforms, so one cannot +expect them to create builds for every platform. To remedy this, it is hoped +that intermediaries called *packagers* will arise to address this need. +Packagers take source distributions released by module developers, +build them on one or more platforms and release the resulting built +distributions. Thus users on a greater range of platforms will be able to +install the most popular Python modules in the most natural way for their +platform without having to run a setup script or compile a single line of code. .. _distutils-simple-example: @@ -48,15 +47,15 @@ A Simple Example ================ -The setup script is usually quite simple, although since it's written in Python, +A setup script is usually quite simple, although since it's written in Python there are no arbitrary limits to what you can do with it, though you should be -careful about putting arbitrarily expensive operations in your setup script. -Unlike, say, Autoconf-style configure scripts, the setup script may be run -multiple times in the course of building and installing your module +careful about putting expensive operations in your setup script. +Unlike, say, Autoconf-style configure scripts the setup script may be run +multiple times in the course of building and installing a module distribution. If all you want to do is distribute a module called :mod:`foo`, contained in a -file :file:`foo.py`, then your setup script can be as simple as this:: +file :file:`foo.py`, then your setup script can be as simple as:: from distutils2.core import setup setup(name='foo', @@ -69,18 +68,18 @@ arguments to the :func:`setup` function * those keyword arguments fall into two categories: package metadata (name, - version number) and information about what's in the package (a list of pure - Python modules, in this case) + version number, etc.) and information about what's in the package (a list + of pure Python modules in this case) * modules are specified by module name, not filename (the same will hold true for packages and extensions) -* it's recommended that you supply a little more metadata, in particular your - name, email address and a URL for the project (see section :ref:`setup-script` - for an example) +* it's recommended that you supply a little more metadata than we have in the + example. In particular your name, email address and a URL for the + project if appropriate (see section :ref:`setup-script` for an example) -To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +To create a source distribution for this module you would create a setup +script, :file:`setup.py`, containing the above code and run:: python setup.py sdist @@ -89,32 +88,32 @@ The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. -If an end-user wishes to install your :mod:`foo` module, all she has to do is -download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and---from the -:file:`foo-1.0` directory---run :: +If an end-user wishes to install your :mod:`foo` module all he has to do is +download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and from the +:file:`foo-1.0` directory run :: python setup.py install -which will ultimately copy :file:`foo.py` to the appropriate directory for +which will copy :file:`foo.py` to the appropriate directory for third-party modules in their Python installation. -This simple example demonstrates some fundamental concepts of the Distutils. +This simple example demonstrates some fundamental concepts of Distutils. First, both developers and installers have the same basic user interface, i.e. the setup script. The difference is which Distutils *commands* they use: the :command:`sdist` command is almost exclusively for module developers, while -:command:`install` is more often for installers (although most developers will -want to install their own code occasionally). +:command:`install` is more often used by installers (although some developers +will want to install their own code occasionally). -If you want to make things really easy for your users, you can create one or -more built distributions for them. For instance, if you are running on a -Windows machine, and want to make things easy for other Windows users, you can +If you want to make things really easy for your users, you can create more +than one built distributions for them. For instance, if you are running on a +Windows machine and want to make things easy for other Windows users, you can create an executable installer (the most appropriate type of built distribution for this platform) with the :command:`bdist_wininst` command. For example:: python setup.py bdist_wininst will create an executable installer, :file:`foo-1.0.win32.exe`, in the current -directory. You can find out what distribution formats are available at any time +directory. You can find out what distribution formats are available at any time by running :: python setup.py bdist --help-formats @@ -125,42 +124,42 @@ General Python terminology ========================== -If you're reading this document, you probably have a good idea of what modules, -extensions, and so forth are. Nevertheless, just to be sure that everyone is -operating from a common starting point, we offer the following glossary of -common Python terms: +If you're reading this document, you probably have a good idea of what Python +modules, extensions and so forth are. Nevertheless, just to be sure that +everyone is on the same page, here's a quick overview of Python terms: module - the basic unit of code reusability in Python: a block of code imported by some - other code. Three types of modules concern us here: pure Python modules, - extension modules, and packages. + The basic unit of code reusability in Python: a block of code imported by + some other code. Three types of modules are important to us here: pure + Python modules, extension modules and packages. pure Python module - a module written in Python and contained in a single :file:`.py` file (and - possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes referred - to as a "pure module." + A module written in Python and contained in a single :file:`.py` file (and + possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes + referred to as a "pure module." extension module - a module written in the low-level language of the Python implementation: C/C++ - for Python, Java for Jython. Typically contained in a single dynamically - loadable pre-compiled file, e.g. a shared object (:file:`.so`) file for Python + A module written in the low-level language of the Python implementation: C/C++ + for Python, Java for Jython. Typically contained in a single dynamically + loaded pre-compiled file, e.g. a shared object (:file:`.so`) file for Python extensions on Unix, a DLL (given the :file:`.pyd` extension) for Python - extensions on Windows, or a Java class file for Jython extensions. (Note that - currently, the Distutils only handles C/C++ extensions for Python.) + extensions on Windows, or a Java class file for Jython extensions. Note that + currently Distutils only handles C/C++ extensions for Python. package - a module that contains other modules; typically contained in a directory in the - filesystem and distinguished from other directories by the presence of a file - :file:`__init__.py`. + A module that contains other modules, typically contained in a directory of + the filesystem and distinguished from other directories by the presence of a + file :file:`__init__.py`. root package - the root of the hierarchy of packages. (This isn't really a package, since it - doesn't have an :file:`__init__.py` file. But we have to call it something.) - The vast majority of the standard library is in the root package, as are many - small, standalone third-party modules that don't belong to a larger module - collection. Unlike regular packages, modules in the root package can be found in - many directories: in fact, every directory listed in ``sys.path`` contributes - modules to the root package. + The root of the hierarchy of packages. (This isn't really a package, + since it doesn't have an :file:`__init__.py` file. But... we have to + call it something, right?) The vast majority of the standard library is + in the root package, as are many small standalone third-party modules that + don't belong to a larger module collection. Unlike regular packages, + modules in the root package can be found in many directories: in fact, + every directory listed in ``sys.path`` contributes modules to the root + package. .. _distutils-term: @@ -169,25 +168,25 @@ ============================== The following terms apply more specifically to the domain of distributing Python -modules using the Distutils: +modules using Distutils: module distribution - a collection of Python modules distributed together as a single downloadable - resource and meant to be installed *en masse*. Examples of some well-known + A collection of Python modules distributed together as a single downloadable + resource and meant to be installed all as one. Examples of some well-known module distributions are Numeric Python, PyXML, PIL (the Python Imaging - Library), or mxBase. (This would be called a *package*, except that term is - already taken in the Python context: a single module distribution may contain - zero, one, or many Python packages.) + Library) or mxBase. (Module distributions would be called a *package*, + except that term is already taken in the Python context: a single module + distribution may contain zero, one, or many Python packages.) pure module distribution - a module distribution that contains only pure Python modules and packages. + A module distribution that contains only pure Python modules and packages. Sometimes referred to as a "pure distribution." non-pure module distribution - a module distribution that contains at least one extension module. Sometimes + A module distribution that contains at least one extension module. Sometimes referred to as a "non-pure distribution." distribution root - the top-level directory of your source tree (or source distribution); the - directory where :file:`setup.py` exists. Generally :file:`setup.py` will be - run from this directory. + The top-level directory of your source tree (or source distribution). The + directory where :file:`setup.py` exists. Generally :file:`setup.py` will + be run from this directory. diff --git a/docs/source/distutils/setupscript.rst b/docs/source/distutils/setupscript.rst --- a/docs/source/distutils/setupscript.rst +++ b/docs/source/distutils/setupscript.rst @@ -5,12 +5,12 @@ ************************ The setup script is the center of all activity in building, distributing, and -installing modules using the Distutils. The main purpose of the setup script is -to describe your module distribution to the Distutils, so that the various +installing modules using Distutils. The main purpose of the setup script is +to describe your module distribution to Distutils, so that the various commands that operate on your modules do the right thing. As we saw in section -:ref:`distutils-simple-example` above, the setup script consists mainly of a -call to :func:`setup`, and most information supplied to the Distutils by the -module developer is supplied as keyword arguments to :func:`setup`. +:ref:`distutils-simple-example`, the setup script consists mainly of a +call to :func:`setup` where the most information is supplied as +keyword arguments to :func:`setup`. Here's a slightly more involved example, which we'll follow for the next couple of sections: a setup script that could be used for Distutils2 itself:: @@ -32,8 +32,8 @@ There are only two differences between this and the trivial one-file distribution presented in section :ref:`distutils-simple-example`: more -metadata, and the specification of pure Python modules by package, rather than -by module. This is important since the Distutils consist of a couple of dozen +metadata and the specification of pure Python modules by package rather than +by module. This is important since Ristutils consist of a couple of dozen modules split into (so far) two packages; an explicit list of every module would be tedious to generate and difficult to maintain. For more information on the additional metadata, see section :ref:`metadata`. -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: cleanup to prevent test_index_simple failures Message-ID: tarek.ziade pushed 7df97ca68db6 to distutils2: http://hg.python.org/distutils2/rev/7df97ca68db6 changeset: 711:7df97ca68db6 parent: 704:2df39aaf6833 user: Nicolas Cadou date: Wed Sep 29 23:45:35 2010 -0400 summary: cleanup to prevent test_index_simple failures files: distutils2/tests/test_test.py diff --git a/distutils2/tests/test_test.py b/distutils2/tests/test_test.py --- a/distutils2/tests/test_test.py +++ b/distutils2/tests/test_test.py @@ -12,6 +12,7 @@ from distutils2.tests.support import unittest, TempdirManager from distutils2.command.test import test from distutils2.dist import Distribution +from distutils2._backport import pkgutil try: any @@ -39,6 +40,7 @@ os.environ['PYTHONPATH'] = distutils2path + os.pathsep + self.old_pythonpath def tearDown(self): + pkgutil.clear_cache() os.environ['PYTHONPATH'] = self.old_pythonpath super(TestTest, self).tearDown() -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Edited distutils/introduction.rst Spiffy happy things have been improved in Message-ID: tarek.ziade pushed fecc322c15f3 to distutils2: http://hg.python.org/distutils2/rev/fecc322c15f3 changeset: 708:fecc322c15f3 parent: 697:12c37807f046 user: Derek McTavish Mounce date: Wed Sep 29 22:43:40 2010 -0400 summary: Edited distutils/introduction.rst Spiffy happy things have been improved in the English. files: docs/source/distutils/introduction.rst diff --git a/docs/source/distutils/introduction.rst b/docs/source/distutils/introduction.rst --- a/docs/source/distutils/introduction.rst +++ b/docs/source/distutils/introduction.rst @@ -4,43 +4,42 @@ An Introduction to Distutils2 ***************************** -This document covers using Distutils2 to distribute your Python modules, -concentrating on the role of developer/distributor; if you're looking for -information on installing Python modules, you should refer to the +This document covers using Distutils2 to distribute your Python modules +concentrating on the role of developer/distributor. If you're looking for +information on installing Python modules you should refer to the :ref:`install-index` chapter. Throughout this documentation, the terms "Distutils", "the Distutils" and -"Distutils2" will be used with the same meaning. +"Distutils2" will be used interchangeably. .. _distutils-concepts: Concepts & Terminology ====================== -Using the Distutils is quite simple, both for module developers and for +Using Distutils is quite simple both for module developers and for users/administrators installing third-party modules. As a developer, your responsibilities (apart from writing solid, well-documented and well-tested code, of course!) are: -* write a setup script (:file:`setup.py` by convention) +* writing a setup script (:file:`setup.py` by convention) -* (optional) write a setup configuration file +* (optional) writing a setup configuration file -* create a source distribution +* creating a source distribution -* (optional) create one or more built (binary) distributions +* (optional) creating one or more "built" (binary) distributions of your project -Each of these tasks is covered in this document. +Each of these tasks are covered in this document. -Not all module developers have access to a multitude of platforms, so it's not -always feasible to expect them to create a multitude of built distributions. It -is hoped that a class of intermediaries, called *packagers*, will arise to -address this need. Packagers will take source distributions released by module -developers, build them on one or more platforms, and release the resulting built -distributions. Thus, users on the most popular platforms will be able to -install most popular Python module distributions in the most natural way for -their platform, without having to run a single setup script or compile a line of -code. +Not all module developers have access to multiple platforms, so one cannot +expect them to create builds for every platform. To remedy this, it is hoped +that intermediaries called *packagers* will arise to address this need. +Packagers take source distributions released by module developers, +build them on one or more platforms and release the resulting built +distributions. Thus users on a greater range of platforms will be able to +install the most popular Python modules in the most natural way for their +platform without having to run a setup script or compile a single line of code. .. _distutils-simple-example: @@ -48,15 +47,15 @@ A Simple Example ================ -The setup script is usually quite simple, although since it's written in Python, +A setup script is usually quite simple, although since it's written in Python there are no arbitrary limits to what you can do with it, though you should be -careful about putting arbitrarily expensive operations in your setup script. -Unlike, say, Autoconf-style configure scripts, the setup script may be run -multiple times in the course of building and installing your module +careful about putting expensive operations in your setup script. +Unlike, say, Autoconf-style configure scripts the setup script may be run +multiple times in the course of building and installing a module distribution. If all you want to do is distribute a module called :mod:`foo`, contained in a -file :file:`foo.py`, then your setup script can be as simple as this:: +file :file:`foo.py`, then your setup script can be as simple as:: from distutils2.core import setup setup(name='foo', @@ -69,18 +68,18 @@ arguments to the :func:`setup` function * those keyword arguments fall into two categories: package metadata (name, - version number) and information about what's in the package (a list of pure - Python modules, in this case) + version number, etc.) and information about what's in the package (a list + of pure Python modules in this case) * modules are specified by module name, not filename (the same will hold true for packages and extensions) -* it's recommended that you supply a little more metadata, in particular your - name, email address and a URL for the project (see section :ref:`setup-script` - for an example) +* it's recommended that you supply a little more metadata than we have in the + example. In particular your name, email address and a URL for the + project if appropriate (see section :ref:`setup-script` for an example) -To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +To create a source distribution for this module you would create a setup +script, :file:`setup.py`, containing the above code and run:: python setup.py sdist @@ -89,32 +88,32 @@ The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. -If an end-user wishes to install your :mod:`foo` module, all she has to do is -download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and---from the -:file:`foo-1.0` directory---run :: +If an end-user wishes to install your :mod:`foo` module all he has to do is +download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and from the +:file:`foo-1.0` directory run :: python setup.py install -which will ultimately copy :file:`foo.py` to the appropriate directory for +which will copy :file:`foo.py` to the appropriate directory for third-party modules in their Python installation. -This simple example demonstrates some fundamental concepts of the Distutils. +This simple example demonstrates some fundamental concepts of Distutils. First, both developers and installers have the same basic user interface, i.e. the setup script. The difference is which Distutils *commands* they use: the :command:`sdist` command is almost exclusively for module developers, while -:command:`install` is more often for installers (although most developers will -want to install their own code occasionally). +:command:`install` is more often used by installers (although some developers +will want to install their own code occasionally). -If you want to make things really easy for your users, you can create one or -more built distributions for them. For instance, if you are running on a -Windows machine, and want to make things easy for other Windows users, you can +If you want to make things really easy for your users, you can create more +than one built distributions for them. For instance, if you are running on a +Windows machine and want to make things easy for other Windows users, you can create an executable installer (the most appropriate type of built distribution for this platform) with the :command:`bdist_wininst` command. For example:: python setup.py bdist_wininst will create an executable installer, :file:`foo-1.0.win32.exe`, in the current -directory. You can find out what distribution formats are available at any time +directory. You can find out what distribution formats are available at any time by running :: python setup.py bdist --help-formats @@ -125,42 +124,42 @@ General Python terminology ========================== -If you're reading this document, you probably have a good idea of what modules, -extensions, and so forth are. Nevertheless, just to be sure that everyone is -operating from a common starting point, we offer the following glossary of -common Python terms: +If you're reading this document, you probably have a good idea of what Python +modules, extensions and so forth are. Nevertheless, just to be sure that +everyone is on the same page, here's a quick overview of Python terms: module - the basic unit of code reusability in Python: a block of code imported by some - other code. Three types of modules concern us here: pure Python modules, - extension modules, and packages. + The basic unit of code reusability in Python: a block of code imported by + some other code. Three types of modules are important to us here: pure + Python modules, extension modules and packages. pure Python module - a module written in Python and contained in a single :file:`.py` file (and - possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes referred - to as a "pure module." + A module written in Python and contained in a single :file:`.py` file (and + possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes + referred to as a "pure module." extension module - a module written in the low-level language of the Python implementation: C/C++ - for Python, Java for Jython. Typically contained in a single dynamically - loadable pre-compiled file, e.g. a shared object (:file:`.so`) file for Python + A module written in the low-level language of the Python implementation: C/C++ + for Python, Java for Jython. Typically contained in a single dynamically + loaded pre-compiled file, e.g. a shared object (:file:`.so`) file for Python extensions on Unix, a DLL (given the :file:`.pyd` extension) for Python - extensions on Windows, or a Java class file for Jython extensions. (Note that - currently, the Distutils only handles C/C++ extensions for Python.) + extensions on Windows, or a Java class file for Jython extensions. Note that + currently Distutils only handles C/C++ extensions for Python. package - a module that contains other modules; typically contained in a directory in the - filesystem and distinguished from other directories by the presence of a file - :file:`__init__.py`. + A module that contains other modules, typically contained in a directory of + the filesystem and distinguished from other directories by the presence of a + file :file:`__init__.py`. root package - the root of the hierarchy of packages. (This isn't really a package, since it - doesn't have an :file:`__init__.py` file. But we have to call it something.) - The vast majority of the standard library is in the root package, as are many - small, standalone third-party modules that don't belong to a larger module - collection. Unlike regular packages, modules in the root package can be found in - many directories: in fact, every directory listed in ``sys.path`` contributes - modules to the root package. + The root of the hierarchy of packages. (This isn't really a package, + since it doesn't have an :file:`__init__.py` file. But... we have to + call it something, right?) The vast majority of the standard library is + in the root package, as are many small standalone third-party modules that + don't belong to a larger module collection. Unlike regular packages, + modules in the root package can be found in many directories: in fact, + every directory listed in ``sys.path`` contributes modules to the root + package. .. _distutils-term: @@ -169,25 +168,25 @@ ============================== The following terms apply more specifically to the domain of distributing Python -modules using the Distutils: +modules using Distutils: module distribution - a collection of Python modules distributed together as a single downloadable - resource and meant to be installed *en masse*. Examples of some well-known + A collection of Python modules distributed together as a single downloadable + resource and meant to be installed all as one. Examples of some well-known module distributions are Numeric Python, PyXML, PIL (the Python Imaging - Library), or mxBase. (This would be called a *package*, except that term is - already taken in the Python context: a single module distribution may contain - zero, one, or many Python packages.) + Library) or mxBase. (Module distributions would be called a *package*, + except that term is already taken in the Python context: a single module + distribution may contain zero, one, or many Python packages.) pure module distribution - a module distribution that contains only pure Python modules and packages. + A module distribution that contains only pure Python modules and packages. Sometimes referred to as a "pure distribution." non-pure module distribution - a module distribution that contains at least one extension module. Sometimes + A module distribution that contains at least one extension module. Sometimes referred to as a "non-pure distribution." distribution root - the top-level directory of your source tree (or source distribution); the - directory where :file:`setup.py` exists. Generally :file:`setup.py` will be - run from this directory. + The top-level directory of your source tree (or source distribution). The + directory where :file:`setup.py` exists. Generally :file:`setup.py` will + be run from this directory. -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Did a little editing. Message-ID: tarek.ziade pushed 7291a92d6de3 to distutils2: http://hg.python.org/distutils2/rev/7291a92d6de3 changeset: 709:7291a92d6de3 user: Derek McTavish Mounce date: Wed Sep 29 23:24:43 2010 -0400 summary: Did a little editing. files: docs/source/distutils/setupscript.rst diff --git a/docs/source/distutils/setupscript.rst b/docs/source/distutils/setupscript.rst --- a/docs/source/distutils/setupscript.rst +++ b/docs/source/distutils/setupscript.rst @@ -5,12 +5,12 @@ ************************ The setup script is the center of all activity in building, distributing, and -installing modules using the Distutils. The main purpose of the setup script is -to describe your module distribution to the Distutils, so that the various +installing modules using Distutils. The main purpose of the setup script is +to describe your module distribution to Distutils, so that the various commands that operate on your modules do the right thing. As we saw in section -:ref:`distutils-simple-example` above, the setup script consists mainly of a -call to :func:`setup`, and most information supplied to the Distutils by the -module developer is supplied as keyword arguments to :func:`setup`. +:ref:`distutils-simple-example`, the setup script consists mainly of a +call to :func:`setup` where the most information is supplied as +keyword arguments to :func:`setup`. Here's a slightly more involved example, which we'll follow for the next couple of sections: a setup script that could be used for Distutils2 itself:: @@ -32,8 +32,8 @@ There are only two differences between this and the trivial one-file distribution presented in section :ref:`distutils-simple-example`: more -metadata, and the specification of pure Python modules by package, rather than -by module. This is important since the Distutils consist of a couple of dozen +metadata and the specification of pure Python modules by package rather than +by module. This is important since Ristutils consist of a couple of dozen modules split into (so far) two packages; an explicit list of every module would be tedious to generate and difficult to maintain. For more information on the additional metadata, see section :ref:`metadata`. -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: Automated merge with https://bitbucket.org/mtlpython/distutils2 Message-ID: tarek.ziade pushed 219ea202e74b to distutils2: http://hg.python.org/distutils2/rev/219ea202e74b changeset: 712:219ea202e74b parent: 710:db86d137f3dd parent: 711:7df97ca68db6 user: Nicolas Cadou date: Wed Sep 29 23:45:51 2010 -0400 summary: Automated merge with https://bitbucket.org/mtlpython/distutils2 files: diff --git a/distutils2/tests/test_test.py b/distutils2/tests/test_test.py --- a/distutils2/tests/test_test.py +++ b/distutils2/tests/test_test.py @@ -12,6 +12,7 @@ from distutils2.tests.support import unittest, TempdirManager from distutils2.command.test import test from distutils2.dist import Distribution +from distutils2._backport import pkgutil try: any @@ -39,6 +40,7 @@ os.environ['PYTHONPATH'] = distutils2path + os.pathsep + self.old_pythonpath def tearDown(self): + pkgutil.clear_cache() os.environ['PYTHONPATH'] = self.old_pythonpath super(TestTest, self).tearDown() -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: added the name Montr?al-Python sprinters who got to commit some code Message-ID: tarek.ziade pushed 38d869d48447 to distutils2: http://hg.python.org/distutils2/rev/38d869d48447 changeset: 714:38d869d48447 user: Yannick Gingras date: Thu Sep 30 05:02:37 2010 -0400 summary: added the name Montr?al-Python sprinters who got to commit some code files: CONTRIBUTORS.txt diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -9,6 +9,7 @@ Thanks to: +- Rajiv Abraham - Ali Afshar - ??ric Araujo - Pior Bastida @@ -19,12 +20,15 @@ - Josip Djolonga - Yannick Gingras - Jeremy Kloth +- Amos Latteier - Martin von L??wis - Carl Meyer - Alexis M??taireau - Zubin Mithra +- Derek McTavish Mounce - Michael Mulich - George Peristerakis +- Mathieu Perreault - Sean Reifschneider - Antoine Reversat - Luis Rojas -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:19 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:19 +0200 Subject: [Python-checkins] distutils2: refactored unittest import logic to improve accuracy of the coverage measurement Message-ID: tarek.ziade pushed 2916c65826c3 to distutils2: http://hg.python.org/distutils2/rev/2916c65826c3 changeset: 713:2916c65826c3 user: Yannick Gingras date: Thu Sep 30 04:47:45 2010 -0400 summary: refactored unittest import logic to improve accuracy of the coverage measurement files: distutils2/tests/__init__.py, distutils2/tests/pypi_server.py, distutils2/tests/support.py, distutils2/tests/test_Mixin2to3.py, distutils2/tests/test_bdist.py, distutils2/tests/test_bdist_dumb.py, distutils2/tests/test_bdist_msi.py, distutils2/tests/test_bdist_wininst.py, distutils2/tests/test_build.py, distutils2/tests/test_build_clib.py, distutils2/tests/test_build_ext.py, distutils2/tests/test_build_py.py, distutils2/tests/test_build_scripts.py, distutils2/tests/test_ccompiler.py, distutils2/tests/test_check.py, distutils2/tests/test_clean.py, distutils2/tests/test_cmd.py, distutils2/tests/test_config.py, distutils2/tests/test_config_cmd.py, distutils2/tests/test_core.py, distutils2/tests/test_cygwinccompiler.py, distutils2/tests/test_depgraph.py, distutils2/tests/test_dist.py, distutils2/tests/test_emxccompiler.py, distutils2/tests/test_extension.py, distutils2/tests/test_index_dist.py, distutils2/tests/test_index_simple.py, distutils2/tests/test_index_xmlrpc.py, distutils2/tests/test_install.py, distutils2/tests/test_install_data.py, distutils2/tests/test_install_distinfo.py, distutils2/tests/test_install_headers.py, distutils2/tests/test_install_lib.py, distutils2/tests/test_install_scripts.py, distutils2/tests/test_install_tools.py, distutils2/tests/test_manifest.py, distutils2/tests/test_metadata.py, distutils2/tests/test_msvc9compiler.py, distutils2/tests/test_pypi_server.py, distutils2/tests/test_pypi_versions.py, distutils2/tests/test_register.py, distutils2/tests/test_sdist.py, distutils2/tests/test_test.py, distutils2/tests/test_unixccompiler.py, distutils2/tests/test_upload.py, distutils2/tests/test_upload_docs.py, distutils2/tests/test_util.py, distutils2/tests/test_version.py, runtests-cov.py diff --git a/distutils2/tests/__init__.py b/distutils2/tests/__init__.py --- a/distutils2/tests/__init__.py +++ b/distutils2/tests/__init__.py @@ -10,15 +10,22 @@ 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). +Always import unittest from this module, it will be the right version +(standard library unittest for 3.2 and higher, third-party unittest2 +release for older versions). + +Utility code is included in distutils2.tests.support. """ import os import sys -from distutils2.tests.support import unittest + +if sys.version_info >= (3, 2): + # improved unittest package from 3.2's standard library + import unittest +else: + # external release of same package for older versions + import unittest2 as unittest from test.test_support import TESTFN # use TESTFN from stdlib/test_support. diff --git a/distutils2/tests/pypi_server.py b/distutils2/tests/pypi_server.py --- a/distutils2/tests/pypi_server.py +++ b/distutils2/tests/pypi_server.py @@ -40,7 +40,7 @@ from SimpleHTTPServer import SimpleHTTPRequestHandler from SimpleXMLRPCServer import SimpleXMLRPCServer -from distutils2.tests.support import unittest +from distutils2.tests import unittest PYPI_DEFAULT_STATIC_PATH = os.path.dirname(os.path.abspath(__file__)) + "/pypiserver" diff --git a/distutils2/tests/support.py b/distutils2/tests/support.py --- a/distutils2/tests/support.py +++ b/distutils2/tests/support.py @@ -1,14 +1,10 @@ """Support code for distutils2 test cases. -Always import unittest from this module, it will be the right version -(standard library unittest for 3.2 and higher, third-party unittest2 -release for older versions). - Four helper classes are provided: LoggingCatcher, TempdirManager, EnvironGuard and WarningsCatcher. They are written to be used as mixins, e.g. :: - from distutils2.tests.support import unittest + from distutils2.tests import unittest from distutils2.tests.support import LoggingCatcher class SomeTestCase(LoggingCatcher, unittest.TestCase): @@ -37,13 +33,7 @@ from distutils2 import log from distutils2.dist import Distribution from distutils2.log import DEBUG, INFO, WARN, ERROR, FATAL - -if sys.version_info >= (3, 2): - # improved unittest package from 3.2's standard library - import unittest -else: - # external release of same package for older versions - import unittest2 as unittest +from distutils2.tests import unittest __all__ = ['LoggingCatcher', 'WarningsCatcher', 'TempdirManager', 'EnvironGuard', 'DummyCommand', 'unittest'] diff --git a/distutils2/tests/test_Mixin2to3.py b/distutils2/tests/test_Mixin2to3.py --- a/distutils2/tests/test_Mixin2to3.py +++ b/distutils2/tests/test_Mixin2to3.py @@ -3,8 +3,7 @@ import logging import distutils2 -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2.compat import Mixin2to3 diff --git a/distutils2/tests/test_bdist.py b/distutils2/tests/test_bdist.py --- a/distutils2/tests/test_bdist.py +++ b/distutils2/tests/test_bdist.py @@ -6,8 +6,7 @@ from distutils2.core import Distribution from distutils2.command.bdist import bdist -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2.util import find_executable from distutils2.errors import DistutilsExecError diff --git a/distutils2/tests/test_bdist_dumb.py b/distutils2/tests/test_bdist_dumb.py --- a/distutils2/tests/test_bdist_dumb.py +++ b/distutils2/tests/test_bdist_dumb.py @@ -10,8 +10,7 @@ except ImportError: zlib = None -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import run_unittest, unittest from distutils2.core import Distribution from distutils2.command.bdist_dumb import bdist_dumb diff --git a/distutils2/tests/test_bdist_msi.py b/distutils2/tests/test_bdist_msi.py --- a/distutils2/tests/test_bdist_msi.py +++ b/distutils2/tests/test_bdist_msi.py @@ -3,8 +3,7 @@ from distutils2.tests import run_unittest -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class BDistMSITestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_bdist_wininst.py b/distutils2/tests/test_bdist_wininst.py --- a/distutils2/tests/test_bdist_wininst.py +++ b/distutils2/tests/test_bdist_wininst.py @@ -1,10 +1,7 @@ """Tests for distutils.command.bdist_wininst.""" -from distutils2.tests import run_unittest - +from distutils2.tests import unittest, support, 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.LoggingCatcher, diff --git a/distutils2/tests/test_build.py b/distutils2/tests/test_build.py --- a/distutils2/tests/test_build.py +++ b/distutils2/tests/test_build.py @@ -3,8 +3,7 @@ import sys from distutils2.command.build import build -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support try: from sysconfig import get_platform except ImportError: diff --git a/distutils2/tests/test_build_clib.py b/distutils2/tests/test_build_clib.py --- a/distutils2/tests/test_build_clib.py +++ b/distutils2/tests/test_build_clib.py @@ -4,9 +4,8 @@ from distutils2.command.build_clib import build_clib from distutils2.errors import DistutilsSetupError -from distutils2.tests import support +from distutils2.tests import unittest, support from distutils2.util import find_executable -from distutils2.tests.support import unittest class BuildCLibTestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_build_ext.py b/distutils2/tests/test_build_ext.py --- a/distutils2/tests/test_build_ext.py +++ b/distutils2/tests/test_build_ext.py @@ -4,7 +4,7 @@ from StringIO import StringIO import distutils2.tests -from distutils2.tests.support import unittest +from distutils2.tests import unittest from distutils2.core import Extension, Distribution from distutils2.command.build_ext import build_ext from distutils2.tests import support diff --git a/distutils2/tests/test_build_py.py b/distutils2/tests/test_build_py.py --- a/distutils2/tests/test_build_py.py +++ b/distutils2/tests/test_build_py.py @@ -8,8 +8,7 @@ from distutils2.core import Distribution from distutils2.errors import DistutilsFileError -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class BuildPyTestCase(support.TempdirManager, diff --git a/distutils2/tests/test_build_scripts.py b/distutils2/tests/test_build_scripts.py --- a/distutils2/tests/test_build_scripts.py +++ b/distutils2/tests/test_build_scripts.py @@ -9,8 +9,7 @@ except ImportError: from distutils2._backport import sysconfig -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class BuildScriptsTestCase(support.TempdirManager, diff --git a/distutils2/tests/test_ccompiler.py b/distutils2/tests/test_ccompiler.py --- a/distutils2/tests/test_ccompiler.py +++ b/distutils2/tests/test_ccompiler.py @@ -4,8 +4,7 @@ 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 +from distutils2.tests import unittest, support class FakeCompiler(object): def library_dir_option(self, dir): diff --git a/distutils2/tests/test_check.py b/distutils2/tests/test_check.py --- a/distutils2/tests/test_check.py +++ b/distutils2/tests/test_check.py @@ -2,8 +2,7 @@ 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.tests import unittest, support from distutils2.errors import DistutilsSetupError class CheckTestCase(support.LoggingCatcher, diff --git a/distutils2/tests/test_clean.py b/distutils2/tests/test_clean.py --- a/distutils2/tests/test_clean.py +++ b/distutils2/tests/test_clean.py @@ -1,11 +1,8 @@ """Tests for distutils.command.clean.""" -import sys import os -import getpass from distutils2.command.clean import clean -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class cleanTestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_cmd.py b/distutils2/tests/test_cmd.py --- a/distutils2/tests/test_cmd.py +++ b/distutils2/tests/test_cmd.py @@ -5,7 +5,7 @@ from distutils2.command.cmd import Command from distutils2.dist import Distribution from distutils2.errors import DistutilsOptionError -from distutils2.tests.support import unittest +from distutils2.tests import unittest class MyCmd(Command): def initialize_options(self): diff --git a/distutils2/tests/test_config.py b/distutils2/tests/test_config.py --- a/distutils2/tests/test_config.py +++ b/distutils2/tests/test_config.py @@ -3,8 +3,7 @@ import os import copy -from distutils2.tests import support, run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support, run_unittest SETUP_CFG = """ diff --git a/distutils2/tests/test_config_cmd.py b/distutils2/tests/test_config_cmd.py --- a/distutils2/tests/test_config_cmd.py +++ b/distutils2/tests/test_config_cmd.py @@ -3,8 +3,7 @@ import sys from distutils2.command.config import dump_file, config -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2 import log class ConfigTestCase(support.LoggingCatcher, diff --git a/distutils2/tests/test_core.py b/distutils2/tests/test_core.py --- a/distutils2/tests/test_core.py +++ b/distutils2/tests/test_core.py @@ -6,8 +6,7 @@ import shutil import sys from distutils2.tests import captured_stdout -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support # setup script that uses __file__ setup_using___file__ = """\ diff --git a/distutils2/tests/test_cygwinccompiler.py b/distutils2/tests/test_cygwinccompiler.py --- a/distutils2/tests/test_cygwinccompiler.py +++ b/distutils2/tests/test_cygwinccompiler.py @@ -15,8 +15,7 @@ CONFIG_H_UNCERTAIN, get_versions, get_msvcr, RE_VERSION) from distutils2.util import get_compiler_versions -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class CygwinCCompilerTestCase(support.TempdirManager, unittest.TestCase): diff --git a/distutils2/tests/test_depgraph.py b/distutils2/tests/test_depgraph.py --- a/distutils2/tests/test_depgraph.py +++ b/distutils2/tests/test_depgraph.py @@ -1,7 +1,6 @@ """Tests for distutils.depgraph """ -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2 import depgraph from distutils2._backport import pkgutil diff --git a/distutils2/tests/test_dist.py b/distutils2/tests/test_dist.py --- a/distutils2/tests/test_dist.py +++ b/distutils2/tests/test_dist.py @@ -11,8 +11,8 @@ from distutils2.command.cmd import Command from distutils2.errors import DistutilsModuleError, DistutilsOptionError from distutils2.tests import TESTFN, captured_stdout -from distutils2.tests import support -from distutils2.tests.support import unittest, create_distribution +from distutils2.tests import support, unittest +from distutils2.tests.support import create_distribution class test_dist(Command): diff --git a/distutils2/tests/test_emxccompiler.py b/distutils2/tests/test_emxccompiler.py --- a/distutils2/tests/test_emxccompiler.py +++ b/distutils2/tests/test_emxccompiler.py @@ -7,8 +7,7 @@ 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 +from distutils2.tests import unittest, support class EmxCCompilerTestCase(support.TempdirManager, unittest.TestCase): diff --git a/distutils2/tests/test_extension.py b/distutils2/tests/test_extension.py --- a/distutils2/tests/test_extension.py +++ b/distutils2/tests/test_extension.py @@ -2,7 +2,7 @@ import os from distutils2.extension import Extension -from distutils2.tests.support import unittest +from distutils2.tests import unittest class ExtensionTestCase(unittest.TestCase): diff --git a/distutils2/tests/test_index_dist.py b/distutils2/tests/test_index_dist.py --- a/distutils2/tests/test_index_dist.py +++ b/distutils2/tests/test_index_dist.py @@ -4,7 +4,8 @@ from distutils2.tests.pypi_server import use_pypi_server from distutils2.tests import run_unittest -from distutils2.tests.support import unittest, TempdirManager +from distutils2.tests import unittest +from distutils2.tests.support import TempdirManager from distutils2.version import VersionPredicate from distutils2.index.errors import HashDoesNotMatch, UnsupportedHashName from distutils2.index.dist import (ReleaseInfo, ReleasesList, DistInfo, diff --git a/distutils2/tests/test_index_simple.py b/distutils2/tests/test_index_simple.py --- a/distutils2/tests/test_index_simple.py +++ b/distutils2/tests/test_index_simple.py @@ -6,8 +6,7 @@ import urllib2 from distutils2.index.simple import Crawler -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2.tests.pypi_server import (use_pypi_server, PyPIServer, PYPI_DEFAULT_STATIC_PATH) diff --git a/distutils2/tests/test_index_xmlrpc.py b/distutils2/tests/test_index_xmlrpc.py --- a/distutils2/tests/test_index_xmlrpc.py +++ b/distutils2/tests/test_index_xmlrpc.py @@ -1,8 +1,7 @@ """Tests for the distutils2.index.xmlrpc module.""" from distutils2.tests.pypi_server import use_xmlrpc_server -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import unittest, run_unittest from distutils2.index.xmlrpc import Client, InvalidSearchField, ProjectNotFound diff --git a/distutils2/tests/test_install.py b/distutils2/tests/test_install.py --- a/distutils2/tests/test_install.py +++ b/distutils2/tests/test_install.py @@ -17,8 +17,7 @@ from distutils2.core import Distribution from distutils2.errors import DistutilsOptionError -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class InstallTestCase(support.TempdirManager, support.EnvironGuard, diff --git a/distutils2/tests/test_install_data.py b/distutils2/tests/test_install_data.py --- a/distutils2/tests/test_install_data.py +++ b/distutils2/tests/test_install_data.py @@ -4,8 +4,7 @@ import getpass from distutils2.command.install_data import install_data -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class InstallDataTestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_install_distinfo.py b/distutils2/tests/test_install_distinfo.py --- a/distutils2/tests/test_install_distinfo.py +++ b/distutils2/tests/test_install_distinfo.py @@ -7,8 +7,7 @@ from distutils2.command.install_distinfo import install_distinfo from distutils2.core import Command from distutils2.metadata import DistributionMetadata -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support try: import hashlib diff --git a/distutils2/tests/test_install_headers.py b/distutils2/tests/test_install_headers.py --- a/distutils2/tests/test_install_headers.py +++ b/distutils2/tests/test_install_headers.py @@ -4,8 +4,7 @@ import getpass from distutils2.command.install_headers import install_headers -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class InstallHeadersTestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_install_lib.py b/distutils2/tests/test_install_lib.py --- a/distutils2/tests/test_install_lib.py +++ b/distutils2/tests/test_install_lib.py @@ -4,9 +4,8 @@ from distutils2.command.install_lib import install_lib from distutils2.extension import Extension -from distutils2.tests import support +from distutils2.tests import unittest, support from distutils2.errors import DistutilsOptionError -from distutils2.tests.support import unittest try: no_bytecode = sys.dont_write_bytecode diff --git a/distutils2/tests/test_install_scripts.py b/distutils2/tests/test_install_scripts.py --- a/distutils2/tests/test_install_scripts.py +++ b/distutils2/tests/test_install_scripts.py @@ -5,8 +5,7 @@ from distutils2.command.install_scripts import install_scripts from distutils2.core import Distribution -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class InstallScriptsTestCase(support.TempdirManager, diff --git a/distutils2/tests/test_install_tools.py b/distutils2/tests/test_install_tools.py --- a/distutils2/tests/test_install_tools.py +++ b/distutils2/tests/test_install_tools.py @@ -1,8 +1,7 @@ """Tests for the distutils2.index.xmlrpc module.""" from distutils2.tests.pypi_server import use_xmlrpc_server -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import unittest, run_unittest from distutils2.index.xmlrpc import Client from distutils2.install_tools import (get_infos, InstallationException) diff --git a/distutils2/tests/test_manifest.py b/distutils2/tests/test_manifest.py --- a/distutils2/tests/test_manifest.py +++ b/distutils2/tests/test_manifest.py @@ -4,8 +4,7 @@ import logging from distutils2.tests import run_unittest -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2.manifest import Manifest _MANIFEST = """\ diff --git a/distutils2/tests/test_metadata.py b/distutils2/tests/test_metadata.py --- a/distutils2/tests/test_metadata.py +++ b/distutils2/tests/test_metadata.py @@ -6,8 +6,8 @@ from distutils2.metadata import (DistributionMetadata, _interpret, PKG_INFO_PREFERRED_VERSION) -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest, LoggingCatcher +from distutils2.tests import run_unittest, unittest +from distutils2.tests.support import LoggingCatcher from distutils2.errors import (MetadataConflictError, MetadataUnrecognizedVersionError) diff --git a/distutils2/tests/test_msvc9compiler.py b/distutils2/tests/test_msvc9compiler.py --- a/distutils2/tests/test_msvc9compiler.py +++ b/distutils2/tests/test_msvc9compiler.py @@ -3,8 +3,7 @@ import os from distutils2.errors import DistutilsPlatformError -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support _MANIFEST = """\ diff --git a/distutils2/tests/test_pypi_server.py b/distutils2/tests/test_pypi_server.py --- a/distutils2/tests/test_pypi_server.py +++ b/distutils2/tests/test_pypi_server.py @@ -4,7 +4,7 @@ import os.path from distutils2.tests.pypi_server import PyPIServer, PYPI_DEFAULT_STATIC_PATH -from distutils2.tests.support import unittest +from distutils2.tests import unittest class PyPIServerTest(unittest.TestCase): diff --git a/distutils2/tests/test_pypi_versions.py b/distutils2/tests/test_pypi_versions.py --- a/distutils2/tests/test_pypi_versions.py +++ b/distutils2/tests/test_pypi_versions.py @@ -18,8 +18,7 @@ import pickle from distutils2.version import suggest_normalized_version -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import unittest, run_unittest def test_pypi(): # FIXME need a better way to do that diff --git a/distutils2/tests/test_register.py b/distutils2/tests/test_register.py --- a/distutils2/tests/test_register.py +++ b/distutils2/tests/test_register.py @@ -16,9 +16,7 @@ from distutils2.core import Distribution from distutils2.errors import DistutilsSetupError -from distutils2.tests import support -from distutils2.tests.support import unittest - +from distutils2.tests import unittest, support PYPIRC_NOPASSWORD = """\ [distutils] diff --git a/distutils2/tests/test_sdist.py b/distutils2/tests/test_sdist.py --- a/distutils2/tests/test_sdist.py +++ b/distutils2/tests/test_sdist.py @@ -26,7 +26,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 import unittest from distutils2.errors import DistutilsExecError, DistutilsOptionError from distutils2.util import find_executable from distutils2.tests import support diff --git a/distutils2/tests/test_test.py b/distutils2/tests/test_test.py --- a/distutils2/tests/test_test.py +++ b/distutils2/tests/test_test.py @@ -9,7 +9,8 @@ from operator import getitem, setitem, delitem from StringIO import StringIO from distutils2.core import Command -from distutils2.tests.support import unittest, TempdirManager +from distutils2.tests import unittest +from distutils2.tests.support import TempdirManager from distutils2.command.test import test from distutils2.dist import Distribution from distutils2._backport import pkgutil diff --git a/distutils2/tests/test_unixccompiler.py b/distutils2/tests/test_unixccompiler.py --- a/distutils2/tests/test_unixccompiler.py +++ b/distutils2/tests/test_unixccompiler.py @@ -7,7 +7,7 @@ from distutils2._backport import sysconfig from distutils2.compiler.unixccompiler import UnixCCompiler -from distutils2.tests.support import unittest +from distutils2.tests import unittest class UnixCCompilerTestCase(unittest.TestCase): diff --git a/distutils2/tests/test_upload.py b/distutils2/tests/test_upload.py --- a/distutils2/tests/test_upload.py +++ b/distutils2/tests/test_upload.py @@ -6,9 +6,8 @@ from distutils2.command.upload import upload from distutils2.core import Distribution -from distutils2.tests import support +from distutils2.tests import unittest, support from distutils2.tests.pypi_server import PyPIServer, PyPIServerTestCase -from distutils2.tests.support import unittest PYPIRC_NOPASSWORD = """\ diff --git a/distutils2/tests/test_upload_docs.py b/distutils2/tests/test_upload_docs.py --- a/distutils2/tests/test_upload_docs.py +++ b/distutils2/tests/test_upload_docs.py @@ -16,9 +16,8 @@ from distutils2.core import Distribution from distutils2.errors import DistutilsFileError, DistutilsOptionError -from distutils2.tests import support +from distutils2.tests import unittest, support from distutils2.tests.pypi_server import PyPIServer, PyPIServerTestCase -from distutils2.tests.support import unittest EXPECTED_MULTIPART_OUTPUT = "\r\n".join([ diff --git a/distutils2/tests/test_util.py b/distutils2/tests/test_util.py --- a/distutils2/tests/test_util.py +++ b/distutils2/tests/test_util.py @@ -7,7 +7,7 @@ import time from distutils2.tests import captured_stdout -from distutils2.tests.support import unittest +from distutils2.tests import unittest from distutils2.errors import (DistutilsPlatformError, DistutilsByteCompileError, DistutilsFileError, @@ -21,8 +21,7 @@ read_pypirc, resolve_name) from distutils2 import util -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support PYPIRC = """\ diff --git a/distutils2/tests/test_version.py b/distutils2/tests/test_version.py --- a/distutils2/tests/test_version.py +++ b/distutils2/tests/test_version.py @@ -6,7 +6,7 @@ from distutils2.version import HugeMajorVersionNumError, IrrationalVersionError from distutils2.version import suggest_normalized_version as suggest from distutils2.version import VersionPredicate -from distutils2.tests.support import unittest +from distutils2.tests import unittest class VersionTestCase(unittest.TestCase): diff --git a/runtests-cov.py b/runtests-cov.py --- a/runtests-cov.py +++ b/runtests-cov.py @@ -136,7 +136,7 @@ if __name__ == "__main__": try: - import unittest2 + from distutils2.tests import unittest except ImportError: sys.stderr.write('Error: You have to install unittest2\n') sys.exit(1) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Add note to try to prevent test_build_ext failure if Python.h is not found Message-ID: tarek.ziade pushed 1f1c16ace447 to distutils2: http://hg.python.org/distutils2/rev/1f1c16ace447 changeset: 715:1f1c16ace447 parent: 696:efe244b78376 user: ?ric Araujo date: Thu Sep 30 17:45:27 2010 +0200 summary: Add note to try to prevent test_build_ext failure if Python.h is not found files: docs/source/devresources.rst diff --git a/docs/source/devresources.rst b/docs/source/devresources.rst --- a/docs/source/devresources.rst +++ b/docs/source/devresources.rst @@ -13,6 +13,9 @@ ~~~~~~~~~~~~ * unittest2 +* If your operating system splits core python and a python-dev (or -devel) + packages, install the dev package too: It contains header files needed by + tests. Issue Tracker ~~~~~~~~~~~~~ -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Fix a section link Message-ID: tarek.ziade pushed 70aa50ecb5b1 to distutils2: http://hg.python.org/distutils2/rev/70aa50ecb5b1 changeset: 716:70aa50ecb5b1 user: ?ric Araujo date: Thu Sep 30 17:46:09 2010 +0200 summary: Fix a section link files: docs/source/distutils/setupscript.rst diff --git a/docs/source/distutils/setupscript.rst b/docs/source/distutils/setupscript.rst --- a/docs/source/distutils/setupscript.rst +++ b/docs/source/distutils/setupscript.rst @@ -501,7 +501,7 @@ file if no template is provided. See :ref:`manifest`. -.. _distutils2-additional-files: +.. _distutils-additional-files: Installing Additional Files =========================== -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Be compatible with Sphinx 0.6 in addition to 1.0 Message-ID: tarek.ziade pushed cb1b9898d0b8 to distutils2: http://hg.python.org/distutils2/rev/cb1b9898d0b8 changeset: 717:cb1b9898d0b8 user: ?ric Araujo date: Thu Sep 30 17:46:38 2010 +0200 summary: Be compatible with Sphinx 0.6 in addition to 1.0 files: docs/source/conf.py diff --git a/docs/source/conf.py b/docs/source/conf.py --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -12,7 +12,9 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import os +import sys +import sphinx # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -98,7 +100,8 @@ # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -html_theme_options = {'collapsiblesidebar': True} +if sphinx.__version__[:3] >= '1.0': + html_theme_options = {'collapsiblesidebar': True} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Revert PEP 345 field names in setup script Message-ID: tarek.ziade pushed 396786e38222 to distutils2: http://hg.python.org/distutils2/rev/396786e38222 changeset: 718:396786e38222 parent: 714:38d869d48447 user: ?ric Araujo date: Fri Oct 01 19:45:34 2010 +0200 summary: Revert PEP 345 field names in setup script files: setup.py diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -210,14 +210,14 @@ setup(name="Distutils2", version=VERSION, - summary="Python Distribution Utilities", + description="Python Distribution Utilities", keywords=['packaging', 'distutils'], author="Tarek Ziade", author_email="tarek at ziade.org", - home_page="http://bitbucket.org/tarek/distutils2/wiki/Home", + url="http://bitbucket.org/tarek/distutils2/wiki/Home", license="PSF", - description=README, - classifier=_CLASSIFIERS.split('\n'), + long_description=README, + classifiers=_CLASSIFIERS.split('\n'), packages=find_packages(), cmdclass={'sdist_hg': sdist_hg, 'install_hg': install_hg}, package_data={'distutils2._backport': ['sysconfig.cfg']}, -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Restore some commas and do other nitpicks Message-ID: tarek.ziade pushed 2bec2999c824 to distutils2: http://hg.python.org/distutils2/rev/2bec2999c824 changeset: 721:2bec2999c824 user: ?ric Araujo date: Fri Oct 01 20:20:45 2010 +0200 summary: Restore some commas and do other nitpicks files: docs/source/distutils/introduction.rst diff --git a/docs/source/distutils/introduction.rst b/docs/source/distutils/introduction.rst --- a/docs/source/distutils/introduction.rst +++ b/docs/source/distutils/introduction.rst @@ -4,7 +4,7 @@ An Introduction to Distutils2 ***************************** -This document covers using Distutils2 to distribute your Python modules +This document covers using Distutils2 to distribute your Python modules, concentrating on the role of developer/distributor. If you're looking for information on installing Python modules you should refer to the :ref:`install-index` chapter. @@ -28,16 +28,17 @@ * creating a source distribution -* (optional) creating one or more "built" (binary) distributions of your project +* (optional) creating one or more "built" (binary) distributions of your + project -Each of these tasks are covered in this document. +All of these tasks are covered in this document. Not all module developers have access to multiple platforms, so one cannot -expect them to create builds for every platform. To remedy this, it is hoped -that intermediaries called *packagers* will arise to address this need. -Packagers take source distributions released by module developers, +expect them to create buildt distributions for every platform. To remedy +this, it is hoped that intermediaries called *packagers* will arise to address +this need. Packagers take source distributions released by module developers, build them on one or more platforms and release the resulting built -distributions. Thus users on a greater range of platforms will be able to +distributions. Thus, users on a greater range of platforms will be able to install the most popular Python modules in the most natural way for their platform without having to run a setup script or compile a single line of code. -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Fix one XXX from Rajiv Message-ID: tarek.ziade pushed 7af455919bec to distutils2: http://hg.python.org/distutils2/rev/7af455919bec changeset: 722:7af455919bec user: ?ric Araujo date: Fri Oct 01 20:21:46 2010 +0200 summary: Fix one XXX from Rajiv files: distutils2/command/bdist_msi.py diff --git a/distutils2/command/bdist_msi.py b/distutils2/command/bdist_msi.py --- a/distutils2/command/bdist_msi.py +++ b/distutils2/command/bdist_msi.py @@ -259,9 +259,8 @@ self.distribution.dist_files.append(tup) if not self.keep_temp: - if self.dry_run: - pass # XXX - else: + log.info("removing temporary build directory %s", self.bdist_dir) + if not self.dry_run: rmtree(self.bdist_dir) def add_files(self): -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Add PSF license text Message-ID: tarek.ziade pushed 9fef3a218bd4 to distutils2: http://hg.python.org/distutils2/rev/9fef3a218bd4 changeset: 719:9fef3a218bd4 user: ?ric Araujo date: Fri Oct 01 19:47:16 2010 +0200 summary: Add PSF license text files: LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,284 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations (now Zope +Corporation, see http://www.zope.com). In 2001, the Python Software +Foundation (PSF, see http://www.python.org/psf/) was formed, a +non-profit organization created specifically to own Python-related +Intellectual Property. Zope Corporation is a sponsoring member of +the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.2 2.1.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2.1 2.2 2002 PSF yes + 2.2.2 2.2.1 2002 PSF yes + 2.2.3 2.2.2 2003 PSF yes + 2.3 2.2.2 2002-2003 PSF yes + 2.3.1 2.3 2002-2003 PSF yes + 2.3.2 2.3.1 2002-2003 PSF yes + 2.3.3 2.3.2 2002-2003 PSF yes + 2.3.4 2.3.3 2004 PSF yes + 2.3.5 2.3.4 2005 PSF yes + 2.4 2.3 2004 PSF yes + 2.4.1 2.4 2005 PSF yes + 2.4.2 2.4.1 2005 PSF yes + 2.4.3 2.4.2 2006 PSF yes + 2.4.4 2.4.3 2006 PSF yes + 2.5 2.4 2006 PSF yes + 2.5.1 2.5 2007 PSF yes + 2.5.2 2.5.1 2008 PSF yes + 2.5.3 2.5.2 2008 PSF yes + 2.6 2.5 2008 PSF yes + 2.6.1 2.6 2008 PSF yes + 2.6.2 2.6.1 2009 PSF yes + 2.6.3 2.6.2 2009 PSF yes + 2.6.4 2.6.3 2009 PSF yes + 2.6.5 2.6.4 2010 PSF yes + 3.0 2.6 2008 PSF yes + 3.0.1 3.0 2009 PSF yes + 3.1 3.0.1 2009 PSF yes + 3.1.1 3.1 2009 PSF yes + 3.1.2 3.1 2010 PSF yes + 3.2 3.1 2010 PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +Python Software Foundation; All Rights Reserved" are retained in Python alone or +in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the Internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the Internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Add missing pattern to hgignore Message-ID: tarek.ziade pushed 063e882f69b0 to distutils2: http://hg.python.org/distutils2/rev/063e882f69b0 changeset: 720:063e882f69b0 user: ?ric Araujo date: Fri Oct 01 19:47:33 2010 +0200 summary: Add missing pattern to hgignore files: .hgignore diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -7,6 +7,7 @@ build/ dist/ _static/ +_build/ *.swp .coverage .tox -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Branch merge Message-ID: tarek.ziade pushed b917c7e35bb5 to distutils2: http://hg.python.org/distutils2/rev/b917c7e35bb5 changeset: 723:b917c7e35bb5 parent: 722:7af455919bec parent: 717:cb1b9898d0b8 user: ?ric Araujo date: Fri Oct 01 21:03:50 2010 +0200 summary: Branch merge files: distutils2/tests/test_config.py, distutils2/tests/test_register.py, distutils2/tests/test_test.py, docs/source/distutils/setupscript.rst diff --git a/distutils2/tests/test_config.py b/distutils2/tests/test_config.py --- a/distutils2/tests/test_config.py +++ b/distutils2/tests/test_config.py @@ -1,8 +1,9 @@ """Tests for distutils.config.""" +import os import sys -import os -import copy +from StringIO import StringIO +from distutils2.core import setup from distutils2.tests import unittest, support, run_unittest @@ -16,26 +17,23 @@ class ConfigTestCase(support.TempdirManager, unittest.TestCase): + def setUp(self): + super(ConfigTestCase, self).setUp() + self.addCleanup(setattr, sys, 'argv', sys.argv[:]) + self.addCleanup(setattr, sys, 'stdout', sys.stdout) + self.addCleanup(os.chdir, os.getcwd()) + def test_config(self): tempdir = self.mkdtemp() - setup_cfg = os.path.join(tempdir, 'setup.cfg') - f = open(setup_cfg, 'w') - try: - f.write(SETUP_CFG) - finally: - f.close() + os.chdir(tempdir) + self.write_file('setup.cfg', SETUP_CFG) - # trying to load the metadata now - old_args = copy.copy(sys.argv) + # try to load the metadata now + sys.stdout = StringIO() sys.argv[:] = ['setup.py', '--version'] - old_wd = os.getcwd() - os.chdir(tempdir) - try: - from distutils2.core import setup - dist = setup() - finally: - os.chdir(old_wd) - sys.argv[:] = old_args + dist = setup() + # sanity check + self.assertEqual(sys.stdout.getvalue(), '1.0' + os.linesep) # check what was done self.assertEqual(dist.metadata['Author'], 'tarek') diff --git a/distutils2/tests/test_register.py b/distutils2/tests/test_register.py --- a/distutils2/tests/test_register.py +++ b/distutils2/tests/test_register.py @@ -65,7 +65,9 @@ def read(self): return 'xxx' -class RegisterTestCase(support.TempdirManager, support.EnvironGuard, +class RegisterTestCase(support.TempdirManager, + support.EnvironGuard, + support.LoggingCatcher, unittest.TestCase): def setUp(self): diff --git a/distutils2/tests/test_test.py b/distutils2/tests/test_test.py --- a/distutils2/tests/test_test.py +++ b/distutils2/tests/test_test.py @@ -10,7 +10,7 @@ from StringIO import StringIO from distutils2.core import Command from distutils2.tests import unittest -from distutils2.tests.support import TempdirManager +from distutils2.tests.support import TempdirManager, LoggingCatcher from distutils2.command.test import test from distutils2.dist import Distribution from distutils2._backport import pkgutil @@ -31,6 +31,7 @@ here = os.path.dirname(os.path.abspath(__file__)) class TestTest(TempdirManager, + LoggingCatcher, unittest.TestCase): def setUp(self): @@ -76,7 +77,7 @@ orig_has_attr = _hasattr(obj, attr) if orig_has_attr: - orig_val = _getattr(obj, attr) + orig_val = _getattr(obj, attr) if delete is False: _setattr(obj, attr, new_val) diff --git a/docs/source/conf.py b/docs/source/conf.py --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -12,7 +12,9 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import os +import sys +import sphinx # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -98,7 +100,8 @@ # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -html_theme_options = {'collapsiblesidebar': True} +if sphinx.__version__[:3] >= '1.0': + html_theme_options = {'collapsiblesidebar': True} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] diff --git a/docs/source/devresources.rst b/docs/source/devresources.rst --- a/docs/source/devresources.rst +++ b/docs/source/devresources.rst @@ -13,6 +13,9 @@ ~~~~~~~~~~~~ * unittest2 +* If your operating system splits core python and a python-dev (or -devel) + packages, install the dev package too: It contains header files needed by + tests. Issue Tracker ~~~~~~~~~~~~~ diff --git a/docs/source/distutils/setupscript.rst b/docs/source/distutils/setupscript.rst --- a/docs/source/distutils/setupscript.rst +++ b/docs/source/distutils/setupscript.rst @@ -501,7 +501,7 @@ file if no template is provided. See :ref:`manifest`. -.. _distutils2-additional-files: +.. _distutils-additional-files: Installing Additional Files =========================== diff --git a/docs/source/distutils/sourcedist.rst b/docs/source/distutils/sourcedist.rst --- a/docs/source/distutils/sourcedist.rst +++ b/docs/source/distutils/sourcedist.rst @@ -142,7 +142,7 @@ python setup.py sdist --manifest-only -:option:`-o` is a sortcut for :option:`--manifest-only`. +:option:`-o` is a shortcut for :option:`--manifest-only`. .. _manifest_template: -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Branch merge Message-ID: tarek.ziade pushed 45418c55703c to distutils2: http://hg.python.org/distutils2/rev/45418c55703c changeset: 724:45418c55703c parent: 723:b917c7e35bb5 parent: 694:00abdfe2a4bd user: ?ric Araujo date: Fri Oct 01 21:05:26 2010 +0200 summary: Branch merge files: DEVNOTES.txt, runtests-cov.py, runtests.py diff --git a/DEVNOTES.txt b/DEVNOTES.txt --- a/DEVNOTES.txt +++ b/DEVNOTES.txt @@ -7,8 +7,3 @@ - Always run tests.sh before you push a change. This implies that you have all Python versions installed from 2.4 to 2.7. - -- With Python 2.4, if you want to run tests with runtests.py, or run - just one test directly, be sure to run python2.4 setup.py build_ext - first, else tests won't find _hashlib or _md5. When using tests.sh, - build_ext is automatically done. diff --git a/runtests-cov.py b/runtests-cov.py --- a/runtests-cov.py +++ b/runtests-cov.py @@ -140,4 +140,10 @@ except ImportError: sys.stderr.write('Error: You have to install unittest2\n') sys.exit(1) + if sys.version < '2.5': + try: + from distutils2._backport import hashlib + except ImportError: + import subprocess + subprocess.call([sys.executable, 'setup.py', 'build_ext']) sys.exit(test_main()) diff --git a/runtests.py b/runtests.py --- a/runtests.py +++ b/runtests.py @@ -33,4 +33,10 @@ except ImportError: sys.stderr.write('Error: You have to install unittest2') sys.exit(1) + if sys.version < '2.5': + try: + from distutils2._backport import hashlib + except ImportError: + import subprocess + subprocess.call([sys.executable, 'setup.py', 'build_ext']) sys.exit(test_main()) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: More test fiddling Message-ID: tarek.ziade pushed 844e2164f861 to distutils2: http://hg.python.org/distutils2/rev/844e2164f861 changeset: 726:844e2164f861 parent: 724:45418c55703c user: ?ric Araujo date: Fri Oct 01 21:54:27 2010 +0200 summary: More test fiddling files: distutils2/_backport/tests/__init__.py, distutils2/_backport/tests/test_pkgutil.py, distutils2/_backport/tests/test_sysconfig.py, distutils2/tests/__init__.py, runtests-cov.py, runtests.py diff --git a/distutils2/_backport/tests/__init__.py b/distutils2/_backport/tests/__init__.py --- a/distutils2/_backport/tests/__init__.py +++ b/distutils2/_backport/tests/__init__.py @@ -1,7 +1,7 @@ import os import sys -from distutils2.tests.support import unittest +from distutils2.tests import unittest here = os.path.dirname(__file__) or os.curdir diff --git a/distutils2/_backport/tests/test_pkgutil.py b/distutils2/_backport/tests/test_pkgutil.py --- a/distutils2/_backport/tests/test_pkgutil.py +++ b/distutils2/_backport/tests/test_pkgutil.py @@ -12,8 +12,8 @@ except ImportError: from distutils2._backport.hashlib import md5 -from test.test_support import run_unittest, TESTFN -from distutils2.tests.support import unittest +from test.test_support import TESTFN +from distutils2.tests import unittest, run_unittest from distutils2._backport import pkgutil diff --git a/distutils2/_backport/tests/test_sysconfig.py b/distutils2/_backport/tests/test_sysconfig.py --- a/distutils2/_backport/tests/test_sysconfig.py +++ b/distutils2/_backport/tests/test_sysconfig.py @@ -14,7 +14,8 @@ get_config_var, get_config_vars, get_path, get_paths, get_platform, get_scheme_names, _main, _SCHEMES) -from distutils2.tests.support import unittest, EnvironGuard +from distutils2.tests import unittest +from distutils2.tests.support import EnvironGuard from test.test_support import TESTFN, unlink try: from test.test_support import skip_unless_symlink diff --git a/distutils2/tests/__init__.py b/distutils2/tests/__init__.py --- a/distutils2/tests/__init__.py +++ b/distutils2/tests/__init__.py @@ -24,8 +24,12 @@ # improved unittest package from 3.2's standard library import unittest else: - # external release of same package for older versions - import unittest2 as unittest + try: + # external release of same package for older versions + import unittest2 as unittest + except ImportError: + sys.exit('Error: You have to install unittest2') + from test.test_support import TESTFN # use TESTFN from stdlib/test_support. diff --git a/runtests-cov.py b/runtests-cov.py --- a/runtests-cov.py +++ b/runtests-cov.py @@ -83,14 +83,14 @@ # that module is also completely optional pass - try: - cov.report(morfs, - omit_prefixes=prefixes, + try: + cov.report(morfs, + omit_prefixes=prefixes, show_missing=opts.show_missing) except TypeError: # Coverage 3.4 turned `omit_prefixes` into a list of globbing patterns - cov.report(morfs, - omit=[p+"*" for p in prefixes], + cov.report(morfs, + omit=[p + "*" for p in prefixes], show_missing=opts.show_missing) def test_main(): @@ -115,18 +115,13 @@ def run_tests(verbose): - import distutils2.tests - from distutils2.tests import run_unittest, reap_children, TestFailed + # do NOT import those at the top level, coverage will be inaccurate if + # modules are imported before its magic is started + from distutils2.tests import run_unittest, test_suite, reap_children, TestFailed from distutils2._backport.tests import test_suite as btest_suite - # XXX just supporting -q right now to enable detailed/quiet output - if len(sys.argv) > 1: - verbose = sys.argv[-1] != '-q' - else: - verbose = 1 try: try: - run_unittest([distutils2.tests.test_suite(), btest_suite()], - verbose_=verbose) + run_unittest([test_suite(), btest_suite()], verbose_=verbose) return 0 except TestFailed: return 1 @@ -135,11 +130,6 @@ if __name__ == "__main__": - try: - from distutils2.tests import unittest - except ImportError: - sys.stderr.write('Error: You have to install unittest2\n') - sys.exit(1) if sys.version < '2.5': try: from distutils2._backport import hashlib diff --git a/runtests.py b/runtests.py --- a/runtests.py +++ b/runtests.py @@ -8,8 +8,8 @@ def test_main(): - import distutils2.tests - from distutils2.tests import run_unittest, reap_children, TestFailed + from distutils2.tests import (run_unittest, reap_children, + test_suite, TestFailed) from distutils2._backport.tests import test_suite as btest_suite # XXX just supporting -q right now to enable detailed/quiet output if len(sys.argv) > 1: @@ -18,8 +18,7 @@ verbose = 1 try: try: - run_unittest([distutils2.tests.test_suite(), btest_suite()], - verbose_=verbose) + run_unittest([test_suite(), btest_suite()], verbose_=verbose) return 0 except TestFailed: return 1 @@ -28,11 +27,6 @@ if __name__ == "__main__": - try: - from distutils2.tests.support import unittest - except ImportError: - sys.stderr.write('Error: You have to install unittest2') - sys.exit(1) if sys.version < '2.5': try: from distutils2._backport import hashlib -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Fixed test error involving pkgutil's caching Message-ID: tarek.ziade pushed ea3d00815339 to distutils2: http://hg.python.org/distutils2/rev/ea3d00815339 changeset: 725:ea3d00815339 parent: 690:37f948f6be6c user: Jeremy Kloth date: Fri Oct 01 13:31:28 2010 -0600 summary: Fixed test error involving pkgutil's caching files: distutils2/_backport/tests/test_pkgutil.py, distutils2/tests/test_depgraph.py diff --git a/distutils2/_backport/tests/test_pkgutil.py b/distutils2/_backport/tests/test_pkgutil.py --- a/distutils2/_backport/tests/test_pkgutil.py +++ b/distutils2/_backport/tests/test_pkgutil.py @@ -39,10 +39,12 @@ super(TestPkgUtilData, self).setUp() self.dirname = tempfile.mkdtemp() sys.path.insert(0, self.dirname) + pkgutil.disable_cache() def tearDown(self): super(TestPkgUtilData, self).tearDown() del sys.path[0] + pkgutil.enable_cache() shutil.rmtree(self.dirname) def test_getdata_filesys(self): @@ -139,10 +141,12 @@ def setUp(self): super(TestPkgUtilPEP302, self).setUp() + pkgutil.disable_cache() sys.meta_path.insert(0, self.MyTestImporter()) def tearDown(self): del sys.meta_path[0] + pkgutil.enable_cache() super(TestPkgUtilPEP302, self).tearDown() def test_getdata_pep302(self): @@ -168,6 +172,7 @@ super(TestPkgUtilDistribution, self).setUp() self.fake_dists_path = os.path.abspath( os.path.join(os.path.dirname(__file__), 'fake_dists')) + pkgutil.disable_cache() self.distinfo_dirs = [os.path.join(self.fake_dists_path, dir) for dir in os.listdir(self.fake_dists_path) @@ -214,6 +219,7 @@ for distinfo_dir in self.distinfo_dirs: record_file = os.path.join(distinfo_dir, 'RECORD') open(record_file, 'w').close() + pkgutil.enable_cache() super(TestPkgUtilDistribution, self).tearDown() def test_instantiation(self): @@ -322,6 +328,7 @@ def setUp(self): super(TestPkgUtilPEP376, self).setUp() + pkgutil.disable_cache() # Setup the path environment with our fake distributions current_path = os.path.abspath(os.path.dirname(__file__)) self.sys_path = sys.path[:] @@ -330,6 +337,7 @@ def tearDown(self): sys.path[:] = self.sys_path + pkgutil.enable_cache() super(TestPkgUtilPEP376, self).tearDown() def test_distinfo_dirname(self): diff --git a/distutils2/tests/test_depgraph.py b/distutils2/tests/test_depgraph.py --- a/distutils2/tests/test_depgraph.py +++ b/distutils2/tests/test_depgraph.py @@ -33,6 +33,7 @@ path = os.path.abspath(path) self.sys_path = sys.path[:] sys.path[0:0] = [path] + pkgutil.disable_cache() def test_generate_graph(self): dists = [] @@ -178,6 +179,7 @@ def tearDown(self): super(DepGraphTestCase, self).tearDown() + pkgutil.enable_cache() sys.path = self.sys_path def test_suite(): -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Merge fixes from jkloth Message-ID: tarek.ziade pushed 5a393dc99d6d to distutils2: http://hg.python.org/distutils2/rev/5a393dc99d6d changeset: 727:5a393dc99d6d parent: 726:844e2164f861 parent: 725:ea3d00815339 user: ?ric Araujo date: Fri Oct 01 22:34:40 2010 +0200 summary: Merge fixes from jkloth files: distutils2/_backport/tests/test_pkgutil.py, distutils2/tests/test_depgraph.py diff --git a/distutils2/_backport/tests/test_pkgutil.py b/distutils2/_backport/tests/test_pkgutil.py --- a/distutils2/_backport/tests/test_pkgutil.py +++ b/distutils2/_backport/tests/test_pkgutil.py @@ -39,10 +39,12 @@ super(TestPkgUtilData, self).setUp() self.dirname = tempfile.mkdtemp() sys.path.insert(0, self.dirname) + pkgutil.disable_cache() def tearDown(self): super(TestPkgUtilData, self).tearDown() del sys.path[0] + pkgutil.enable_cache() shutil.rmtree(self.dirname) def test_getdata_filesys(self): @@ -139,10 +141,12 @@ def setUp(self): super(TestPkgUtilPEP302, self).setUp() + pkgutil.disable_cache() sys.meta_path.insert(0, self.MyTestImporter()) def tearDown(self): del sys.meta_path[0] + pkgutil.enable_cache() super(TestPkgUtilPEP302, self).tearDown() def test_getdata_pep302(self): @@ -168,6 +172,7 @@ super(TestPkgUtilDistribution, self).setUp() self.fake_dists_path = os.path.abspath( os.path.join(os.path.dirname(__file__), 'fake_dists')) + pkgutil.disable_cache() self.distinfo_dirs = [os.path.join(self.fake_dists_path, dir) for dir in os.listdir(self.fake_dists_path) @@ -214,6 +219,7 @@ for distinfo_dir in self.distinfo_dirs: record_file = os.path.join(distinfo_dir, 'RECORD') open(record_file, 'w').close() + pkgutil.enable_cache() super(TestPkgUtilDistribution, self).tearDown() def test_instantiation(self): @@ -322,6 +328,7 @@ def setUp(self): super(TestPkgUtilPEP376, self).setUp() + pkgutil.disable_cache() # Setup the path environment with our fake distributions current_path = os.path.abspath(os.path.dirname(__file__)) self.sys_path = sys.path[:] @@ -330,6 +337,7 @@ def tearDown(self): sys.path[:] = self.sys_path + pkgutil.enable_cache() super(TestPkgUtilPEP376, self).tearDown() def test_distinfo_dirname(self): diff --git a/distutils2/tests/test_depgraph.py b/distutils2/tests/test_depgraph.py --- a/distutils2/tests/test_depgraph.py +++ b/distutils2/tests/test_depgraph.py @@ -32,6 +32,7 @@ path = os.path.abspath(path) self.sys_path = sys.path[:] sys.path[0:0] = [path] + pkgutil.disable_cache() def test_generate_graph(self): dists = [] @@ -177,6 +178,7 @@ def tearDown(self): super(DepGraphTestCase, self).tearDown() + pkgutil.enable_cache() sys.path = self.sys_path def test_suite(): -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: Merge coverage functionality into runtests.py. Thanks Yannick! Message-ID: tarek.ziade pushed e94847294adf to distutils2: http://hg.python.org/distutils2/rev/e94847294adf changeset: 728:e94847294adf user: ?ric Araujo date: Fri Oct 01 22:43:22 2010 +0200 summary: Merge coverage functionality into runtests.py. Thanks Yannick! files: runtests-cov.py, runtests.py diff --git a/runtests-cov.py b/runtests-cov.py deleted file mode 100644 --- a/runtests-cov.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python -"""Tests for distutils2. - -The tests for distutils2 are defined in the distutils2.tests package. -""" - -import sys -from os.path import dirname, islink, realpath, join, abspath -from optparse import OptionParser - -COVERAGE_FILE = join(dirname(abspath(__file__)), '.coverage') - -def get_coverage(): - """ Return a usable coverage object. """ - # deferred import because coverage is optional - import coverage - cov = getattr(coverage, "the_coverage", None) - if not cov: - cov = coverage.coverage(COVERAGE_FILE) - return cov - -def ignore_prefixes(module): - """ Return a list of prefixes to ignore in the coverage report if - we want to completely skip `module`. - """ - # A function like that is needed because some GNU/Linux - # distributions, such a Ubuntu, really like to build link farm in - # /usr/lib in order to save a few bytes on the disk. - dirnames = [dirname(module.__file__)] - - pymod = module.__file__.rstrip("c") - if islink(pymod): - dirnames.append(dirname(realpath(pymod))) - return dirnames - - -def parse_opts(): - parser = OptionParser(usage="%prog [OPTIONS]", - description="run the distutils2 unittests") - - parser.add_option("-q", "--quiet", help="do not print verbose messages", - action="store_true", default=False) - parser.add_option("-c", "--coverage", action="store_true", default=False, - help="produce a coverage report at the end of the run") - parser.add_option("-r", "--report", action="store_true", default=False, - help="produce a coverage report from the last test run") - parser.add_option("-m", "--show-missing", action="store_true", - default=False, - help=("Show line numbers of statements in each module " - "that weren't executed.")) - - opts, args = parser.parse_args() - return opts, args - - -def coverage_report(opts): - from distutils2.tests.support import unittest - cov = get_coverage() - if hasattr(cov, "load"): - # running coverage 3.x - cov.load() - morfs = None - else: - # running coverage 2.x - cov.cache = COVERAGE_FILE - cov.restore() - morfs = [m for m in cov.cexecuted.keys() if "distutils2" in m] - - prefixes = ["runtests", "distutils2/tests", "distutils2/_backport"] - prefixes += ignore_prefixes(unittest) - - try: - import docutils - prefixes += ignore_prefixes(docutils) - except ImportError: - # that module is completely optional - pass - - try: - import roman - prefixes += ignore_prefixes(roman) - except ImportError: - # that module is also completely optional - pass - - try: - cov.report(morfs, - omit_prefixes=prefixes, - show_missing=opts.show_missing) - except TypeError: - # Coverage 3.4 turned `omit_prefixes` into a list of globbing patterns - cov.report(morfs, - omit=[p + "*" for p in prefixes], - show_missing=opts.show_missing) - -def test_main(): - opts, args = parse_opts() - verbose = not opts.quiet - ret = 0 - - if opts.coverage: - cov = get_coverage() - cov.erase() - cov.start() - if not opts.report: - ret = run_tests(verbose) - if opts.coverage: - cov.stop() - cov.save() - - if opts.report or opts.coverage: - coverage_report(opts) - - return ret - - -def run_tests(verbose): - # do NOT import those at the top level, coverage will be inaccurate if - # modules are imported before its magic is started - from distutils2.tests import run_unittest, test_suite, reap_children, TestFailed - from distutils2._backport.tests import test_suite as btest_suite - try: - try: - run_unittest([test_suite(), btest_suite()], verbose_=verbose) - return 0 - except TestFailed: - return 1 - finally: - reap_children() - - -if __name__ == "__main__": - if sys.version < '2.5': - try: - from distutils2._backport import hashlib - except ImportError: - import subprocess - subprocess.call([sys.executable, 'setup.py', 'build_ext']) - sys.exit(test_main()) diff --git a/runtests.py b/runtests.py --- a/runtests.py +++ b/runtests.py @@ -5,17 +5,120 @@ """ import sys +from os.path import dirname, islink, realpath, join, abspath +from optparse import OptionParser +COVERAGE_FILE = join(dirname(abspath(__file__)), '.coverage') + +def get_coverage(): + """ Return a usable coverage object. """ + # deferred import because coverage is optional + import coverage + cov = getattr(coverage, "the_coverage", None) + if not cov: + cov = coverage.coverage(COVERAGE_FILE) + return cov + +def ignore_prefixes(module): + """ Return a list of prefixes to ignore in the coverage report if + we want to completely skip `module`. + """ + # A function like that is needed because some GNU/Linux + # distributions, such a Ubuntu, really like to build link farm in + # /usr/lib in order to save a few bytes on the disk. + dirnames = [dirname(module.__file__)] + + pymod = module.__file__.rstrip("c") + if islink(pymod): + dirnames.append(dirname(realpath(pymod))) + return dirnames + + +def parse_opts(): + parser = OptionParser(usage="%prog [OPTIONS]", + description="run the distutils2 unittests") + + parser.add_option("-q", "--quiet", help="do not print verbose messages", + action="store_true", default=False) + parser.add_option("-c", "--coverage", action="store_true", default=False, + help="produce a coverage report at the end of the run") + parser.add_option("-r", "--report", action="store_true", default=False, + help="produce a coverage report from the last test run") + parser.add_option("-m", "--show-missing", action="store_true", + default=False, + help=("Show line numbers of statements in each module " + "that weren't executed.")) + + opts, args = parser.parse_args() + return opts, args + + +def coverage_report(opts): + from distutils2.tests.support import unittest + cov = get_coverage() + if hasattr(cov, "load"): + # running coverage 3.x + cov.load() + morfs = None + else: + # running coverage 2.x + cov.cache = COVERAGE_FILE + cov.restore() + morfs = [m for m in cov.cexecuted.keys() if "distutils2" in m] + + prefixes = ["runtests", "distutils2/tests", "distutils2/_backport"] + prefixes += ignore_prefixes(unittest) + + try: + import docutils + prefixes += ignore_prefixes(docutils) + except ImportError: + # that module is completely optional + pass + + try: + import roman + prefixes += ignore_prefixes(roman) + except ImportError: + # that module is also completely optional + pass + + try: + cov.report(morfs, + omit_prefixes=prefixes, + show_missing=opts.show_missing) + except TypeError: + # Coverage 3.4 turned `omit_prefixes` into a list of globbing patterns + cov.report(morfs, + omit=[p + "*" for p in prefixes], + show_missing=opts.show_missing) def test_main(): - from distutils2.tests import (run_unittest, reap_children, - test_suite, TestFailed) + opts, args = parse_opts() + verbose = not opts.quiet + ret = 0 + + if opts.coverage: + cov = get_coverage() + cov.erase() + cov.start() + if not opts.report: + ret = run_tests(verbose) + if opts.coverage: + cov.stop() + cov.save() + + if opts.report or opts.coverage: + coverage_report(opts) + + return ret + + +def run_tests(verbose): + # do NOT import those at the top level, coverage will be inaccurate if + # modules are imported before its magic is started + from distutils2.tests import run_unittest, test_suite, reap_children, TestFailed from distutils2._backport.tests import test_suite as btest_suite - # XXX just supporting -q right now to enable detailed/quiet output - if len(sys.argv) > 1: - verbose = sys.argv[-1] != '-q' - else: - verbose = 1 try: try: run_unittest([test_suite(), btest_suite()], verbose_=verbose) -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:52:20 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 00:52:20 +0200 Subject: [Python-checkins] distutils2: merged Message-ID: tarek.ziade pushed 397f4622333b to distutils2: http://hg.python.org/distutils2/rev/397f4622333b changeset: 729:397f4622333b tag: tip parent: 691:c7e47ada3eec parent: 728:e94847294adf user: Tarek Ziade date: Sat Oct 02 00:50:48 2010 +0200 summary: merged files: distutils2/core.py, distutils2/tests/test_config.py, runtests-cov.py, runtests.py diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -7,6 +7,7 @@ build/ dist/ _static/ +_build/ *.swp .coverage .tox diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -9,6 +9,7 @@ Thanks to: +- Rajiv Abraham - Ali Afshar - ??ric Araujo - Pior Bastida @@ -19,12 +20,15 @@ - Josip Djolonga - Yannick Gingras - Jeremy Kloth +- Amos Latteier - Martin von L??wis - Carl Meyer - Alexis M??taireau - Zubin Mithra +- Derek McTavish Mounce - Michael Mulich - George Peristerakis +- Mathieu Perreault - Sean Reifschneider - Antoine Reversat - Luis Rojas diff --git a/DEVNOTES.txt b/DEVNOTES.txt --- a/DEVNOTES.txt +++ b/DEVNOTES.txt @@ -7,8 +7,3 @@ - Always run tests.sh before you push a change. This implies that you have all Python versions installed from 2.4 to 2.7. - -- With Python 2.4, if you want to run tests with runtests.py, or run - just one test directly, be sure to run python2.4 setup.py build_ext - first, else tests won't find _hashlib or _md5. When using tests.sh, - build_ext is automatically done. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,284 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations (now Zope +Corporation, see http://www.zope.com). In 2001, the Python Software +Foundation (PSF, see http://www.python.org/psf/) was formed, a +non-profit organization created specifically to own Python-related +Intellectual Property. Zope Corporation is a sponsoring member of +the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.2 2.1.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2.1 2.2 2002 PSF yes + 2.2.2 2.2.1 2002 PSF yes + 2.2.3 2.2.2 2003 PSF yes + 2.3 2.2.2 2002-2003 PSF yes + 2.3.1 2.3 2002-2003 PSF yes + 2.3.2 2.3.1 2002-2003 PSF yes + 2.3.3 2.3.2 2002-2003 PSF yes + 2.3.4 2.3.3 2004 PSF yes + 2.3.5 2.3.4 2005 PSF yes + 2.4 2.3 2004 PSF yes + 2.4.1 2.4 2005 PSF yes + 2.4.2 2.4.1 2005 PSF yes + 2.4.3 2.4.2 2006 PSF yes + 2.4.4 2.4.3 2006 PSF yes + 2.5 2.4 2006 PSF yes + 2.5.1 2.5 2007 PSF yes + 2.5.2 2.5.1 2008 PSF yes + 2.5.3 2.5.2 2008 PSF yes + 2.6 2.5 2008 PSF yes + 2.6.1 2.6 2008 PSF yes + 2.6.2 2.6.1 2009 PSF yes + 2.6.3 2.6.2 2009 PSF yes + 2.6.4 2.6.3 2009 PSF yes + 2.6.5 2.6.4 2010 PSF yes + 3.0 2.6 2008 PSF yes + 3.0.1 3.0 2009 PSF yes + 3.1 3.0.1 2009 PSF yes + 3.1.1 3.1 2009 PSF yes + 3.1.2 3.1 2010 PSF yes + 3.2 3.1 2010 PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +Python Software Foundation; All Rights Reserved" are retained in Python alone or +in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the Internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the Internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/distutils2/_backport/tests/__init__.py b/distutils2/_backport/tests/__init__.py --- a/distutils2/_backport/tests/__init__.py +++ b/distutils2/_backport/tests/__init__.py @@ -1,7 +1,7 @@ import os import sys -from distutils2.tests.support import unittest +from distutils2.tests import unittest here = os.path.dirname(__file__) or os.curdir diff --git a/distutils2/_backport/tests/test_pkgutil.py b/distutils2/_backport/tests/test_pkgutil.py --- a/distutils2/_backport/tests/test_pkgutil.py +++ b/distutils2/_backport/tests/test_pkgutil.py @@ -12,8 +12,8 @@ except ImportError: from distutils2._backport.hashlib import md5 -from test.test_support import run_unittest, TESTFN -from distutils2.tests.support import unittest +from test.test_support import TESTFN +from distutils2.tests import unittest, run_unittest from distutils2._backport import pkgutil @@ -39,10 +39,12 @@ super(TestPkgUtilData, self).setUp() self.dirname = tempfile.mkdtemp() sys.path.insert(0, self.dirname) + pkgutil.disable_cache() def tearDown(self): super(TestPkgUtilData, self).tearDown() del sys.path[0] + pkgutil.enable_cache() shutil.rmtree(self.dirname) def test_getdata_filesys(self): @@ -139,10 +141,12 @@ def setUp(self): super(TestPkgUtilPEP302, self).setUp() + pkgutil.disable_cache() sys.meta_path.insert(0, self.MyTestImporter()) def tearDown(self): del sys.meta_path[0] + pkgutil.enable_cache() super(TestPkgUtilPEP302, self).tearDown() def test_getdata_pep302(self): @@ -168,6 +172,7 @@ super(TestPkgUtilDistribution, self).setUp() self.fake_dists_path = os.path.abspath( os.path.join(os.path.dirname(__file__), 'fake_dists')) + pkgutil.disable_cache() self.distinfo_dirs = [os.path.join(self.fake_dists_path, dir) for dir in os.listdir(self.fake_dists_path) @@ -214,6 +219,7 @@ for distinfo_dir in self.distinfo_dirs: record_file = os.path.join(distinfo_dir, 'RECORD') open(record_file, 'w').close() + pkgutil.enable_cache() super(TestPkgUtilDistribution, self).tearDown() def test_instantiation(self): @@ -322,6 +328,7 @@ def setUp(self): super(TestPkgUtilPEP376, self).setUp() + pkgutil.disable_cache() # Setup the path environment with our fake distributions current_path = os.path.abspath(os.path.dirname(__file__)) self.sys_path = sys.path[:] @@ -330,6 +337,7 @@ def tearDown(self): sys.path[:] = self.sys_path + pkgutil.enable_cache() super(TestPkgUtilPEP376, self).tearDown() def test_distinfo_dirname(self): diff --git a/distutils2/_backport/tests/test_sysconfig.py b/distutils2/_backport/tests/test_sysconfig.py --- a/distutils2/_backport/tests/test_sysconfig.py +++ b/distutils2/_backport/tests/test_sysconfig.py @@ -14,7 +14,8 @@ get_config_var, get_config_vars, get_path, get_paths, get_platform, get_scheme_names, _main, _SCHEMES) -from distutils2.tests.support import unittest, EnvironGuard +from distutils2.tests import unittest +from distutils2.tests.support import EnvironGuard from test.test_support import TESTFN, unlink try: from test.test_support import skip_unless_symlink diff --git a/distutils2/command/bdist_msi.py b/distutils2/command/bdist_msi.py --- a/distutils2/command/bdist_msi.py +++ b/distutils2/command/bdist_msi.py @@ -10,11 +10,11 @@ from sysconfig import get_python_version from distutils2.core import Command -from distutils2.dir_util import remove_tree from distutils2.version import StrictVersion from distutils2.errors import DistutilsOptionError from distutils2 import log from distutils2.util import get_platform +from distutils2._backport.shutil import rmtree import msilib from msilib import schema, sequence, text @@ -259,7 +259,9 @@ self.distribution.dist_files.append(tup) if not self.keep_temp: - remove_tree(self.bdist_dir, dry_run=self.dry_run) + log.info("removing temporary build directory %s", self.bdist_dir) + if not self.dry_run: + rmtree(self.bdist_dir) def add_files(self): db = self.db diff --git a/distutils2/command/build_ext.py b/distutils2/command/build_ext.py --- a/distutils2/command/build_ext.py +++ b/distutils2/command/build_ext.py @@ -31,7 +31,7 @@ HAS_USER_SITE = True if os.name == 'nt': - from distutils2.msvccompiler import get_build_version + from distutils2.compiler.msvccompiler import get_build_version MSVC_VERSION = int(get_build_version()) # An extension name is just a dot-separated list of Python NAMEs (ie. diff --git a/distutils2/compiler/msvccompiler.py b/distutils2/compiler/msvccompiler.py --- a/distutils2/compiler/msvccompiler.py +++ b/distutils2/compiler/msvccompiler.py @@ -654,6 +654,6 @@ if get_build_version() >= 8.0: log.debug("Importing new compiler from distutils.msvc9compiler") OldMSVCCompiler = MSVCCompiler - from distutils2.msvc9compiler import MSVCCompiler + from distutils2.compiler.msvc9compiler import MSVCCompiler # get_build_architecture not really relevant now we support cross-compile - from distutils2.msvc9compiler import MacroExpander + from distutils2.compiler.msvc9compiler import MacroExpander diff --git a/distutils2/core.py b/distutils2/core.py --- a/distutils2/core.py +++ b/distutils2/core.py @@ -199,9 +199,10 @@ l = {} try: try: - sys.argv[0] = script_name if script_args is not None: - sys.argv[1:] = script_args + sys.argv = [script_name] + script_args + else: + sys.argv = [script_name] exec open(script_name, 'r').read() in g, l finally: sys.argv = save_argv diff --git a/distutils2/tests/__init__.py b/distutils2/tests/__init__.py --- a/distutils2/tests/__init__.py +++ b/distutils2/tests/__init__.py @@ -10,15 +10,26 @@ 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). +Always import unittest from this module, it will be the right version +(standard library unittest for 3.2 and higher, third-party unittest2 +release for older versions). + +Utility code is included in distutils2.tests.support. """ import os import sys -from distutils2.tests.support import unittest + +if sys.version_info >= (3, 2): + # improved unittest package from 3.2's standard library + import unittest +else: + try: + # external release of same package for older versions + import unittest2 as unittest + except ImportError: + sys.exit('Error: You have to install unittest2') + from test.test_support import TESTFN # use TESTFN from stdlib/test_support. diff --git a/distutils2/tests/pypi_server.py b/distutils2/tests/pypi_server.py --- a/distutils2/tests/pypi_server.py +++ b/distutils2/tests/pypi_server.py @@ -40,7 +40,7 @@ from SimpleHTTPServer import SimpleHTTPRequestHandler from SimpleXMLRPCServer import SimpleXMLRPCServer -from distutils2.tests.support import unittest +from distutils2.tests import unittest PYPI_DEFAULT_STATIC_PATH = os.path.dirname(os.path.abspath(__file__)) + "/pypiserver" diff --git a/distutils2/tests/support.py b/distutils2/tests/support.py --- a/distutils2/tests/support.py +++ b/distutils2/tests/support.py @@ -1,14 +1,10 @@ """Support code for distutils2 test cases. -Always import unittest from this module, it will be the right version -(standard library unittest for 3.2 and higher, third-party unittest2 -release for older versions). - Four helper classes are provided: LoggingCatcher, TempdirManager, EnvironGuard and WarningsCatcher. They are written to be used as mixins, e.g. :: - from distutils2.tests.support import unittest + from distutils2.tests import unittest from distutils2.tests.support import LoggingCatcher class SomeTestCase(LoggingCatcher, unittest.TestCase): @@ -37,13 +33,7 @@ from distutils2 import log from distutils2.dist import Distribution from distutils2.log import DEBUG, INFO, WARN, ERROR, FATAL - -if sys.version_info >= (3, 2): - # improved unittest package from 3.2's standard library - import unittest -else: - # external release of same package for older versions - import unittest2 as unittest +from distutils2.tests import unittest __all__ = ['LoggingCatcher', 'WarningsCatcher', 'TempdirManager', 'EnvironGuard', 'DummyCommand', 'unittest'] diff --git a/distutils2/tests/test_Mixin2to3.py b/distutils2/tests/test_Mixin2to3.py --- a/distutils2/tests/test_Mixin2to3.py +++ b/distutils2/tests/test_Mixin2to3.py @@ -3,8 +3,7 @@ import logging import distutils2 -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2.compat import Mixin2to3 diff --git a/distutils2/tests/test_bdist.py b/distutils2/tests/test_bdist.py --- a/distutils2/tests/test_bdist.py +++ b/distutils2/tests/test_bdist.py @@ -6,8 +6,7 @@ from distutils2.core import Distribution from distutils2.command.bdist import bdist -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2.util import find_executable from distutils2.errors import DistutilsExecError diff --git a/distutils2/tests/test_bdist_dumb.py b/distutils2/tests/test_bdist_dumb.py --- a/distutils2/tests/test_bdist_dumb.py +++ b/distutils2/tests/test_bdist_dumb.py @@ -10,8 +10,7 @@ except ImportError: zlib = None -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import run_unittest, unittest from distutils2.core import Distribution from distutils2.command.bdist_dumb import bdist_dumb diff --git a/distutils2/tests/test_bdist_msi.py b/distutils2/tests/test_bdist_msi.py --- a/distutils2/tests/test_bdist_msi.py +++ b/distutils2/tests/test_bdist_msi.py @@ -3,8 +3,7 @@ from distutils2.tests import run_unittest -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class BDistMSITestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_bdist_wininst.py b/distutils2/tests/test_bdist_wininst.py --- a/distutils2/tests/test_bdist_wininst.py +++ b/distutils2/tests/test_bdist_wininst.py @@ -1,10 +1,7 @@ """Tests for distutils.command.bdist_wininst.""" -from distutils2.tests import run_unittest - +from distutils2.tests import unittest, support, 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.LoggingCatcher, diff --git a/distutils2/tests/test_build.py b/distutils2/tests/test_build.py --- a/distutils2/tests/test_build.py +++ b/distutils2/tests/test_build.py @@ -3,8 +3,7 @@ import sys from distutils2.command.build import build -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support try: from sysconfig import get_platform except ImportError: diff --git a/distutils2/tests/test_build_clib.py b/distutils2/tests/test_build_clib.py --- a/distutils2/tests/test_build_clib.py +++ b/distutils2/tests/test_build_clib.py @@ -4,9 +4,8 @@ from distutils2.command.build_clib import build_clib from distutils2.errors import DistutilsSetupError -from distutils2.tests import support +from distutils2.tests import unittest, support from distutils2.util import find_executable -from distutils2.tests.support import unittest class BuildCLibTestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_build_ext.py b/distutils2/tests/test_build_ext.py --- a/distutils2/tests/test_build_ext.py +++ b/distutils2/tests/test_build_ext.py @@ -4,7 +4,7 @@ from StringIO import StringIO import distutils2.tests -from distutils2.tests.support import unittest +from distutils2.tests import unittest from distutils2.core import Extension, Distribution from distutils2.command.build_ext import build_ext from distutils2.tests import support diff --git a/distutils2/tests/test_build_py.py b/distutils2/tests/test_build_py.py --- a/distutils2/tests/test_build_py.py +++ b/distutils2/tests/test_build_py.py @@ -8,8 +8,7 @@ from distutils2.core import Distribution from distutils2.errors import DistutilsFileError -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class BuildPyTestCase(support.TempdirManager, diff --git a/distutils2/tests/test_build_scripts.py b/distutils2/tests/test_build_scripts.py --- a/distutils2/tests/test_build_scripts.py +++ b/distutils2/tests/test_build_scripts.py @@ -9,8 +9,7 @@ except ImportError: from distutils2._backport import sysconfig -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class BuildScriptsTestCase(support.TempdirManager, diff --git a/distutils2/tests/test_ccompiler.py b/distutils2/tests/test_ccompiler.py --- a/distutils2/tests/test_ccompiler.py +++ b/distutils2/tests/test_ccompiler.py @@ -4,8 +4,7 @@ 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 +from distutils2.tests import unittest, support class FakeCompiler(object): def library_dir_option(self, dir): diff --git a/distutils2/tests/test_check.py b/distutils2/tests/test_check.py --- a/distutils2/tests/test_check.py +++ b/distutils2/tests/test_check.py @@ -2,8 +2,7 @@ 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.tests import unittest, support from distutils2.errors import DistutilsSetupError class CheckTestCase(support.LoggingCatcher, diff --git a/distutils2/tests/test_clean.py b/distutils2/tests/test_clean.py --- a/distutils2/tests/test_clean.py +++ b/distutils2/tests/test_clean.py @@ -1,11 +1,8 @@ """Tests for distutils.command.clean.""" -import sys import os -import getpass from distutils2.command.clean import clean -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class cleanTestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_cmd.py b/distutils2/tests/test_cmd.py --- a/distutils2/tests/test_cmd.py +++ b/distutils2/tests/test_cmd.py @@ -5,7 +5,7 @@ from distutils2.command.cmd import Command from distutils2.dist import Distribution from distutils2.errors import DistutilsOptionError -from distutils2.tests.support import unittest +from distutils2.tests import unittest class MyCmd(Command): def initialize_options(self): diff --git a/distutils2/tests/test_config.py b/distutils2/tests/test_config.py --- a/distutils2/tests/test_config.py +++ b/distutils2/tests/test_config.py @@ -1,11 +1,10 @@ # -*- encoding: utf8 -*- """Tests for distutils.config.""" +import os import sys -import os -import copy +from StringIO import StringIO -from distutils2.tests import support, run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support, run_unittest SETUP_CFG = """ @@ -76,26 +75,28 @@ class ConfigTestCase(support.TempdirManager, unittest.TestCase): + def setUp(self): + super(ConfigTestCase, self).setUp() + self.addCleanup(setattr, sys, 'stdout', sys.stdout) + self.addCleanup(os.chdir, os.getcwd()) + def test_config(self): tempdir = self.mkdtemp() - setup_cfg = os.path.join(tempdir, 'setup.cfg') - f = open(setup_cfg, 'w') - try: - f.write(SETUP_CFG) - finally: - f.close() + os.chdir(tempdir) + self.write_file('setup.cfg', SETUP_CFG) - # trying to load the metadata now - old_args = copy.copy(sys.argv) + # try to load the metadata now + sys.stdout = StringIO() sys.argv[:] = ['setup.py', '--version'] - old_wd = os.getcwd() - os.chdir(tempdir) + old_sys = sys.argv[:] try: from distutils2.core import setup dist = setup() finally: - os.chdir(old_wd) - sys.argv[:] = old_args + sys.argv[:] = old_sys + + # sanity check + self.assertEqual(sys.stdout.getvalue(), '0.6.4' + os.linesep) # check what was done self.assertEqual(dist.metadata['Author'], 'Carl Meyer') diff --git a/distutils2/tests/test_config_cmd.py b/distutils2/tests/test_config_cmd.py --- a/distutils2/tests/test_config_cmd.py +++ b/distutils2/tests/test_config_cmd.py @@ -3,8 +3,7 @@ import sys from distutils2.command.config import dump_file, config -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2 import log class ConfigTestCase(support.LoggingCatcher, diff --git a/distutils2/tests/test_core.py b/distutils2/tests/test_core.py --- a/distutils2/tests/test_core.py +++ b/distutils2/tests/test_core.py @@ -6,8 +6,7 @@ import shutil import sys from distutils2.tests import captured_stdout -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support # setup script that uses __file__ setup_using___file__ = """\ diff --git a/distutils2/tests/test_cygwinccompiler.py b/distutils2/tests/test_cygwinccompiler.py --- a/distutils2/tests/test_cygwinccompiler.py +++ b/distutils2/tests/test_cygwinccompiler.py @@ -15,8 +15,7 @@ CONFIG_H_UNCERTAIN, get_versions, get_msvcr, RE_VERSION) from distutils2.util import get_compiler_versions -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class CygwinCCompilerTestCase(support.TempdirManager, unittest.TestCase): diff --git a/distutils2/tests/test_depgraph.py b/distutils2/tests/test_depgraph.py --- a/distutils2/tests/test_depgraph.py +++ b/distutils2/tests/test_depgraph.py @@ -1,7 +1,6 @@ """Tests for distutils.depgraph """ -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2 import depgraph from distutils2._backport import pkgutil @@ -33,6 +32,7 @@ path = os.path.abspath(path) self.sys_path = sys.path[:] sys.path[0:0] = [path] + pkgutil.disable_cache() def test_generate_graph(self): dists = [] @@ -178,6 +178,7 @@ def tearDown(self): super(DepGraphTestCase, self).tearDown() + pkgutil.enable_cache() sys.path = self.sys_path def test_suite(): diff --git a/distutils2/tests/test_dist.py b/distutils2/tests/test_dist.py --- a/distutils2/tests/test_dist.py +++ b/distutils2/tests/test_dist.py @@ -11,8 +11,8 @@ from distutils2.command.cmd import Command from distutils2.errors import DistutilsModuleError, DistutilsOptionError from distutils2.tests import TESTFN, captured_stdout -from distutils2.tests import support -from distutils2.tests.support import unittest, create_distribution +from distutils2.tests import support, unittest +from distutils2.tests.support import create_distribution class test_dist(Command): diff --git a/distutils2/tests/test_emxccompiler.py b/distutils2/tests/test_emxccompiler.py --- a/distutils2/tests/test_emxccompiler.py +++ b/distutils2/tests/test_emxccompiler.py @@ -7,8 +7,7 @@ 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 +from distutils2.tests import unittest, support class EmxCCompilerTestCase(support.TempdirManager, unittest.TestCase): diff --git a/distutils2/tests/test_extension.py b/distutils2/tests/test_extension.py --- a/distutils2/tests/test_extension.py +++ b/distutils2/tests/test_extension.py @@ -2,7 +2,7 @@ import os from distutils2.extension import Extension -from distutils2.tests.support import unittest +from distutils2.tests import unittest class ExtensionTestCase(unittest.TestCase): diff --git a/distutils2/tests/test_index_dist.py b/distutils2/tests/test_index_dist.py --- a/distutils2/tests/test_index_dist.py +++ b/distutils2/tests/test_index_dist.py @@ -4,7 +4,8 @@ from distutils2.tests.pypi_server import use_pypi_server from distutils2.tests import run_unittest -from distutils2.tests.support import unittest, TempdirManager +from distutils2.tests import unittest +from distutils2.tests.support import TempdirManager from distutils2.version import VersionPredicate from distutils2.index.errors import HashDoesNotMatch, UnsupportedHashName from distutils2.index.dist import (ReleaseInfo, ReleasesList, DistInfo, diff --git a/distutils2/tests/test_index_simple.py b/distutils2/tests/test_index_simple.py --- a/distutils2/tests/test_index_simple.py +++ b/distutils2/tests/test_index_simple.py @@ -6,8 +6,7 @@ import urllib2 from distutils2.index.simple import Crawler -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2.tests.pypi_server import (use_pypi_server, PyPIServer, PYPI_DEFAULT_STATIC_PATH) @@ -20,7 +19,7 @@ urls """ if hosts is None: - hosts = (server.full_address.strip("http://"),) + hosts = (server.full_address.replace("http://", ""),) kwargs['hosts'] = hosts return Crawler(server.full_address + base_url, *args, **kwargs) diff --git a/distutils2/tests/test_index_xmlrpc.py b/distutils2/tests/test_index_xmlrpc.py --- a/distutils2/tests/test_index_xmlrpc.py +++ b/distutils2/tests/test_index_xmlrpc.py @@ -1,8 +1,7 @@ """Tests for the distutils2.index.xmlrpc module.""" from distutils2.tests.pypi_server import use_xmlrpc_server -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import unittest, run_unittest from distutils2.index.xmlrpc import Client, InvalidSearchField, ProjectNotFound diff --git a/distutils2/tests/test_install.py b/distutils2/tests/test_install.py --- a/distutils2/tests/test_install.py +++ b/distutils2/tests/test_install.py @@ -17,8 +17,7 @@ from distutils2.core import Distribution from distutils2.errors import DistutilsOptionError -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class InstallTestCase(support.TempdirManager, support.EnvironGuard, diff --git a/distutils2/tests/test_install_data.py b/distutils2/tests/test_install_data.py --- a/distutils2/tests/test_install_data.py +++ b/distutils2/tests/test_install_data.py @@ -4,8 +4,7 @@ import getpass from distutils2.command.install_data import install_data -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class InstallDataTestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_install_distinfo.py b/distutils2/tests/test_install_distinfo.py --- a/distutils2/tests/test_install_distinfo.py +++ b/distutils2/tests/test_install_distinfo.py @@ -7,8 +7,7 @@ from distutils2.command.install_distinfo import install_distinfo from distutils2.core import Command from distutils2.metadata import DistributionMetadata -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support try: import hashlib diff --git a/distutils2/tests/test_install_headers.py b/distutils2/tests/test_install_headers.py --- a/distutils2/tests/test_install_headers.py +++ b/distutils2/tests/test_install_headers.py @@ -4,8 +4,7 @@ import getpass from distutils2.command.install_headers import install_headers -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class InstallHeadersTestCase(support.TempdirManager, support.LoggingCatcher, diff --git a/distutils2/tests/test_install_lib.py b/distutils2/tests/test_install_lib.py --- a/distutils2/tests/test_install_lib.py +++ b/distutils2/tests/test_install_lib.py @@ -4,9 +4,8 @@ from distutils2.command.install_lib import install_lib from distutils2.extension import Extension -from distutils2.tests import support +from distutils2.tests import unittest, support from distutils2.errors import DistutilsOptionError -from distutils2.tests.support import unittest try: no_bytecode = sys.dont_write_bytecode diff --git a/distutils2/tests/test_install_scripts.py b/distutils2/tests/test_install_scripts.py --- a/distutils2/tests/test_install_scripts.py +++ b/distutils2/tests/test_install_scripts.py @@ -5,8 +5,7 @@ from distutils2.command.install_scripts import install_scripts from distutils2.core import Distribution -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support class InstallScriptsTestCase(support.TempdirManager, diff --git a/distutils2/tests/test_install_tools.py b/distutils2/tests/test_install_tools.py --- a/distutils2/tests/test_install_tools.py +++ b/distutils2/tests/test_install_tools.py @@ -1,8 +1,7 @@ """Tests for the distutils2.index.xmlrpc module.""" from distutils2.tests.pypi_server import use_xmlrpc_server -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import unittest, run_unittest from distutils2.index.xmlrpc import Client from distutils2.install_tools import (get_infos, InstallationException) diff --git a/distutils2/tests/test_manifest.py b/distutils2/tests/test_manifest.py --- a/distutils2/tests/test_manifest.py +++ b/distutils2/tests/test_manifest.py @@ -4,8 +4,7 @@ import logging from distutils2.tests import run_unittest -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support from distutils2.manifest import Manifest _MANIFEST = """\ diff --git a/distutils2/tests/test_metadata.py b/distutils2/tests/test_metadata.py --- a/distutils2/tests/test_metadata.py +++ b/distutils2/tests/test_metadata.py @@ -6,8 +6,8 @@ from distutils2.metadata import (DistributionMetadata, _interpret, PKG_INFO_PREFERRED_VERSION) -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest, LoggingCatcher +from distutils2.tests import run_unittest, unittest +from distutils2.tests.support import LoggingCatcher from distutils2.errors import (MetadataConflictError, MetadataUnrecognizedVersionError) diff --git a/distutils2/tests/test_msvc9compiler.py b/distutils2/tests/test_msvc9compiler.py --- a/distutils2/tests/test_msvc9compiler.py +++ b/distutils2/tests/test_msvc9compiler.py @@ -3,8 +3,7 @@ import os from distutils2.errors import DistutilsPlatformError -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support _MANIFEST = """\ diff --git a/distutils2/tests/test_pypi_server.py b/distutils2/tests/test_pypi_server.py --- a/distutils2/tests/test_pypi_server.py +++ b/distutils2/tests/test_pypi_server.py @@ -4,7 +4,7 @@ import os.path from distutils2.tests.pypi_server import PyPIServer, PYPI_DEFAULT_STATIC_PATH -from distutils2.tests.support import unittest +from distutils2.tests import unittest class PyPIServerTest(unittest.TestCase): diff --git a/distutils2/tests/test_pypi_versions.py b/distutils2/tests/test_pypi_versions.py --- a/distutils2/tests/test_pypi_versions.py +++ b/distutils2/tests/test_pypi_versions.py @@ -18,8 +18,7 @@ import pickle from distutils2.version import suggest_normalized_version -from distutils2.tests import run_unittest -from distutils2.tests.support import unittest +from distutils2.tests import unittest, run_unittest def test_pypi(): # FIXME need a better way to do that diff --git a/distutils2/tests/test_register.py b/distutils2/tests/test_register.py --- a/distutils2/tests/test_register.py +++ b/distutils2/tests/test_register.py @@ -16,9 +16,7 @@ from distutils2.core import Distribution from distutils2.errors import DistutilsSetupError -from distutils2.tests import support -from distutils2.tests.support import unittest - +from distutils2.tests import unittest, support PYPIRC_NOPASSWORD = """\ [distutils] @@ -67,7 +65,9 @@ def read(self): return 'xxx' -class RegisterTestCase(support.TempdirManager, support.EnvironGuard, +class RegisterTestCase(support.TempdirManager, + support.EnvironGuard, + support.LoggingCatcher, unittest.TestCase): def setUp(self): diff --git a/distutils2/tests/test_sdist.py b/distutils2/tests/test_sdist.py --- a/distutils2/tests/test_sdist.py +++ b/distutils2/tests/test_sdist.py @@ -26,7 +26,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 import unittest from distutils2.errors import DistutilsExecError, DistutilsOptionError from distutils2.util import find_executable from distutils2.tests import support diff --git a/distutils2/tests/test_test.py b/distutils2/tests/test_test.py --- a/distutils2/tests/test_test.py +++ b/distutils2/tests/test_test.py @@ -9,9 +9,11 @@ from operator import getitem, setitem, delitem from StringIO import StringIO from distutils2.core import Command -from distutils2.tests.support import unittest, TempdirManager +from distutils2.tests import unittest +from distutils2.tests.support import TempdirManager, LoggingCatcher from distutils2.command.test import test from distutils2.dist import Distribution +from distutils2._backport import pkgutil try: any @@ -29,6 +31,7 @@ here = os.path.dirname(os.path.abspath(__file__)) class TestTest(TempdirManager, + LoggingCatcher, unittest.TestCase): def setUp(self): @@ -39,6 +42,7 @@ os.environ['PYTHONPATH'] = distutils2path + os.pathsep + self.old_pythonpath def tearDown(self): + pkgutil.clear_cache() os.environ['PYTHONPATH'] = self.old_pythonpath super(TestTest, self).tearDown() @@ -73,7 +77,7 @@ orig_has_attr = _hasattr(obj, attr) if orig_has_attr: - orig_val = _getattr(obj, attr) + orig_val = _getattr(obj, attr) if delete is False: _setattr(obj, attr, new_val) diff --git a/distutils2/tests/test_unixccompiler.py b/distutils2/tests/test_unixccompiler.py --- a/distutils2/tests/test_unixccompiler.py +++ b/distutils2/tests/test_unixccompiler.py @@ -7,7 +7,7 @@ from distutils2._backport import sysconfig from distutils2.compiler.unixccompiler import UnixCCompiler -from distutils2.tests.support import unittest +from distutils2.tests import unittest class UnixCCompilerTestCase(unittest.TestCase): diff --git a/distutils2/tests/test_upload.py b/distutils2/tests/test_upload.py --- a/distutils2/tests/test_upload.py +++ b/distutils2/tests/test_upload.py @@ -6,9 +6,8 @@ from distutils2.command.upload import upload from distutils2.core import Distribution -from distutils2.tests import support +from distutils2.tests import unittest, support from distutils2.tests.pypi_server import PyPIServer, PyPIServerTestCase -from distutils2.tests.support import unittest PYPIRC_NOPASSWORD = """\ diff --git a/distutils2/tests/test_upload_docs.py b/distutils2/tests/test_upload_docs.py --- a/distutils2/tests/test_upload_docs.py +++ b/distutils2/tests/test_upload_docs.py @@ -16,9 +16,8 @@ from distutils2.core import Distribution from distutils2.errors import DistutilsFileError, DistutilsOptionError -from distutils2.tests import support +from distutils2.tests import unittest, support from distutils2.tests.pypi_server import PyPIServer, PyPIServerTestCase -from distutils2.tests.support import unittest EXPECTED_MULTIPART_OUTPUT = "\r\n".join([ diff --git a/distutils2/tests/test_util.py b/distutils2/tests/test_util.py --- a/distutils2/tests/test_util.py +++ b/distutils2/tests/test_util.py @@ -7,7 +7,7 @@ import time from distutils2.tests import captured_stdout -from distutils2.tests.support import unittest +from distutils2.tests import unittest from distutils2.errors import (DistutilsPlatformError, DistutilsByteCompileError, DistutilsFileError, @@ -21,8 +21,7 @@ read_pypirc, resolve_name) from distutils2 import util -from distutils2.tests import support -from distutils2.tests.support import unittest +from distutils2.tests import unittest, support PYPIRC = """\ diff --git a/distutils2/tests/test_version.py b/distutils2/tests/test_version.py --- a/distutils2/tests/test_version.py +++ b/distutils2/tests/test_version.py @@ -6,7 +6,7 @@ from distutils2.version import HugeMajorVersionNumError, IrrationalVersionError from distutils2.version import suggest_normalized_version as suggest from distutils2.version import VersionPredicate -from distutils2.tests.support import unittest +from distutils2.tests import unittest class VersionTestCase(unittest.TestCase): @@ -31,6 +31,17 @@ for v, s in self.versions: self.assertEqual(str(v), s) + def test_hash(self): + + for v, s in self.versions: + self.assertEqual(hash(v), hash(V(s))) + + versions = set([v for v,s in self.versions]) + for v, s in self.versions: + self.assertIn(v, versions) + + self.assertEqual(set([V('1.0')]), set([V('1.0'), V('1.0')])) + def test_from_parts(self): for v, s in self.versions: @@ -188,6 +199,10 @@ # XXX need to silent the micro version in this case #assert not VersionPredicate('Ho (<3.0,!=2.6)').match('2.6.3') + # test repr + for predicate in predicates: + self.assertEqual(str(VersionPredicate(predicate)), predicate) + def test_predicate_name(self): # Test that names are parsed the right way diff --git a/distutils2/version.py b/distutils2/version.py --- a/distutils2/version.py +++ b/distutils2/version.py @@ -131,7 +131,7 @@ pad_zeros_length=0): """Parse 'N.N.N' sequences, return a list of ints. - @param s {str} 'N.N.N..." sequence to be parsed + @param s {str} 'N.N.N...' sequence to be parsed @param full_ver_str {str} The full version string from which this comes. Used for error strings. @param drop_trailing_zeros {bool} Whether to drop trailing zeros @@ -206,7 +206,8 @@ return self.__eq__(other) or self.__gt__(other) # See http://docs.python.org/reference/datamodel#object.__hash__ - __hash__ = object.__hash__ + def __hash__(self): + return hash(self.parts) def suggest_normalized_version(s): diff --git a/docs/source/conf.py b/docs/source/conf.py --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -12,7 +12,9 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import os +import sys +import sphinx # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -98,7 +100,8 @@ # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -html_theme_options = {'collapsiblesidebar': True} +if sphinx.__version__[:3] >= '1.0': + html_theme_options = {'collapsiblesidebar': True} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] diff --git a/docs/source/devresources.rst b/docs/source/devresources.rst --- a/docs/source/devresources.rst +++ b/docs/source/devresources.rst @@ -13,6 +13,9 @@ ~~~~~~~~~~~~ * unittest2 +* If your operating system splits core python and a python-dev (or -devel) + packages, install the dev package too: It contains header files needed by + tests. Issue Tracker ~~~~~~~~~~~~~ diff --git a/docs/source/distutils/introduction.rst b/docs/source/distutils/introduction.rst --- a/docs/source/distutils/introduction.rst +++ b/docs/source/distutils/introduction.rst @@ -5,42 +5,42 @@ ***************************** This document covers using Distutils2 to distribute your Python modules, -concentrating on the role of developer/distributor; if you're looking for -information on installing Python modules, you should refer to the +concentrating on the role of developer/distributor. If you're looking for +information on installing Python modules you should refer to the :ref:`install-index` chapter. Throughout this documentation, the terms "Distutils", "the Distutils" and -"Distutils2" will be used with the same meaning. +"Distutils2" will be used interchangeably. .. _distutils-concepts: Concepts & Terminology ====================== -Using the Distutils is quite simple, both for module developers and for +Using Distutils is quite simple both for module developers and for users/administrators installing third-party modules. As a developer, your responsibilities (apart from writing solid, well-documented and well-tested code, of course!) are: -* write a setup script (:file:`setup.py` by convention) +* writing a setup script (:file:`setup.py` by convention) -* (optional) write a setup configuration file +* (optional) writing a setup configuration file -* create a source distribution +* creating a source distribution -* (optional) create one or more built (binary) distributions +* (optional) creating one or more "built" (binary) distributions of your + project -Each of these tasks is covered in this document. +All of these tasks are covered in this document. -Not all module developers have access to a multitude of platforms, so it's not -always feasible to expect them to create a multitude of built distributions. It -is hoped that a class of intermediaries, called *packagers*, will arise to -address this need. Packagers will take source distributions released by module -developers, build them on one or more platforms, and release the resulting built -distributions. Thus, users on the most popular platforms will be able to -install most popular Python module distributions in the most natural way for -their platform, without having to run a single setup script or compile a line of -code. +Not all module developers have access to multiple platforms, so one cannot +expect them to create buildt distributions for every platform. To remedy +this, it is hoped that intermediaries called *packagers* will arise to address +this need. Packagers take source distributions released by module developers, +build them on one or more platforms and release the resulting built +distributions. Thus, users on a greater range of platforms will be able to +install the most popular Python modules in the most natural way for their +platform without having to run a setup script or compile a single line of code. .. _distutils-simple-example: @@ -48,15 +48,15 @@ A Simple Example ================ -The setup script is usually quite simple, although since it's written in Python, +A setup script is usually quite simple, although since it's written in Python there are no arbitrary limits to what you can do with it, though you should be -careful about putting arbitrarily expensive operations in your setup script. -Unlike, say, Autoconf-style configure scripts, the setup script may be run -multiple times in the course of building and installing your module +careful about putting expensive operations in your setup script. +Unlike, say, Autoconf-style configure scripts the setup script may be run +multiple times in the course of building and installing a module distribution. If all you want to do is distribute a module called :mod:`foo`, contained in a -file :file:`foo.py`, then your setup script can be as simple as this:: +file :file:`foo.py`, then your setup script can be as simple as:: from distutils2.core import setup setup(name='foo', @@ -69,18 +69,18 @@ arguments to the :func:`setup` function * those keyword arguments fall into two categories: package metadata (name, - version number) and information about what's in the package (a list of pure - Python modules, in this case) + version number, etc.) and information about what's in the package (a list + of pure Python modules in this case) * modules are specified by module name, not filename (the same will hold true for packages and extensions) -* it's recommended that you supply a little more metadata, in particular your - name, email address and a URL for the project (see section :ref:`setup-script` - for an example) +* it's recommended that you supply a little more metadata than we have in the + example. In particular your name, email address and a URL for the + project if appropriate (see section :ref:`setup-script` for an example) -To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +To create a source distribution for this module you would create a setup +script, :file:`setup.py`, containing the above code and run:: python setup.py sdist @@ -89,32 +89,32 @@ The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. -If an end-user wishes to install your :mod:`foo` module, all she has to do is -download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and---from the -:file:`foo-1.0` directory---run :: +If an end-user wishes to install your :mod:`foo` module all he has to do is +download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and from the +:file:`foo-1.0` directory run :: python setup.py install -which will ultimately copy :file:`foo.py` to the appropriate directory for +which will copy :file:`foo.py` to the appropriate directory for third-party modules in their Python installation. -This simple example demonstrates some fundamental concepts of the Distutils. +This simple example demonstrates some fundamental concepts of Distutils. First, both developers and installers have the same basic user interface, i.e. the setup script. The difference is which Distutils *commands* they use: the :command:`sdist` command is almost exclusively for module developers, while -:command:`install` is more often for installers (although most developers will -want to install their own code occasionally). +:command:`install` is more often used by installers (although some developers +will want to install their own code occasionally). -If you want to make things really easy for your users, you can create one or -more built distributions for them. For instance, if you are running on a -Windows machine, and want to make things easy for other Windows users, you can +If you want to make things really easy for your users, you can create more +than one built distributions for them. For instance, if you are running on a +Windows machine and want to make things easy for other Windows users, you can create an executable installer (the most appropriate type of built distribution for this platform) with the :command:`bdist_wininst` command. For example:: python setup.py bdist_wininst will create an executable installer, :file:`foo-1.0.win32.exe`, in the current -directory. You can find out what distribution formats are available at any time +directory. You can find out what distribution formats are available at any time by running :: python setup.py bdist --help-formats @@ -125,42 +125,42 @@ General Python terminology ========================== -If you're reading this document, you probably have a good idea of what modules, -extensions, and so forth are. Nevertheless, just to be sure that everyone is -operating from a common starting point, we offer the following glossary of -common Python terms: +If you're reading this document, you probably have a good idea of what Python +modules, extensions and so forth are. Nevertheless, just to be sure that +everyone is on the same page, here's a quick overview of Python terms: module - the basic unit of code reusability in Python: a block of code imported by some - other code. Three types of modules concern us here: pure Python modules, - extension modules, and packages. + The basic unit of code reusability in Python: a block of code imported by + some other code. Three types of modules are important to us here: pure + Python modules, extension modules and packages. pure Python module - a module written in Python and contained in a single :file:`.py` file (and - possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes referred - to as a "pure module." + A module written in Python and contained in a single :file:`.py` file (and + possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes + referred to as a "pure module." extension module - a module written in the low-level language of the Python implementation: C/C++ - for Python, Java for Jython. Typically contained in a single dynamically - loadable pre-compiled file, e.g. a shared object (:file:`.so`) file for Python + A module written in the low-level language of the Python implementation: C/C++ + for Python, Java for Jython. Typically contained in a single dynamically + loaded pre-compiled file, e.g. a shared object (:file:`.so`) file for Python extensions on Unix, a DLL (given the :file:`.pyd` extension) for Python - extensions on Windows, or a Java class file for Jython extensions. (Note that - currently, the Distutils only handles C/C++ extensions for Python.) + extensions on Windows, or a Java class file for Jython extensions. Note that + currently Distutils only handles C/C++ extensions for Python. package - a module that contains other modules; typically contained in a directory in the - filesystem and distinguished from other directories by the presence of a file - :file:`__init__.py`. + A module that contains other modules, typically contained in a directory of + the filesystem and distinguished from other directories by the presence of a + file :file:`__init__.py`. root package - the root of the hierarchy of packages. (This isn't really a package, since it - doesn't have an :file:`__init__.py` file. But we have to call it something.) - The vast majority of the standard library is in the root package, as are many - small, standalone third-party modules that don't belong to a larger module - collection. Unlike regular packages, modules in the root package can be found in - many directories: in fact, every directory listed in ``sys.path`` contributes - modules to the root package. + The root of the hierarchy of packages. (This isn't really a package, + since it doesn't have an :file:`__init__.py` file. But... we have to + call it something, right?) The vast majority of the standard library is + in the root package, as are many small standalone third-party modules that + don't belong to a larger module collection. Unlike regular packages, + modules in the root package can be found in many directories: in fact, + every directory listed in ``sys.path`` contributes modules to the root + package. .. _distutils-term: @@ -169,25 +169,25 @@ ============================== The following terms apply more specifically to the domain of distributing Python -modules using the Distutils: +modules using Distutils: module distribution - a collection of Python modules distributed together as a single downloadable - resource and meant to be installed *en masse*. Examples of some well-known + A collection of Python modules distributed together as a single downloadable + resource and meant to be installed all as one. Examples of some well-known module distributions are Numeric Python, PyXML, PIL (the Python Imaging - Library), or mxBase. (This would be called a *package*, except that term is - already taken in the Python context: a single module distribution may contain - zero, one, or many Python packages.) + Library) or mxBase. (Module distributions would be called a *package*, + except that term is already taken in the Python context: a single module + distribution may contain zero, one, or many Python packages.) pure module distribution - a module distribution that contains only pure Python modules and packages. + A module distribution that contains only pure Python modules and packages. Sometimes referred to as a "pure distribution." non-pure module distribution - a module distribution that contains at least one extension module. Sometimes + A module distribution that contains at least one extension module. Sometimes referred to as a "non-pure distribution." distribution root - the top-level directory of your source tree (or source distribution); the - directory where :file:`setup.py` exists. Generally :file:`setup.py` will be - run from this directory. + The top-level directory of your source tree (or source distribution). The + directory where :file:`setup.py` exists. Generally :file:`setup.py` will + be run from this directory. diff --git a/docs/source/distutils/setupscript.rst b/docs/source/distutils/setupscript.rst --- a/docs/source/distutils/setupscript.rst +++ b/docs/source/distutils/setupscript.rst @@ -5,12 +5,12 @@ ************************ The setup script is the center of all activity in building, distributing, and -installing modules using the Distutils. The main purpose of the setup script is -to describe your module distribution to the Distutils, so that the various +installing modules using Distutils. The main purpose of the setup script is +to describe your module distribution to Distutils, so that the various commands that operate on your modules do the right thing. As we saw in section -:ref:`distutils-simple-example` above, the setup script consists mainly of a -call to :func:`setup`, and most information supplied to the Distutils by the -module developer is supplied as keyword arguments to :func:`setup`. +:ref:`distutils-simple-example`, the setup script consists mainly of a +call to :func:`setup` where the most information is supplied as +keyword arguments to :func:`setup`. Here's a slightly more involved example, which we'll follow for the next couple of sections: a setup script that could be used for Distutils2 itself:: @@ -32,8 +32,8 @@ There are only two differences between this and the trivial one-file distribution presented in section :ref:`distutils-simple-example`: more -metadata, and the specification of pure Python modules by package, rather than -by module. This is important since the Distutils consist of a couple of dozen +metadata and the specification of pure Python modules by package rather than +by module. This is important since Ristutils consist of a couple of dozen modules split into (so far) two packages; an explicit list of every module would be tedious to generate and difficult to maintain. For more information on the additional metadata, see section :ref:`metadata`. @@ -501,7 +501,7 @@ file if no template is provided. See :ref:`manifest`. -.. _distutils2-additional-files: +.. _distutils-additional-files: Installing Additional Files =========================== diff --git a/docs/source/distutils/sourcedist.rst b/docs/source/distutils/sourcedist.rst --- a/docs/source/distutils/sourcedist.rst +++ b/docs/source/distutils/sourcedist.rst @@ -142,7 +142,7 @@ python setup.py sdist --manifest-only -:option:`-o` is a sortcut for :option:`--manifest-only`. +:option:`-o` is a shortcut for :option:`--manifest-only`. .. _manifest_template: diff --git a/runtests-cov.py b/runtests-cov.py deleted file mode 100644 --- a/runtests-cov.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python -"""Tests for distutils2. - -The tests for distutils2 are defined in the distutils2.tests package. -""" - -import sys -from os.path import dirname, islink, realpath, join, abspath -from optparse import OptionParser - -COVERAGE_FILE = join(dirname(abspath(__file__)), '.coverage') - -def get_coverage(): - """ Return a usable coverage object. """ - # deferred import because coverage is optional - import coverage - cov = getattr(coverage, "the_coverage", None) - if not cov: - cov = coverage.coverage(COVERAGE_FILE) - return cov - -def ignore_prefixes(module): - """ Return a list of prefixes to ignore in the coverage report if - we want to completely skip `module`. - """ - # A function like that is needed because some GNU/Linux - # distributions, such a Ubuntu, really like to build link farm in - # /usr/lib in order to save a few bytes on the disk. - dirnames = [dirname(module.__file__)] - - pymod = module.__file__.rstrip("c") - if islink(pymod): - dirnames.append(dirname(realpath(pymod))) - return dirnames - - -def parse_opts(): - parser = OptionParser(usage="%prog [OPTIONS]", - description="run the distutils2 unittests") - - parser.add_option("-q", "--quiet", help="do not print verbose messages", - action="store_true", default=False) - parser.add_option("-c", "--coverage", action="store_true", default=False, - help="produce a coverage report at the end of the run") - parser.add_option("-r", "--report", action="store_true", default=False, - help="produce a coverage report from the last test run") - parser.add_option("-m", "--show-missing", action="store_true", - default=False, - help=("Show line numbers of statements in each module " - "that weren't executed.")) - - opts, args = parser.parse_args() - return opts, args - - -def coverage_report(opts): - from distutils2.tests.support import unittest - cov = get_coverage() - if hasattr(cov, "load"): - # running coverage 3.x - cov.load() - morfs = None - else: - # running coverage 2.x - cov.cache = COVERAGE_FILE - cov.restore() - morfs = [m for m in cov.cexecuted.keys() if "distutils2" in m] - - prefixes = ["runtests", "distutils2/tests", "distutils2/_backport"] - prefixes += ignore_prefixes(unittest) - - try: - import docutils - prefixes += ignore_prefixes(docutils) - except ImportError: - # that module is completely optional - pass - - try: - import roman - prefixes += ignore_prefixes(roman) - except ImportError: - # that module is also completely optional - pass - - cov.report(morfs, omit_prefixes=prefixes, show_missing=opts.show_missing) - - -def test_main(): - opts, args = parse_opts() - verbose = not opts.quiet - ret = 0 - - if opts.coverage: - cov = get_coverage() - cov.erase() - cov.start() - if not opts.report: - ret = run_tests(verbose) - if opts.coverage: - cov.stop() - cov.save() - - if opts.report or opts.coverage: - coverage_report(opts) - - return ret - - -def run_tests(verbose): - import distutils2.tests - from distutils2.tests import run_unittest, reap_children, TestFailed - from distutils2._backport.tests import test_suite as btest_suite - # XXX just supporting -q right now to enable detailed/quiet output - if len(sys.argv) > 1: - verbose = sys.argv[-1] != '-q' - else: - verbose = 1 - try: - try: - run_unittest([distutils2.tests.test_suite(), btest_suite()], - verbose_=verbose) - return 0 - except TestFailed: - return 1 - finally: - reap_children() - - -if __name__ == "__main__": - try: - from distutils2.tests.support import unittest - except ImportError: - sys.stderr.write('Error: You have to install unittest2') - sys.exit(1) - sys.exit(test_main()) diff --git a/runtests.py b/runtests.py --- a/runtests.py +++ b/runtests.py @@ -5,21 +5,123 @@ """ import sys +from os.path import dirname, islink, realpath, join, abspath +from optparse import OptionParser +COVERAGE_FILE = join(dirname(abspath(__file__)), '.coverage') + +def get_coverage(): + """ Return a usable coverage object. """ + # deferred import because coverage is optional + import coverage + cov = getattr(coverage, "the_coverage", None) + if not cov: + cov = coverage.coverage(COVERAGE_FILE) + return cov + +def ignore_prefixes(module): + """ Return a list of prefixes to ignore in the coverage report if + we want to completely skip `module`. + """ + # A function like that is needed because some GNU/Linux + # distributions, such a Ubuntu, really like to build link farm in + # /usr/lib in order to save a few bytes on the disk. + dirnames = [dirname(module.__file__)] + + pymod = module.__file__.rstrip("c") + if islink(pymod): + dirnames.append(dirname(realpath(pymod))) + return dirnames + + +def parse_opts(): + parser = OptionParser(usage="%prog [OPTIONS]", + description="run the distutils2 unittests") + + parser.add_option("-q", "--quiet", help="do not print verbose messages", + action="store_true", default=False) + parser.add_option("-c", "--coverage", action="store_true", default=False, + help="produce a coverage report at the end of the run") + parser.add_option("-r", "--report", action="store_true", default=False, + help="produce a coverage report from the last test run") + parser.add_option("-m", "--show-missing", action="store_true", + default=False, + help=("Show line numbers of statements in each module " + "that weren't executed.")) + + opts, args = parser.parse_args() + return opts, args + + +def coverage_report(opts): + from distutils2.tests.support import unittest + cov = get_coverage() + if hasattr(cov, "load"): + # running coverage 3.x + cov.load() + morfs = None + else: + # running coverage 2.x + cov.cache = COVERAGE_FILE + cov.restore() + morfs = [m for m in cov.cexecuted.keys() if "distutils2" in m] + + prefixes = ["runtests", "distutils2/tests", "distutils2/_backport"] + prefixes += ignore_prefixes(unittest) + + try: + import docutils + prefixes += ignore_prefixes(docutils) + except ImportError: + # that module is completely optional + pass + + try: + import roman + prefixes += ignore_prefixes(roman) + except ImportError: + # that module is also completely optional + pass + + try: + cov.report(morfs, + omit_prefixes=prefixes, + show_missing=opts.show_missing) + except TypeError: + # Coverage 3.4 turned `omit_prefixes` into a list of globbing patterns + cov.report(morfs, + omit=[p + "*" for p in prefixes], + show_missing=opts.show_missing) def test_main(): - import distutils2.tests - from distutils2.tests import run_unittest, reap_children, TestFailed + opts, args = parse_opts() + verbose = not opts.quiet + ret = 0 + + if opts.coverage: + cov = get_coverage() + cov.erase() + cov.start() + if not opts.report: + ret = run_tests(verbose) + if opts.coverage: + cov.stop() + cov.save() + + if opts.report or opts.coverage: + coverage_report(opts) + + return ret + + +def run_tests(verbose): + # do NOT import those at the top level, coverage will be inaccurate if + # modules are imported before its magic is started + from distutils2.tests import run_unittest, test_suite, reap_children, TestFailed from distutils2._backport.tests import test_suite as btest_suite - # XXX just supporting -q right now to enable detailed/quiet output - if len(sys.argv) > 1: - verbose = sys.argv[-1] != '-q' - else: - verbose = 1 try: try: - run_unittest([distutils2.tests.test_suite(), btest_suite()], - verbose_=verbose) + run_unittest([test_suite(), btest_suite()], verbose_=verbose) return 0 except TestFailed: return 1 @@ -28,9 +130,10 @@ if __name__ == "__main__": - try: - from distutils2.tests.support import unittest - except ImportError: - sys.stderr.write('Error: You have to install unittest2') - sys.exit(1) + if sys.version < '2.5': + try: + from distutils2._backport import hashlib + except ImportError: + import subprocess + subprocess.call([sys.executable, 'setup.py', 'build_ext']) sys.exit(test_main()) diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -210,14 +210,14 @@ setup(name="Distutils2", version=VERSION, - summary="Python Distribution Utilities", + description="Python Distribution Utilities", keywords=['packaging', 'distutils'], author="Tarek Ziade", author_email="tarek at ziade.org", - home_page="http://bitbucket.org/tarek/distutils2/wiki/Home", + url="http://bitbucket.org/tarek/distutils2/wiki/Home", license="PSF", - description=README, - classifier=_CLASSIFIERS.split('\n'), + long_description=README, + classifiers=_CLASSIFIERS.split('\n'), packages=find_packages(), cmdclass={'sdist_hg': sdist_hg, 'install_hg': install_hg}, package_data={'distutils2._backport': ['sysconfig.cfg']}, -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 00:57:27 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 00:57:27 +0200 (CEST) Subject: [Python-checkins] r85152 - tracker/instances/python-dev/config.ini.template Message-ID: <20101001225727.01CC7EE9EC@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 00:57:26 2010 New Revision: 85152 Log: Add django settings to template. Modified: tracker/instances/python-dev/config.ini.template Modified: tracker/instances/python-dev/config.ini.template ============================================================================== --- tracker/instances/python-dev/config.ini.template (original) +++ tracker/instances/python-dev/config.ini.template Sat Oct 2 00:57:26 2010 @@ -381,3 +381,7 @@ # each recipient as a CC address. # Default: single email_sending = multiple + +[django] +# generate on a per-instance basis +secret_key = 'el at 4s$*(idwm5-87teftxlksckmy8$tyo7(tm!n-5x)zeuheex' From benjamin at python.org Sat Oct 2 01:06:37 2010 From: benjamin at python.org (Benjamin Peterson) Date: Fri, 1 Oct 2010 18:06:37 -0500 Subject: [Python-checkins] r85152 - tracker/instances/python-dev/config.ini.template In-Reply-To: <20101001225727.01CC7EE9EC@mail.python.org> References: <20101001225727.01CC7EE9EC@mail.python.org> Message-ID: 2010/10/1 martin.v.loewis : > Author: martin.v.loewis > Date: Sat Oct ?2 00:57:26 2010 > New Revision: 85152 > > Log: > Add django settings to template. > > > Modified: > ? tracker/instances/python-dev/config.ini.template > > Modified: tracker/instances/python-dev/config.ini.template > ============================================================================== > --- tracker/instances/python-dev/config.ini.template ? ?(original) > +++ tracker/instances/python-dev/config.ini.template ? ?Sat Oct ?2 00:57:26 2010 > @@ -381,3 +381,7 @@ > ?# each recipient as a CC address. > ?# Default: single > ?email_sending = multiple > + > +[django] > +# generate on a per-instance basis > +secret_key = 'el at 4s$*(idwm5-87teftxlksckmy8$tyo7(tm!n-5x)zeuheex' I assume the secrecy of this is rather irrelevant? -- Regards, Benjamin From python-checkins at python.org Sat Oct 2 01:42:24 2010 From: python-checkins at python.org (amaury.forgeotdarc) Date: Sat, 2 Oct 2010 01:42:24 +0200 (CEST) Subject: [Python-checkins] r85153 - python/branches/py3k/Doc/library/urllib.request.rst Message-ID: <20101001234224.DBD02EE988@mail.python.org> Author: amaury.forgeotdarc Date: Sat Oct 2 01:42:24 2010 New Revision: 85153 Log: Lower the tone of the warning about SSL certificate validation. Modified: python/branches/py3k/Doc/library/urllib.request.rst Modified: python/branches/py3k/Doc/library/urllib.request.rst ============================================================================== --- python/branches/py3k/Doc/library/urllib.request.rst (original) +++ python/branches/py3k/Doc/library/urllib.request.rst Sat Oct 2 01:42:24 2010 @@ -11,9 +11,6 @@ opening URLs (mostly HTTP) in a complex world --- basic and digest authentication, redirections, cookies and more. -.. warning:: When opening HTTPS (or FTPS) URLs, it is not attempted to - validate the server certificate. Use at your own risk! - The :mod:`urllib.request` module defines the following functions: @@ -23,6 +20,10 @@ Open the URL *url*, which can be either a string or a :class:`Request` object. + .. warning:: + HTTPS (or FTPS) requests do not do any verification of the server's + certificate. + *data* may be a string specifying additional data to send to the server, or ``None`` if no such data is needed. Currently HTTP requests are the only ones that use *data*; the HTTP request will From python-checkins at python.org Sat Oct 2 02:03:31 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 2 Oct 2010 02:03:31 +0200 (CEST) Subject: [Python-checkins] r85154 - in python/branches/py3k: Lib/test/test_abc.py Misc/NEWS Objects/typeobject.c Message-ID: <20101002000331.B7389EE9EC@mail.python.org> Author: benjamin.peterson Date: Sat Oct 2 02:03:31 2010 New Revision: 85154 Log: type.__abstractmethods__ should raise an AttributeError #10006 Modified: python/branches/py3k/Lib/test/test_abc.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/typeobject.c Modified: python/branches/py3k/Lib/test/test_abc.py ============================================================================== --- python/branches/py3k/Lib/test/test_abc.py (original) +++ python/branches/py3k/Lib/test/test_abc.py Sat Oct 2 02:03:31 2010 @@ -98,6 +98,13 @@ self.assertRaises(TypeError, F) # because bar is abstract now self.assertTrue(isabstract(F)) + def test_type_has_no_abstractmethods(self): + # type pretends not to have __abstractmethods__. + self.assertRaises(AttributeError, getattr, type, "__abstractmethods__") + class meta(type): + pass + self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__") + def test_registration_basics(self): class A(metaclass=abc.ABCMeta): pass Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Oct 2 02:03:31 2010 @@ -10,6 +10,8 @@ Core and Builtins ----------------- +- Issue #10006: type.__abstractmethods__ now raises an AttributeError. + - Issue #10003: Allow handling of SIGBREAK on Windows. Fixes a regression introduced by issue #9324. Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Sat Oct 2 02:03:31 2010 @@ -320,8 +320,11 @@ static PyObject * type_abstractmethods(PyTypeObject *type, void *context) { - PyObject *mod = PyDict_GetItemString(type->tp_dict, - "__abstractmethods__"); + PyObject *mod = NULL; + /* type its self has an __abstractmethods__ descriptor (this). Don't + return that. */ + if (type != &PyType_Type) + mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__"); if (!mod) { PyErr_Format(PyExc_AttributeError, "__abstractmethods__"); return NULL; From python-checkins at python.org Sat Oct 2 02:08:58 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 2 Oct 2010 02:08:58 +0200 (CEST) Subject: [Python-checkins] r85155 - in python/branches/release27-maint: Lib/test/test_abc.py Misc/NEWS Objects/typeobject.c Message-ID: <20101002000858.70113EE9CD@mail.python.org> Author: benjamin.peterson Date: Sat Oct 2 02:08:58 2010 New Revision: 85155 Log: Merged revisions 85154 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85154 | benjamin.peterson | 2010-10-01 19:03:31 -0500 (Fri, 01 Oct 2010) | 1 line type.__abstractmethods__ should raise an AttributeError #10006 ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Lib/test/test_abc.py python/branches/release27-maint/Misc/NEWS python/branches/release27-maint/Objects/typeobject.c Modified: python/branches/release27-maint/Lib/test/test_abc.py ============================================================================== --- python/branches/release27-maint/Lib/test/test_abc.py (original) +++ python/branches/release27-maint/Lib/test/test_abc.py Sat Oct 2 02:08:58 2010 @@ -70,6 +70,13 @@ self.assertFalse(issubclass(OldstyleClass, A)) self.assertFalse(issubclass(A, OldstyleClass)) + def test_type_has_no_abstractmethods(self): + # type pretends not to have __abstractmethods__. + self.assertRaises(AttributeError, getattr, type, "__abstractmethods__") + class meta(type): + pass + self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__") + def test_isinstance_class(self): class A: __metaclass__ = abc.ABCMeta Modified: python/branches/release27-maint/Misc/NEWS ============================================================================== --- python/branches/release27-maint/Misc/NEWS (original) +++ python/branches/release27-maint/Misc/NEWS Sat Oct 2 02:08:58 2010 @@ -17,6 +17,8 @@ fixes an interpreter crash when initializing an instance of a long subclass from an object whose __long__ method returns a plain int. +- Issue #10006: type.__abstractmethods__ now raises an AttributeError. + - Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid thread-local storage key. Modified: python/branches/release27-maint/Objects/typeobject.c ============================================================================== --- python/branches/release27-maint/Objects/typeobject.c (original) +++ python/branches/release27-maint/Objects/typeobject.c Sat Oct 2 02:08:58 2010 @@ -307,8 +307,11 @@ static PyObject * type_abstractmethods(PyTypeObject *type, void *context) { - PyObject *mod = PyDict_GetItemString(type->tp_dict, - "__abstractmethods__"); + PyObject *mod = NULL; + /* type its self has an __abstractmethods__ descriptor (this). Don't + return that. */ + if (type != &PyType_Type) + mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__"); if (!mod) { PyErr_Format(PyExc_AttributeError, "__abstractmethods__"); return NULL; From python-checkins at python.org Sat Oct 2 02:15:31 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 02:15:31 +0200 Subject: [Python-checkins] distutils2: added the package_dir conversion Message-ID: tarek.ziade pushed 98c67c12fc3e to distutils2: http://hg.python.org/distutils2/rev/98c67c12fc3e changeset: 730:98c67c12fc3e tag: tip user: Tarek Ziade date: Sat Oct 02 02:15:25 2010 +0200 summary: added the package_dir conversion files: distutils2/config.py, distutils2/tests/test_config.py diff --git a/distutils2/config.py b/distutils2/config.py --- a/distutils2/config.py +++ b/distutils2/config.py @@ -102,11 +102,21 @@ if 'files' in parser.sections(): files = dict([(key, self._multiline(value)) for key, value in parser.items('files')]) - self.dist.packages = files.get('packages', []) + self.dist.packages = [] + self.dist.package_dir = {} + + for package in files.get('packages', []): + if ':' in package: + dir_, package = package.split(':') + self.dist.package_dir[package] = dir_ + self.dist.packages.append(package) + self.dist.py_modules = files.get('py_modules', []) if isinstance(self.dist.py_modules, str): self.dist.py_modules = [self.dist.py_modules] self.dist.scripts = files.get('scripts', []) + if isinstance(self.dist.scripts, str): + self.dist.scripts = [self.dist.scripts] self.dist.package_data = {} for data in files.get('package_data', []): diff --git a/distutils2/tests/test_config.py b/distutils2/tests/test_config.py --- a/distutils2/tests/test_config.py +++ b/distutils2/tests/test_config.py @@ -48,8 +48,9 @@ [files] packages = one - two - three + src:two + src2:three + py_modules = haven scripts = @@ -138,6 +139,7 @@ [('bitmaps ', ['bm/b1.gif', 'bm/b2.gif']), ('config ', ['cfg/data.cfg']), ('/etc/init.d ', ['init-script'])]) + self.assertEqual(dist.package_dir['two'], 'src') def test_suite(): -- Repository URL: http://hg.python.org/distutils2 From solipsis at pitrou.net Sat Oct 2 04:47:12 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 02 Oct 2010 04:47:12 +0200 Subject: [Python-checkins] Daily py3k reference leaks (r85154): sum=0 Message-ID: py3k results for svn r85154 (hg cset a88fe908dfab) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogkwt4aN', '-x'] From python-checkins at python.org Sat Oct 2 05:16:04 2010 From: python-checkins at python.org (senthil.kumaran) Date: Sat, 2 Oct 2010 05:16:04 +0200 (CEST) Subject: [Python-checkins] r85156 - in python/branches/py3k/Doc: library/stdtypes.rst reference/datamodel.rst Message-ID: <20101002031604.8AEBAEE9FA@mail.python.org> Author: senthil.kumaran Date: Sat Oct 2 05:16:04 2010 New Revision: 85156 Log: Fix - issue10010 .. index:: position in the docs. Modified: python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/reference/datamodel.rst Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Sat Oct 2 05:16:04 2010 @@ -1592,6 +1592,22 @@ Note that while lists allow their items to be of any type, bytearray object "items" are all integers in the range 0 <= x < 256. +.. index:: + triple: operations on; sequence; types + triple: operations on; list; type + pair: subscript; assignment + pair: slice; assignment + statement: del + single: append() (sequence method) + single: extend() (sequence method) + single: count() (sequence method) + single: index() (sequence method) + single: insert() (sequence method) + single: pop() (sequence method) + single: remove() (sequence method) + single: reverse() (sequence method) + single: sort() (sequence method) + +------------------------------+--------------------------------+---------------------+ | Operation | Result | Notes | +==============================+================================+=====================+ @@ -1636,21 +1652,6 @@ | ``s.sort([key[, reverse]])`` | sort the items of *s* in place | (6), (7), (8) | +------------------------------+--------------------------------+---------------------+ -.. index:: - triple: operations on; sequence; types - triple: operations on; list; type - pair: subscript; assignment - pair: slice; assignment - statement: del - single: append() (sequence method) - single: extend() (sequence method) - single: count() (sequence method) - single: index() (sequence method) - single: insert() (sequence method) - single: pop() (sequence method) - single: remove() (sequence method) - single: reverse() (sequence method) - single: sort() (sequence method) Notes: Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Sat Oct 2 05:16:04 2010 @@ -816,6 +816,22 @@ objects, code objects are immutable and contain no references (directly or indirectly) to mutable objects. + .. index:: + single: co_argcount (code object attribute) + single: co_code (code object attribute) + single: co_consts (code object attribute) + single: co_filename (code object attribute) + single: co_firstlineno (code object attribute) + single: co_flags (code object attribute) + single: co_lnotab (code object attribute) + single: co_name (code object attribute) + single: co_names (code object attribute) + single: co_nlocals (code object attribute) + single: co_stacksize (code object attribute) + single: co_varnames (code object attribute) + single: co_cellvars (code object attribute) + single: co_freevars (code object attribute) + Special read-only attributes: :attr:`co_name` gives the function name; :attr:`co_argcount` is the number of positional arguments (including arguments with default values); :attr:`co_nlocals` is the number of local variables used @@ -833,22 +849,6 @@ :attr:`co_stacksize` is the required stack size (including local variables); :attr:`co_flags` is an integer encoding a number of flags for the interpreter. - .. index:: - single: co_argcount (code object attribute) - single: co_code (code object attribute) - single: co_consts (code object attribute) - single: co_filename (code object attribute) - single: co_firstlineno (code object attribute) - single: co_flags (code object attribute) - single: co_lnotab (code object attribute) - single: co_name (code object attribute) - single: co_names (code object attribute) - single: co_nlocals (code object attribute) - single: co_stacksize (code object attribute) - single: co_varnames (code object attribute) - single: co_cellvars (code object attribute) - single: co_freevars (code object attribute) - .. index:: object: generator The following flag bits are defined for :attr:`co_flags`: bit ``0x04`` is set if From python-checkins at python.org Sat Oct 2 05:25:12 2010 From: python-checkins at python.org (senthil.kumaran) Date: Sat, 2 Oct 2010 05:25:12 +0200 (CEST) Subject: [Python-checkins] r85157 - in python/branches/release31-maint: Doc/library/stdtypes.rst Doc/reference/datamodel.rst Message-ID: <20101002032512.D4F5DEE984@mail.python.org> Author: senthil.kumaran Date: Sat Oct 2 05:25:12 2010 New Revision: 85157 Log: Merged revisions 85156 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85156 | senthil.kumaran | 2010-10-02 08:46:04 +0530 (Sat, 02 Oct 2010) | 3 lines Fix - issue10010 .. index:: position in the docs. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/stdtypes.rst python/branches/release31-maint/Doc/reference/datamodel.rst Modified: python/branches/release31-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release31-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release31-maint/Doc/library/stdtypes.rst Sat Oct 2 05:25:12 2010 @@ -1409,6 +1409,22 @@ Note that while lists allow their items to be of any type, bytearray object "items" are all integers in the range 0 <= x < 256. +.. index:: + triple: operations on; sequence; types + triple: operations on; list; type + pair: subscript; assignment + pair: slice; assignment + statement: del + single: append() (sequence method) + single: extend() (sequence method) + single: count() (sequence method) + single: index() (sequence method) + single: insert() (sequence method) + single: pop() (sequence method) + single: remove() (sequence method) + single: reverse() (sequence method) + single: sort() (sequence method) + +------------------------------+--------------------------------+---------------------+ | Operation | Result | Notes | +==============================+================================+=====================+ @@ -1453,21 +1469,6 @@ | ``s.sort([key[, reverse]])`` | sort the items of *s* in place | (6), (7), (8) | +------------------------------+--------------------------------+---------------------+ -.. index:: - triple: operations on; sequence; types - triple: operations on; list; type - pair: subscript; assignment - pair: slice; assignment - statement: del - single: append() (sequence method) - single: extend() (sequence method) - single: count() (sequence method) - single: index() (sequence method) - single: insert() (sequence method) - single: pop() (sequence method) - single: remove() (sequence method) - single: reverse() (sequence method) - single: sort() (sequence method) Notes: Modified: python/branches/release31-maint/Doc/reference/datamodel.rst ============================================================================== --- python/branches/release31-maint/Doc/reference/datamodel.rst (original) +++ python/branches/release31-maint/Doc/reference/datamodel.rst Sat Oct 2 05:25:12 2010 @@ -816,6 +816,22 @@ objects, code objects are immutable and contain no references (directly or indirectly) to mutable objects. + .. index:: + single: co_argcount (code object attribute) + single: co_code (code object attribute) + single: co_consts (code object attribute) + single: co_filename (code object attribute) + single: co_firstlineno (code object attribute) + single: co_flags (code object attribute) + single: co_lnotab (code object attribute) + single: co_name (code object attribute) + single: co_names (code object attribute) + single: co_nlocals (code object attribute) + single: co_stacksize (code object attribute) + single: co_varnames (code object attribute) + single: co_cellvars (code object attribute) + single: co_freevars (code object attribute) + Special read-only attributes: :attr:`co_name` gives the function name; :attr:`co_argcount` is the number of positional arguments (including arguments with default values); :attr:`co_nlocals` is the number of local variables used @@ -833,22 +849,6 @@ :attr:`co_stacksize` is the required stack size (including local variables); :attr:`co_flags` is an integer encoding a number of flags for the interpreter. - .. index:: - single: co_argcount (code object attribute) - single: co_code (code object attribute) - single: co_consts (code object attribute) - single: co_filename (code object attribute) - single: co_firstlineno (code object attribute) - single: co_flags (code object attribute) - single: co_lnotab (code object attribute) - single: co_name (code object attribute) - single: co_names (code object attribute) - single: co_nlocals (code object attribute) - single: co_stacksize (code object attribute) - single: co_varnames (code object attribute) - single: co_cellvars (code object attribute) - single: co_freevars (code object attribute) - .. index:: object: generator The following flag bits are defined for :attr:`co_flags`: bit ``0x04`` is set if From python-checkins at python.org Sat Oct 2 05:29:31 2010 From: python-checkins at python.org (senthil.kumaran) Date: Sat, 2 Oct 2010 05:29:31 +0200 (CEST) Subject: [Python-checkins] r85158 - in python/branches/release27-maint: Doc/library/stdtypes.rst Doc/reference/datamodel.rst Message-ID: <20101002032931.57251EE984@mail.python.org> Author: senthil.kumaran Date: Sat Oct 2 05:29:31 2010 New Revision: 85158 Log: Merged revisions 85156 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85156 | senthil.kumaran | 2010-10-02 08:46:04 +0530 (Sat, 02 Oct 2010) | 3 lines Fix - issue10010 .. index:: position in the docs. ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Doc/library/stdtypes.rst python/branches/release27-maint/Doc/reference/datamodel.rst Modified: python/branches/release27-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release27-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release27-maint/Doc/library/stdtypes.rst Sat Oct 2 05:29:31 2010 @@ -1499,6 +1499,23 @@ such objects cannot be modified once created. The following operations are defined on mutable sequence types (where *x* is an arbitrary object): +.. index:: + triple: operations on; sequence; types + triple: operations on; list; type + pair: subscript; assignment + pair: slice; assignment + pair: extended slice; assignment + statement: del + single: append() (list method) + single: extend() (list method) + single: count() (list method) + single: index() (list method) + single: insert() (list method) + single: pop() (list method) + single: remove() (list method) + single: reverse() (list method) + single: sort() (list method) + +------------------------------+--------------------------------+---------------------+ | Operation | Result | Notes | +==============================+================================+=====================+ @@ -1544,23 +1561,6 @@ | reverse]]])`` | | | +------------------------------+--------------------------------+---------------------+ -.. index:: - triple: operations on; sequence; types - triple: operations on; list; type - pair: subscript; assignment - pair: slice; assignment - pair: extended slice; assignment - statement: del - single: append() (list method) - single: extend() (list method) - single: count() (list method) - single: index() (list method) - single: insert() (list method) - single: pop() (list method) - single: remove() (list method) - single: reverse() (list method) - single: sort() (list method) - Notes: (1) Modified: python/branches/release27-maint/Doc/reference/datamodel.rst ============================================================================== --- python/branches/release27-maint/Doc/reference/datamodel.rst (original) +++ python/branches/release27-maint/Doc/reference/datamodel.rst Sat Oct 2 05:29:31 2010 @@ -908,6 +908,22 @@ objects, code objects are immutable and contain no references (directly or indirectly) to mutable objects. + .. index:: + single: co_argcount (code object attribute) + single: co_code (code object attribute) + single: co_consts (code object attribute) + single: co_filename (code object attribute) + single: co_firstlineno (code object attribute) + single: co_flags (code object attribute) + single: co_lnotab (code object attribute) + single: co_name (code object attribute) + single: co_names (code object attribute) + single: co_nlocals (code object attribute) + single: co_stacksize (code object attribute) + single: co_varnames (code object attribute) + single: co_cellvars (code object attribute) + single: co_freevars (code object attribute) + Special read-only attributes: :attr:`co_name` gives the function name; :attr:`co_argcount` is the number of positional arguments (including arguments with default values); :attr:`co_nlocals` is the number of local variables used @@ -925,22 +941,6 @@ :attr:`co_stacksize` is the required stack size (including local variables); :attr:`co_flags` is an integer encoding a number of flags for the interpreter. - .. index:: - single: co_argcount (code object attribute) - single: co_code (code object attribute) - single: co_consts (code object attribute) - single: co_filename (code object attribute) - single: co_firstlineno (code object attribute) - single: co_flags (code object attribute) - single: co_lnotab (code object attribute) - single: co_name (code object attribute) - single: co_names (code object attribute) - single: co_nlocals (code object attribute) - single: co_stacksize (code object attribute) - single: co_varnames (code object attribute) - single: co_cellvars (code object attribute) - single: co_freevars (code object attribute) - .. index:: object: generator The following flag bits are defined for :attr:`co_flags`: bit ``0x04`` is set if From python-checkins at python.org Sat Oct 2 08:17:04 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 08:17:04 +0200 (CEST) Subject: [Python-checkins] r85159 - tracker/instances/python-dev/detectors/rietveldreactor.py Message-ID: <20101002061704.486E0EEA2F@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 08:17:03 2010 New Revision: 85159 Log: Create django users and rietveld issues on creation of respective roundup objects. Added: tracker/instances/python-dev/detectors/rietveldreactor.py (contents, props changed) Added: tracker/instances/python-dev/detectors/rietveldreactor.py ============================================================================== --- (empty file) +++ tracker/instances/python-dev/detectors/rietveldreactor.py Sat Oct 2 08:17:03 2010 @@ -0,0 +1,29 @@ +import cPickle, base64 + +# ListProperty is initialized to the cPickle of an empty list +empty_list = base64.encodestring(cPickle.dumps([])) + +def create_django_user(db, cl, nodeid, oldvalues): + username = cl.get(nodeid, 'username') + email = cl.get(nodeid, 'address') + c = db.cursor + # django.contrib.auth.models.UNUSABLE_PASSWORD=='!' + c.execute("insert into auth_user(id, username, email, password, first_name, last_name, " + "is_staff, is_active, is_superuser, last_login, date_joined) " + "values(%s, %s, %s, '!', '', '', false, true, false, now(), now())", + (nodeid, username, email)) + +def create_rietveld_issue(db, cl, nodeid, oldvalues): + subject = cl.get(nodeid, 'title') + c = db.cursor + # find owner id: same in django as in rietveld + owner_id = cl.get(nodeid, 'creator') + c.execute("insert into codereview_issue(id, subject, owner_id, reviewers, cc, created, modified, closed, private, n_comments) " + "values(%s, %s, %s, %s, %s, now(), now(), false, false, 0)", + (nodeid, subject, owner_id, empty_list, empty_list)) + +def init(db): + db.user.react('create', create_django_user) + # XXX react to email changes, roles + db.issue.react('create', create_rietveld_issue) + # XXX reacto to subject, closed changes From python-checkins at python.org Sat Oct 2 08:18:36 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 08:18:36 +0200 (CEST) Subject: [Python-checkins] r85160 - in tracker/instances/python-dev: lib/rietveld rietveld Message-ID: <20101002061836.7CBF2EEA49@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 08:18:36 2010 New Revision: 85160 Log: Move rietveld out of lib, as it won't be used from roundup, anyway. Added: tracker/instances/python-dev/rietveld/ - copied from r85158, /tracker/instances/python-dev/lib/rietveld/ Removed: tracker/instances/python-dev/lib/rietveld/ From python-checkins at python.org Sat Oct 2 08:24:05 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 08:24:05 +0200 (CEST) Subject: [Python-checkins] r85161 - in tracker/instances/python-dev/rietveld: Makefile patches rietveld_helper settings.py Message-ID: <20101002062405.70BE6E32D@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 08:24:05 2010 New Revision: 85161 Log: Adjust to relocation. Added: tracker/instances/python-dev/rietveld/patches (contents, props changed) tracker/instances/python-dev/rietveld/rietveld_helper (contents, props changed) Modified: tracker/instances/python-dev/rietveld/ (props changed) tracker/instances/python-dev/rietveld/Makefile tracker/instances/python-dev/rietveld/settings.py Modified: tracker/instances/python-dev/rietveld/Makefile ============================================================================== --- tracker/instances/python-dev/rietveld/Makefile (original) +++ tracker/instances/python-dev/rietveld/Makefile Sat Oct 2 08:24:05 2010 @@ -3,7 +3,7 @@ default: @echo "Run 'make all' to fetch required sources to run this example." -all: static templates codereview django gae2django dev.db +all: static templates codereview django gae2django syncdb @echo "Run './manage.py runserver 127.0.0.1:8000' to run Rietveld." clean: clean_local clean_external @@ -18,10 +18,9 @@ clean_local: unlink gae2django - rm -f dev.db gae2django: - ln -s ../../gae2django/gae2django . + ln -s ../gae2django/gae2django . syncdb: ./manage.py syncdb @@ -37,4 +36,4 @@ svn co http://rietveld.googlecode.com/svn/trunk/templates@$(RIETVELDREV) templates_svn django: - ln -s ../../gae2django/django . + ln -s ../gae2django/django . Added: tracker/instances/python-dev/rietveld/patches ============================================================================== --- (empty file) +++ tracker/instances/python-dev/rietveld/patches Sat Oct 2 08:24:05 2010 @@ -0,0 +1 @@ +link ../gae2django/examples/rietveld/patches \ No newline at end of file Added: tracker/instances/python-dev/rietveld/rietveld_helper ============================================================================== --- (empty file) +++ tracker/instances/python-dev/rietveld/rietveld_helper Sat Oct 2 08:24:05 2010 @@ -0,0 +1 @@ +link ../gae2django/examples/rietveld/rietveld_helper \ No newline at end of file Modified: tracker/instances/python-dev/rietveld/settings.py ============================================================================== --- tracker/instances/python-dev/rietveld/settings.py (original) +++ tracker/instances/python-dev/rietveld/settings.py Sat Oct 2 08:24:05 2010 @@ -14,7 +14,7 @@ MANAGERS = ADMINS _c = ConfigParser.ConfigParser({'password':'', 'port':''}) -_c.read(os.path.dirname(__file__)+"/../../config.ini") +_c.read(os.path.dirname(__file__)+"/../config.ini") DATABASE_ENGINE = 'postgresql_psycopg2' DATABASE_NAME = _c.get('rdbms', 'name') From python-checkins at python.org Sat Oct 2 08:56:58 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 08:56:58 +0200 (CEST) Subject: [Python-checkins] r85162 - in tracker/instances/python-dev/rietveld: Makefile codereview.diff roundup_helper/middleware.py Message-ID: <20101002065658.312C8EEA39@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 08:56:58 2010 New Revision: 85162 Log: Make roundup users, django users and codereview accounts all have the same IDs. Added: tracker/instances/python-dev/rietveld/codereview.diff (contents, props changed) Modified: tracker/instances/python-dev/rietveld/Makefile tracker/instances/python-dev/rietveld/roundup_helper/middleware.py Modified: tracker/instances/python-dev/rietveld/Makefile ============================================================================== --- tracker/instances/python-dev/rietveld/Makefile (original) +++ tracker/instances/python-dev/rietveld/Makefile Sat Oct 2 08:56:58 2010 @@ -3,7 +3,7 @@ default: @echo "Run 'make all' to fetch required sources to run this example." -all: static templates codereview django gae2django syncdb +all: static templates_svn codereview django gae2django syncdb @echo "Run './manage.py runserver 127.0.0.1:8000' to run Rietveld." clean: clean_local clean_external @@ -27,6 +27,7 @@ codereview: svn co http://rietveld.googlecode.com/svn/trunk/codereview@$(RIETVELDREV) + patch -p0 < codereview.diff static: svn co http://rietveld.googlecode.com/svn/trunk/static@$(RIETVELDREV) Added: tracker/instances/python-dev/rietveld/codereview.diff ============================================================================== --- (empty file) +++ tracker/instances/python-dev/rietveld/codereview.diff Sat Oct 2 08:56:58 2010 @@ -0,0 +1,23 @@ +Index: codereview/models.py +=================================================================== +--- codereview/models.py (Revision 510) ++++ codereview/models.py (Arbeitskopie) +@@ -520,14 +520,14 @@ + @classmethod + def get_account_for_user(cls, user): + """Get the Account for a user, creating a default one if needed.""" +- email = user.email() +- assert email +- key = '<%s>' % email + # Since usually the account already exists, first try getting it + # without the transaction implied by get_or_insert(). +- account = cls.get_by_key_name(key) ++ # Roundup adjustment: accounts will have the same IDs as users ++ account = cls.get_by_id(user.id) + if account is not None: + return account ++ # Not found, don't auto-create in any case ++ raise engine.FetchError('account not found') + nickname = cls.create_nickname_for_user(user) + return cls.get_or_insert(key, user=user, email=email, nickname=nickname, + fresh=True) Modified: tracker/instances/python-dev/rietveld/roundup_helper/middleware.py ============================================================================== --- tracker/instances/python-dev/rietveld/roundup_helper/middleware.py (original) +++ tracker/instances/python-dev/rietveld/roundup_helper/middleware.py Sat Oct 2 08:56:58 2010 @@ -1,17 +1,12 @@ from models import Session, User +from codereview.models import Account from django.contrib import auth from django.contrib.auth.backends import RemoteUserBackend class UserBackend(RemoteUserBackend): - def configure_user(self, user): - roundup_user = User.objects.filter(_username=user.username)[0] - user.email = roundup_user._address - user.save() - from codereview import models - account = models.Account.get_account_for_user(user) - account.nickname = user.username - account.save() - return user + # auto-creation of django users should not be necessary, + # as they should have been created before, so suppress it here. + create_unknown_user = False class LookupRoundupUser(object): @@ -27,21 +22,24 @@ username = eval(session[0].session_value)['user'] # the username comes from the cookie, so it really ought to exist roundup_user = User.objects.filter(_username=username)[0] - if not roundup_user._address: - # Rietveld insists that user objects must have email addresses - return - # Taken from RemoteUserMiddleware: auto-create the user if it's new + # if we already have a user from the session, we are done. if request.user.is_authenticated(): if request.user.username == username: return - # We are seeing this user for the first time in this session, attempt - # to authenticate the user. + # We see the user for the first time. Authenticate it, and create + # codereview account if none exists. user = auth.authenticate(remote_user=username) - if user: - # User is valid. Set request.user and persist user in the session - # by logging the user in. - request.user = user - auth.login(request, user) + if not user: + return + # User is valid. Set request.user and persist user in the session + # by logging the user in. + request.user = user + account = Account.get_by_id(user.id) + if not account: + account = Account(id=user.id, user=user, email=user.email, + nickname=username, fresh=True) + account.put() + auth.login(request, user) def logout(self, request): # Clear django session if roundup session is gone. From python-checkins at python.org Sat Oct 2 09:04:41 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 09:04:41 +0200 (CEST) Subject: [Python-checkins] r85163 - tracker/instances/python-dev/rietveld/codereview.diff Message-ID: <20101002070441.67A58EE9CA@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 09:04:41 2010 New Revision: 85163 Log: Don't choke on issues without patchsets. Modified: tracker/instances/python-dev/rietveld/codereview.diff Modified: tracker/instances/python-dev/rietveld/codereview.diff ============================================================================== --- tracker/instances/python-dev/rietveld/codereview.diff (original) +++ tracker/instances/python-dev/rietveld/codereview.diff Sat Oct 2 09:04:41 2010 @@ -1,3 +1,16 @@ +Index: codereview/views.py +=================================================================== +--- codereview/views.py (Revision 510) ++++ codereview/views.py (Arbeitskopie) +@@ -1382,6 +1382,8 @@ + issue = request.issue + patchsets = list(issue.patchset_set.order('created')) + response = None ++ if not patchsets: ++ return issue, patchsets, response + if not patchset_id: + patchset_id = patchsets[-1].key().id() + Index: codereview/models.py =================================================================== --- codereview/models.py (Revision 510) From python-checkins at python.org Sat Oct 2 09:46:34 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 09:46:34 +0200 (CEST) Subject: [Python-checkins] r85164 - in tracker/instances/python-dev: detectors/rietveldreactor.py scripts/initrietveld Message-ID: <20101002074634.6A44BEE9CA@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 09:46:34 2010 New Revision: 85164 Log: Import existing users and issues into rietveld. Added: tracker/instances/python-dev/scripts/initrietveld (contents, props changed) Modified: tracker/instances/python-dev/detectors/rietveldreactor.py Modified: tracker/instances/python-dev/detectors/rietveldreactor.py ============================================================================== --- tracker/instances/python-dev/detectors/rietveldreactor.py (original) +++ tracker/instances/python-dev/detectors/rietveldreactor.py Sat Oct 2 09:46:34 2010 @@ -6,6 +6,8 @@ def create_django_user(db, cl, nodeid, oldvalues): username = cl.get(nodeid, 'username') email = cl.get(nodeid, 'address') + if email is None: + email = '' c = db.cursor # django.contrib.auth.models.UNUSABLE_PASSWORD=='!' c.execute("insert into auth_user(id, username, email, password, first_name, last_name, " Added: tracker/instances/python-dev/scripts/initrietveld ============================================================================== --- (empty file) +++ tracker/instances/python-dev/scripts/initrietveld Sat Oct 2 09:46:34 2010 @@ -0,0 +1,32 @@ +#!/usr/bin/python +# Create Rietveld users and issues +import rietveldreactor +import roundup.instance +tracker = roundup.instance.open('.') +db = tracker.open('admin') + +# Need to widen username, as some roundup names are too long +widen_username = """ +begin; +alter table auth_user add username2 varchar(50); +update auth_user set username2=username; +alter table auth_user drop username; +alter table auth_user add username varchar(50); +update auth_user set username=username2; +commit; +""" + +c = db.cursor +for userid in db.user.getnodeids(): + c.execute("select count(*) from auth_user where id=%s", (userid,)) + if c.fetchone()[0] == 1: + continue + rietveldreactor.create_django_user(db, db.user, userid, None) + db.commit() + +for issue in db.issue.list(): + c.execute("select count(*) from codereview_issue where id=%s", (issue,)) + if c.fetchone()[0] == 1: + continue + rietveldreactor.create_rietveld_issue(db, db.issue, issue, None) + db.commit() From python-checkins at python.org Sat Oct 2 11:31:23 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 11:31:23 +0200 (CEST) Subject: [Python-checkins] r85165 - tracker/instances/python-dev/rietveld.wsgi Message-ID: <20101002093123.6E636EEA49@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 11:31:23 2010 New Revision: 85165 Log: Add mod_wsgi script Added: tracker/instances/python-dev/rietveld.wsgi (contents, props changed) Added: tracker/instances/python-dev/rietveld.wsgi ============================================================================== --- (empty file) +++ tracker/instances/python-dev/rietveld.wsgi Sat Oct 2 11:31:23 2010 @@ -0,0 +1,8 @@ +import os, sys +sys.path.append('/home/roundup/trackers/tracker/rietveld') +os.environ['DJANGO_SETTINGS_MODULE']='settings' +import django.core.handlers.wsgi +import gae2django +gae2django.install(server_software='Django') +application = django.core.handlers.wsgi.WSGIHandler() + From python-checkins at python.org Sat Oct 2 11:31:42 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 11:31:42 +0200 (CEST) Subject: [Python-checkins] r85166 - in tracker/instances/python-dev/rietveld: settings.py templates/base.html templates/issue_base.html Message-ID: <20101002093142.41D08EEA39@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 11:31:41 2010 New Revision: 85166 Log: Adjust to bugs.python.org. Modified: tracker/instances/python-dev/rietveld/settings.py tracker/instances/python-dev/rietveld/templates/base.html tracker/instances/python-dev/rietveld/templates/issue_base.html Modified: tracker/instances/python-dev/rietveld/settings.py ============================================================================== --- tracker/instances/python-dev/rietveld/settings.py (original) +++ tracker/instances/python-dev/rietveld/settings.py Sat Oct 2 11:31:41 2010 @@ -79,7 +79,7 @@ 'django.core.context_processors.request', ) -ROOT_URLCONF = 'roundup_helper.urls' +ROOT_URLCONF = 'rietveld_helper.urls' TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), 'templates'), Modified: tracker/instances/python-dev/rietveld/templates/base.html ============================================================================== --- tracker/instances/python-dev/rietveld/templates/base.html (original) +++ tracker/instances/python-dev/rietveld/templates/base.html Sat Oct 2 11:31:41 2010 @@ -185,9 +185,9 @@ href="http://code.google.com/p/rietveld">Source code | {%if user%} -Sign out +Sign out {% else %} -Sign in +Sign in {%endif%} Modified: tracker/instances/python-dev/rietveld/templates/issue_base.html ============================================================================== --- tracker/instances/python-dev/rietveld/templates/issue_base.html (original) +++ tracker/instances/python-dev/rietveld/templates/issue_base.html Sat Oct 2 11:31:41 2010 @@ -22,7 +22,7 @@ {%else%} Recent Issues | - Sign in + Sign in with your traccer account to create issues and add comments {%endif%} {%endblock%} From python-checkins at python.org Sat Oct 2 11:41:00 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 11:41:00 +0200 (CEST) Subject: [Python-checkins] r85167 - in tracker/instances/python-dev/rietveld: roundup_helper/middleware.py settings.py Message-ID: <20101002094100.4CF4BEE9B5@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 11:40:59 2010 New Revision: 85167 Log: Fetch cookie name from config.ini. Modified: tracker/instances/python-dev/rietveld/ (props changed) tracker/instances/python-dev/rietveld/roundup_helper/middleware.py tracker/instances/python-dev/rietveld/settings.py Modified: tracker/instances/python-dev/rietveld/roundup_helper/middleware.py ============================================================================== --- tracker/instances/python-dev/rietveld/roundup_helper/middleware.py (original) +++ tracker/instances/python-dev/rietveld/roundup_helper/middleware.py Sat Oct 2 11:40:59 2010 @@ -1,5 +1,6 @@ from models import Session, User from codereview.models import Account +from django.conf import settings from django.contrib import auth from django.contrib.auth.backends import RemoteUserBackend @@ -11,7 +12,7 @@ class LookupRoundupUser(object): def process_request(self, request): - session_key = request.COOKIES.get('roundup_session_Tracker', None) + session_key = request.COOKIES.get(settings.TRACKER_COOKIE_NAME, None) if not session_key: self.logout(request) return Modified: tracker/instances/python-dev/rietveld/settings.py ============================================================================== --- tracker/instances/python-dev/rietveld/settings.py (original) +++ tracker/instances/python-dev/rietveld/settings.py Sat Oct 2 11:40:59 2010 @@ -2,7 +2,7 @@ # NOTE: Keep the settings.py in examples directories in sync with this one! -import os, ConfigParser +import os, ConfigParser, re DEBUG = True TEMPLATE_DEBUG = DEBUG @@ -15,6 +15,7 @@ _c = ConfigParser.ConfigParser({'password':'', 'port':''}) _c.read(os.path.dirname(__file__)+"/../config.ini") +TRACKER_COOKIE_NAME=re.sub('[^a-zA-Z]', '', _c.get('tracker','name')) DATABASE_ENGINE = 'postgresql_psycopg2' DATABASE_NAME = _c.get('rdbms', 'name') From python-checkins at python.org Sat Oct 2 12:14:25 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 12:14:25 +0200 (CEST) Subject: [Python-checkins] r85168 - in tracker/instances/python-dev: rietveld.wsgi rietveld/roundup_helper/urls.py rietveld/settings.py Message-ID: <20101002101425.86B08D2B0@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 12:14:25 2010 New Revision: 85168 Log: Incorporate SCRIPT_NAME into PATH_INFO for wsgi. Modified: tracker/instances/python-dev/rietveld.wsgi tracker/instances/python-dev/rietveld/roundup_helper/urls.py tracker/instances/python-dev/rietveld/settings.py Modified: tracker/instances/python-dev/rietveld.wsgi ============================================================================== --- tracker/instances/python-dev/rietveld.wsgi (original) +++ tracker/instances/python-dev/rietveld.wsgi Sat Oct 2 12:14:25 2010 @@ -4,5 +4,15 @@ import django.core.handlers.wsgi import gae2django gae2django.install(server_software='Django') -application = django.core.handlers.wsgi.WSGIHandler() +_application = django.core.handlers.wsgi.WSGIHandler() +def application(environ, start_response): + # Django's {%url%} template won't prefix script_name, + # so clear it here and put everything in path_info + environ['PATH_INFO'] = environ['SCRIPT_NAME']+environ['PATH_INFO'] + environ['SCRIPT_NAME'] = '' + + #start_response('200 Ok', [('Content-type', 'text/plain')]) + #return ["\n".join([':'.join((str(k),str(v))) for k,v in environ.items()])] + + return _application(environ, start_response) Modified: tracker/instances/python-dev/rietveld/roundup_helper/urls.py ============================================================================== --- tracker/instances/python-dev/rietveld/roundup_helper/urls.py (original) +++ tracker/instances/python-dev/rietveld/roundup_helper/urls.py Sat Oct 2 12:14:25 2010 @@ -2,6 +2,5 @@ from django.contrib import admin urlpatterns = patterns('', - ('python-dev/', 'roundup'), ('review/', include('rietveld_helper.urls')), ) Modified: tracker/instances/python-dev/rietveld/settings.py ============================================================================== --- tracker/instances/python-dev/rietveld/settings.py (original) +++ tracker/instances/python-dev/rietveld/settings.py Sat Oct 2 12:14:25 2010 @@ -80,7 +80,7 @@ 'django.core.context_processors.request', ) -ROOT_URLCONF = 'rietveld_helper.urls' +ROOT_URLCONF = 'roundup_helper.urls' TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), 'templates'), From python-checkins at python.org Sat Oct 2 12:33:13 2010 From: python-checkins at python.org (senthil.kumaran) Date: Sat, 2 Oct 2010 12:33:13 +0200 (CEST) Subject: [Python-checkins] r85169 - python/branches/py3k/Lib/http/client.py Message-ID: <20101002103313.B1B8CDA63@mail.python.org> Author: senthil.kumaran Date: Sat Oct 2 12:33:13 2010 New Revision: 85169 Log: Use proper variable name 'data' instead of 'str' in the send method. Modified: python/branches/py3k/Lib/http/client.py Modified: python/branches/py3k/Lib/http/client.py ============================================================================== --- python/branches/py3k/Lib/http/client.py (original) +++ python/branches/py3k/Lib/http/client.py Sat Oct 2 12:33:13 2010 @@ -730,8 +730,8 @@ self.__response = None self.__state = _CS_IDLE - def send(self, str): - """Send `str' to the server.""" + def send(self, data): + """Send `data' to the server.""" if self.sock is None: if self.auto_open: self.connect() @@ -739,14 +739,14 @@ raise NotConnected() if self.debuglevel > 0: - print("send:", repr(str)) + print("send:", repr(data)) blocksize = 8192 - if hasattr(str, "read") : + if hasattr(data, "read") : if self.debuglevel > 0: print("sendIng a read()able") encode = False try: - mode = str.mode + mode = data.mode except AttributeError: # io.BytesIO and other file-like objects don't have a `mode` # attribute. @@ -757,14 +757,14 @@ if self.debuglevel > 0: print("encoding file using iso-8859-1") while 1: - data = str.read(blocksize) - if not data: + datablock = data.read(blocksize) + if not datablock: break if encode: - data = data.encode("iso-8859-1") - self.sock.sendall(data) + datablock = datablock.encode("iso-8859-1") + self.sock.sendall(datablock) else: - self.sock.sendall(str) + self.sock.sendall(data) def _output(self, s): """Add a line of output to the current request buffer. From python-checkins at python.org Sat Oct 2 12:35:24 2010 From: python-checkins at python.org (senthil.kumaran) Date: Sat, 2 Oct 2010 12:35:24 +0200 (CEST) Subject: [Python-checkins] r85170 - in python/branches/release31-maint: Lib/http/client.py Message-ID: <20101002103524.E8222DA63@mail.python.org> Author: senthil.kumaran Date: Sat Oct 2 12:35:24 2010 New Revision: 85170 Log: Merged revisions 85169 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85169 | senthil.kumaran | 2010-10-02 16:03:13 +0530 (Sat, 02 Oct 2010) | 3 lines Use proper variable name 'data' instead of 'str' in the send method. ........ 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 Sat Oct 2 12:35:24 2010 @@ -724,8 +724,8 @@ self.__response = None self.__state = _CS_IDLE - def send(self, str): - """Send `str' to the server.""" + def send(self, data): + """Send `data' to the server.""" if self.sock is None: if self.auto_open: self.connect() @@ -738,14 +738,14 @@ # NOTE: we DO propagate the error, though, because we cannot simply # ignore the error... the caller will know if they can retry. if self.debuglevel > 0: - print("send:", repr(str)) + print("send:", repr(data)) blocksize = 8192 - if hasattr(str, "read") : + if hasattr(data, "read") : if self.debuglevel > 0: print("sendIng a read()able") encode = False try: - mode = str.mode + mode = data.mode except AttributeError: # io.BytesIO and other file-like objects don't have a `mode` # attribute. @@ -756,14 +756,14 @@ if self.debuglevel > 0: print("encoding file using iso-8859-1") while 1: - data = str.read(blocksize) - if not data: + datablock = data.read(blocksize) + if not datablock: break if encode: - data = data.encode("iso-8859-1") - self.sock.sendall(data) + datablock = datablock.encode("iso-8859-1") + self.sock.sendall(datablock) else: - self.sock.sendall(str) + self.sock.sendall(data) def _output(self, s): """Add a line of output to the current request buffer. From python-checkins at python.org Sat Oct 2 12:43:45 2010 From: python-checkins at python.org (senthil.kumaran) Date: Sat, 2 Oct 2010 12:43:45 +0200 (CEST) Subject: [Python-checkins] r85171 - in python/branches/release27-maint: Lib/httplib.py Message-ID: <20101002104345.E73ACDCA4@mail.python.org> Author: senthil.kumaran Date: Sat Oct 2 12:43:45 2010 New Revision: 85171 Log: Merged revisions 85169 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85169 | senthil.kumaran | 2010-10-02 16:03:13 +0530 (Sat, 02 Oct 2010) | 3 lines Use proper variable name 'data' instead of 'str' in the send method. ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Lib/httplib.py Modified: python/branches/release27-maint/Lib/httplib.py ============================================================================== --- python/branches/release27-maint/Lib/httplib.py (original) +++ python/branches/release27-maint/Lib/httplib.py Sat Oct 2 12:43:45 2010 @@ -752,8 +752,8 @@ self.__response = None self.__state = _CS_IDLE - def send(self, str): - """Send `str' to the server.""" + def send(self, data): + """Send `data' to the server.""" if self.sock is None: if self.auto_open: self.connect() @@ -761,16 +761,16 @@ raise NotConnected() if self.debuglevel > 0: - print "send:", repr(str) + print "send:", repr(data) blocksize = 8192 - if hasattr(str,'read') and not isinstance(str, array): + if hasattr(data,'read') and not isinstance(data, array): if self.debuglevel > 0: print "sendIng a read()able" - data = str.read(blocksize) - while data: - self.sock.sendall(data) - data = str.read(blocksize) + datablock = data.read(blocksize) + while datablock: + self.sock.sendall(datablock) + datablock = data.read(blocksize) else: - self.sock.sendall(str) + self.sock.sendall(data) def _output(self, s): """Add a line of output to the current request buffer. @@ -842,9 +842,9 @@ self._method = method if not url: url = '/' - str = '%s %s %s' % (method, url, self._http_vsn_str) + hdr = '%s %s %s' % (method, url, self._http_vsn_str) - self._output(str) + self._output(hdr) if self._http_vsn == 11: # Issue some standard headers for better HTTP/1.1 compliance @@ -915,8 +915,8 @@ if self.__state != _CS_REQ_STARTED: raise CannotSendHeader() - str = '%s: %s' % (header, '\r\n\t'.join(values)) - self._output(str) + hdr = '%s: %s' % (header, '\r\n\t'.join(values)) + self._output(hdr) def endheaders(self, message_body=None): """Indicate that the last header line has been sent to the server. From nnorwitz at gmail.com Sat Oct 2 12:53:33 2010 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 2 Oct 2010 06:53:33 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20101002105333.GA18900@kbk-i386-bb.dyndns.org> More important issues: ---------------------- test_bz2 leaked [-84, 0, 0] references, sum=-84 Less important issues: ---------------------- From python-checkins at python.org Sat Oct 2 13:03:13 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 2 Oct 2010 13:03:13 +0200 (CEST) Subject: [Python-checkins] r85172 - in python/branches/py3k: Doc/c-api/unicode.rst Lib/test/test_unicode.py Modules/_testcapimodule.c Objects/unicodeobject.c Message-ID: <20101002110313.CC8D4D330@mail.python.org> Author: victor.stinner Date: Sat Oct 2 13:03:13 2010 New Revision: 85172 Log: Issue #8870: PyUnicode_AsWideChar() doesn't count the trailing nul character And write unit tests for PyUnicode_AsWideChar() and PyUnicode_AsWideChar(). Modified: python/branches/py3k/Doc/c-api/unicode.rst python/branches/py3k/Lib/test/test_unicode.py python/branches/py3k/Modules/_testcapimodule.c python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Doc/c-api/unicode.rst ============================================================================== --- python/branches/py3k/Doc/c-api/unicode.rst (original) +++ python/branches/py3k/Doc/c-api/unicode.rst Sat Oct 2 13:03:13 2010 @@ -466,7 +466,8 @@ Convert the Unicode object to a wide character string. The output string always ends with a nul character. If *size* is not *NULL*, write the number - of wide characters (including the nul character) into *\*size*. + of wide characters (excluding the trailing 0-termination character) into + *\*size*. Returns a buffer allocated by :cfunc:`PyMem_Alloc` (use :cfunc:`PyMem_Free` to free it) on success. On error, returns *NULL*, *\*size* is undefined and Modified: python/branches/py3k/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicode.py (original) +++ python/branches/py3k/Lib/test/test_unicode.py Sat Oct 2 13:03:13 2010 @@ -1394,6 +1394,45 @@ 'string, got a non-ASCII byte: 0xe9$', format_unicode, b'unicode\xe9=%s', 'ascii') + # Test PyUnicode_AsWideChar() + def test_aswidechar(self): + from _testcapi import test_aswidechar + from ctypes import c_wchar, sizeof + + wchar, size = test_aswidechar('abcdef', 2) + self.assertEquals(size, 2) + self.assertEquals(wchar, 'ab') + + wchar, size = test_aswidechar('abc', 3) + self.assertEquals(size, 3) + self.assertEquals(wchar, 'abc') + + wchar, size = test_aswidechar('abc', 4) + self.assertEquals(size, 3) + self.assertEquals(wchar, 'abc\0') + + wchar, size = test_aswidechar('abc', 10) + self.assertEquals(size, 3) + self.assertEquals(wchar, 'abc\0') + + wchar, size = test_aswidechar('abc\0def', 20) + self.assertEquals(size, 7) + self.assertEquals(wchar, 'abc\0def\0') + + # Test PyUnicode_AsWideCharString() + def test_aswidecharstring(self): + from _testcapi import test_aswidecharstring + from ctypes import c_wchar, sizeof + + wchar, size = test_aswidecharstring('abc') + self.assertEquals(size, 3) + self.assertEquals(wchar, 'abc\0') + + wchar, size = test_aswidecharstring('abc\0def') + self.assertEquals(size, 7) + self.assertEquals(wchar, 'abc\0def\0') + + def test_main(): support.run_unittest(__name__) Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Sat Oct 2 13:03:13 2010 @@ -1386,6 +1386,58 @@ } static PyObject * +test_aswidechar(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_ssize_t buflen, size; + wchar_t *buffer; + + if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) + return NULL; + buffer = PyMem_Malloc(buflen * sizeof(wchar_t)); + if (buffer == NULL) + return PyErr_NoMemory(); + + size = PyUnicode_AsWideChar((PyUnicodeObject*)unicode, buffer, buflen); + if (size == -1) { + PyMem_Free(buffer); + return NULL; + } + + if (size < buflen) + buflen = size + 1; + else + buflen = size; + result = PyUnicode_FromWideChar(buffer, buflen); + PyMem_Free(buffer); + if (result == NULL) + return NULL; + + return Py_BuildValue("(Nn)", result, size); +} + +static PyObject * +test_aswidecharstring(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_ssize_t size; + wchar_t *buffer; + + if (!PyArg_ParseTuple(args, "U", &unicode)) + return NULL; + + buffer = PyUnicode_AsWideCharString((PyUnicodeObject*)unicode, &size); + if (buffer == NULL) + return NULL; + + result = PyUnicode_FromWideChar(buffer, size + 1); + PyMem_Free(buffer); + if (result == NULL) + return NULL; + return Py_BuildValue("(Nn)", result, size); +} + +static PyObject * getargs_w_star(PyObject *self, PyObject *args) { Py_buffer buffer; @@ -2262,28 +2314,30 @@ {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, {"getargs_w_star", getargs_w_star, METH_VARARGS}, {"codec_incrementalencoder", - (PyCFunction)codec_incrementalencoder, METH_VARARGS}, + (PyCFunction)codec_incrementalencoder, METH_VARARGS}, {"codec_incrementaldecoder", - (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, + (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, {"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}, {"test_widechar", (PyCFunction)test_widechar, METH_NOARGS}, + {"test_aswidechar", test_aswidechar, METH_VARARGS}, + {"test_aswidecharstring", test_aswidecharstring, METH_VARARGS}, #ifdef WITH_THREAD - {"_test_thread_state", test_thread_state, METH_VARARGS}, + {"_test_thread_state", test_thread_state, METH_VARARGS}, {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, #endif #ifdef HAVE_GETTIMEOFDAY - {"profile_int", profile_int, METH_NOARGS}, + {"profile_int", profile_int, METH_NOARGS}, #endif - {"traceback_print", traceback_print, METH_VARARGS}, - {"exception_print", exception_print, METH_VARARGS}, - {"argparsing", argparsing, METH_VARARGS}, - {"code_newempty", code_newempty, METH_VARARGS}, + {"traceback_print", traceback_print, METH_VARARGS}, + {"exception_print", exception_print, METH_VARARGS}, + {"argparsing", argparsing, METH_VARARGS}, + {"code_newempty", code_newempty, METH_VARARGS}, {"make_exception_with_doc", (PyCFunction)make_exception_with_doc, METH_VARARGS | METH_KEYWORDS}, {"crash_no_current_thread", (PyCFunction)crash_no_current_thread, METH_NOARGS}, - {"format_unicode", format_unicode, METH_VARARGS}, + {"format_unicode", format_unicode, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Sat Oct 2 13:03:13 2010 @@ -1216,7 +1216,7 @@ } unicode_aswidechar(unicode, buffer, buflen); if (size) - *size = buflen; + *size = buflen - 1; return buffer; } From python-checkins at python.org Sat Oct 2 13:11:15 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 13:11:15 +0200 Subject: [Python-checkins] distutils2: now generating a setup.cfg instead of a setup.py in mkpkg Message-ID: tarek.ziade pushed f93fc80f6a71 to distutils2: http://hg.python.org/distutils2/rev/f93fc80f6a71 changeset: 731:f93fc80f6a71 tag: tip user: Tarek Ziade date: Sat Oct 02 13:11:11 2010 +0200 summary: now generating a setup.cfg instead of a setup.py in mkpkg files: distutils2/mkpkg.py diff --git a/distutils2/mkpkg.py b/distutils2/mkpkg.py --- a/distutils2/mkpkg.py +++ b/distutils2/mkpkg.py @@ -32,6 +32,7 @@ # dict form or another structures for all purposes from distutils2._trove import all_classifiers as _CLASSIFIERS_LIST +_FILENAME = 'setup.cfg' _helptext = { 'name': ''' @@ -213,7 +214,7 @@ for root, dirs, files in os.walk(os.curdir): for filename in files: - if root == os.curdir and filename == 'setup.py': + if root == os.curdir and filename == _FILENAME: continue self.inspect_file(os.path.join(root, filename)) @@ -361,45 +362,39 @@ return modified_pkgs def write_setup_script(self): - if os.path.exists('setup.py'): - if os.path.exists('setup.py.old'): - print ("ERROR: setup.py.old backup exists, please check that " - "current setup.py is correct and remove setup.py.old") + if os.path.exists(_FILENAME): + if os.path.exists('%s.old' % _FILENAME): + print("ERROR: %(name)s.old backup exists, please check that " + "current %(name)s is correct and remove %(name)s.old" % \ + {'name': _FILENAME}) return - shutil.move('setup.py', 'setup.py.old') + shutil.move(_FILENAME, '%s.old' % _FILENAME) - fp = open('setup.py', 'w') + fp = open(_FILENAME, 'w') try: - # XXX do LFs work on all platforms? - fp.write('#!/usr/bin/env python\n\n') - fp.write('from distutils2.core import setup\n\n') - fp.write('setup(name=%s,\n' % repr(self.data['name'])) - fp.write(' version=%s,\n' % repr(self.data['version'])) - fp.write(' description=%s,\n' - % repr(self.data['description'])) - fp.write(' author=%s,\n' % repr(self.data['author'])) - fp.write(' author_email=%s,\n' - % repr(self.data['author_email'])) - if self.data['url']: - fp.write(' url=%s,\n' % repr(self.data['url'])) - if self.data['classifier']: - fp.write(' classifier=[\n') - for classifier in sorted(self.data['classifier'].keys()): - fp.write(' %s,\n' % repr(classifier)) - fp.write(' ],\n') - if self.data['packages']: - fp.write(' packages=%s,\n' - % repr(self._dotted_packages(self.data['packages']))) - fp.write(' package_dir=%s,\n' - % repr(self.data['packages'])) - fp.write(' #scripts=[\'path/to/script\']\n') + fp.write('[metadata]\n') + fp.write('name = %s\n' % self.data['name']) + fp.write('version = %s\n' % self.data['version']) + fp.write('author = %s\n' % self.data['author']) + fp.write('author_email = %s\n' % self.data['author_email']) + fp.write('description = %s\n' % self.data['description']) + fp.write('home_url = %s\n' % self.data['url']) + fp.write('\n') + classifiers = '\n'.join([' %s' % clas for clas in + self.data['classifier']]) + fp.write('classifier = %s\n' % classifiers.strip()) - fp.write(' )\n') + + fp.write('[files]\n') + packages = '\n'.join([' %s' % pkg for pkg in + self.data['packages']]) + fp.write('\n') + fp.write('packages = %s\n' % packages.strip()) finally: fp.close() - os.chmod('setup.py', 0755) - print 'Wrote "setup.py".' + os.chmod(_FILENAME, 0755) + print 'Wrote "%s".' % _FILENAME def main(): @@ -410,7 +405,7 @@ program.inspect_directory() program.query_user() program.update_config_file() - program.write_setup() + program.write_setup_script() if __name__ == '__main__': -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 13:11:27 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 2 Oct 2010 13:11:27 +0200 (CEST) Subject: [Python-checkins] r85173 - in python/branches/py3k: Lib/test/test_unicode.py Misc/NEWS Objects/unicodeobject.c Message-ID: <20101002111127.59DD8E1DF@mail.python.org> Author: victor.stinner Date: Sat Oct 2 13:11:27 2010 New Revision: 85173 Log: Issue #8670: PyUnicode_AsWideChar() and PyUnicode_AsWideCharString() replace UTF-16 surrogate pairs by single non-BMP characters for 16 bits Py_UNICODE and 32 bits wchar_t (eg. Linux in narrow build). Modified: python/branches/py3k/Lib/test/test_unicode.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicode.py (original) +++ python/branches/py3k/Lib/test/test_unicode.py Sat Oct 2 13:11:27 2010 @@ -1419,6 +1419,17 @@ self.assertEquals(size, 7) self.assertEquals(wchar, 'abc\0def\0') + nonbmp = chr(0x10ffff) + if sizeof(c_wchar) == 2: + buflen = 3 + nchar = 2 + else: # sizeof(c_wchar) == 4 + buflen = 2 + nchar = 1 + wchar, size = test_aswidechar(nonbmp, buflen) + self.assertEquals(size, nchar) + self.assertEquals(wchar, nonbmp + '\0') + # Test PyUnicode_AsWideCharString() def test_aswidecharstring(self): from _testcapi import test_aswidecharstring @@ -1432,6 +1443,15 @@ self.assertEquals(size, 7) self.assertEquals(wchar, 'abc\0def\0') + nonbmp = chr(0x10ffff) + if sizeof(c_wchar) == 2: + nchar = 2 + else: # sizeof(c_wchar) == 4 + nchar = 1 + wchar, size = test_aswidecharstring(nonbmp) + self.assertEquals(size, nchar) + self.assertEquals(wchar, nonbmp + '\0') + def test_main(): support.run_unittest(__name__) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Oct 2 13:11:27 2010 @@ -10,10 +10,14 @@ Core and Builtins ----------------- +- Issue #8670: PyUnicode_AsWideChar() and PyUnicode_AsWideCharString() replace + UTF-16 surrogate pairs by single non-BMP characters for 16 bits Py_UNICODE + and 32 bits wchar_t (eg. Linux in narrow build). + - Issue #10006: type.__abstractmethods__ now raises an AttributeError. - Issue #10003: Allow handling of SIGBREAK on Windows. Fixes a regression - introduced by issue #9324. + introduced by issue #9324. - Issue #9979: Create function PyUnicode_AsWideCharString(). Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Sat Oct 2 13:11:27 2010 @@ -1153,19 +1153,112 @@ return ret; } -static void +/* Helper function for PyUnicode_AsWideChar() and PyUnicode_AsWideCharString(): + convert a Unicode object to a wide character string. + + - If w is NULL: return the number of wide characters (including the nul + character) required to convert the unicode object. Ignore size argument. + + - Otherwise: return the number of wide characters (excluding the nul + character) written into w. Write at most size wide characters (including + the nul character). */ +static Py_ssize_t unicode_aswidechar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size) { #if Py_UNICODE_SIZE == SIZEOF_WCHAR_T - memcpy(w, unicode->str, size * sizeof(wchar_t)); -#else - register Py_UNICODE *u; + Py_ssize_t res; + if (w != NULL) { + res = PyUnicode_GET_SIZE(unicode); + if (size > res) + size = res + 1; + else + res = size; + memcpy(w, unicode->str, size * sizeof(wchar_t)); + return res; + } + else + return PyUnicode_GET_SIZE(unicode) + 1; +#elif Py_UNICODE_SIZE == 2 && SIZEOF_WCHAR_T == 4 + register const Py_UNICODE *u; + const Py_UNICODE *uend; + const wchar_t *worig, *wend; + Py_ssize_t nchar; + + u = PyUnicode_AS_UNICODE(unicode); + uend = u + PyUnicode_GET_SIZE(unicode); + if (w != NULL) { + worig = w; + wend = w + size; + while (u != uend && w != wend) { + if (0xD800 <= u[0] && u[0] <= 0xDBFF + && 0xDC00 <= u[1] && u[1] <= 0xDFFF) + { + *w = (((u[0] & 0x3FF) << 10) | (u[1] & 0x3FF)) + 0x10000; + u += 2; + } + else { + *w = *u; + u++; + } + w++; + } + if (w != wend) + *w = L'\0'; + return w - worig; + } + else { + nchar = 1; /* nul character at the end */ + while (u != uend) { + if (0xD800 <= u[0] && u[0] <= 0xDBFF + && 0xDC00 <= u[1] && u[1] <= 0xDFFF) + u += 2; + else + u++; + nchar++; + } + } + return nchar; +#elif Py_UNICODE_SIZE == 4 && SIZEOF_WCHAR_T == 2 + register Py_UNICODE *u, *uend, ordinal; register Py_ssize_t i; + wchar_t *worig, *wend; + Py_ssize_t nchar; + u = PyUnicode_AS_UNICODE(unicode); - for (i = size; i > 0; i--) - *w++ = *u++; + uend = u + PyUnicode_GET_SIZE(u); + if (w != NULL) { + worig = w; + wend = w + size; + while (u != uend && w != wend) { + ordinal = *u; + if (ordinal > 0xffff) { + ordinal -= 0x10000; + *w++ = 0xD800 | (ordinal >> 10); + *w++ = 0xDC00 | (ordinal & 0x3FF); + } + else + *w++ = ordinal; + u++; + } + if (w != wend) + *w = 0; + return w - worig; + } + else { + nchar = 1; /* nul character */ + while (u != uend) { + if (*u > 0xffff) + nchar += 2; + else + nchar++; + u++; + } + return nchar; + } +#else +# error "unsupported wchar_t and Py_UNICODE sizes, see issue #8670" #endif } @@ -1178,17 +1271,7 @@ PyErr_BadInternalCall(); return -1; } - - /* If possible, try to copy the 0-termination as well */ - if (size > PyUnicode_GET_SIZE(unicode)) - size = PyUnicode_GET_SIZE(unicode) + 1; - - unicode_aswidechar(unicode, w, size); - - if (size > PyUnicode_GET_SIZE(unicode)) - return PyUnicode_GET_SIZE(unicode); - else - return size; + return unicode_aswidechar(unicode, w, size); } wchar_t* @@ -1203,20 +1286,20 @@ return NULL; } - if ((PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) < PyUnicode_GET_SIZE(unicode)) { + buflen = unicode_aswidechar(unicode, NULL, 0); + if (PY_SSIZE_T_MAX / sizeof(wchar_t) < buflen) { PyErr_NoMemory(); return NULL; } - buflen = PyUnicode_GET_SIZE(unicode) + 1; /* copy L'\0' */ buffer = PyMem_MALLOC(buflen * sizeof(wchar_t)); if (buffer == NULL) { PyErr_NoMemory(); return NULL; } - unicode_aswidechar(unicode, buffer, buflen); - if (size) - *size = buflen - 1; + buflen = unicode_aswidechar(unicode, buffer, buflen); + if (size != NULL) + *size = buflen; return buffer; } From python-checkins at python.org Sat Oct 2 13:15:08 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 2 Oct 2010 13:15:08 +0200 (CEST) Subject: [Python-checkins] r85172 - svn:log Message-ID: <20101002111508.ADB3AD6A4@mail.python.org> Author: victor.stinner Revision: 85172 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1,3 +1,3 @@ -Issue #8870: PyUnicode_AsWideChar() doesn't count the trailing nul character +Issue #8870: PyUnicode_AsWideCharString() doesn't count the trailing nul character -And write unit tests for PyUnicode_AsWideChar() and PyUnicode_AsWideChar(). +And write unit tests for PyUnicode_AsWideChar() and PyUnicode_AsWideCharString(). From python-checkins at python.org Sat Oct 2 13:25:35 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 2 Oct 2010 13:25:35 +0200 (CEST) Subject: [Python-checkins] r85174 - in python/branches/py3k: Lib/ctypes/test/test_strings.py Lib/test/test_unicode.py Modules/_ctypes/cfield.c Modules/_testcapimodule.c Message-ID: <20101002112535.9BB75D2AE@mail.python.org> Author: victor.stinner Date: Sat Oct 2 13:25:35 2010 New Revision: 85174 Log: Issue #8670: Rename testcapi unicode test methods * test_aswidechar() => unicode_aswidechar() * test_aswidecharstring() => unicode_aswidecharstring() Modified: python/branches/py3k/Lib/ctypes/test/test_strings.py python/branches/py3k/Lib/test/test_unicode.py python/branches/py3k/Modules/_ctypes/cfield.c python/branches/py3k/Modules/_testcapimodule.c Modified: python/branches/py3k/Lib/ctypes/test/test_strings.py ============================================================================== --- python/branches/py3k/Lib/ctypes/test/test_strings.py (original) +++ python/branches/py3k/Lib/ctypes/test/test_strings.py Sat Oct 2 13:25:35 2010 @@ -74,6 +74,13 @@ buf[1] = "Z" self.assertEqual(buf.value, "xZCD") + @unittest.skipIf(sizeof(c_wchar) < 4, + "sizeof(wchar_t) is smaller than 4 bytes") + def test_nonbmp(self): + u = chr(0x10ffff) + w = c_wchar(u) + self.assertEqual(w.value, u) + class StringTestCase(unittest.TestCase): def XX_test_basic_strings(self): cs = c_string("abcdef") Modified: python/branches/py3k/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicode.py (original) +++ python/branches/py3k/Lib/test/test_unicode.py Sat Oct 2 13:25:35 2010 @@ -1396,26 +1396,26 @@ # Test PyUnicode_AsWideChar() def test_aswidechar(self): - from _testcapi import test_aswidechar + from _testcapi import unicode_aswidechar from ctypes import c_wchar, sizeof - wchar, size = test_aswidechar('abcdef', 2) + wchar, size = unicode_aswidechar('abcdef', 2) self.assertEquals(size, 2) self.assertEquals(wchar, 'ab') - wchar, size = test_aswidechar('abc', 3) + wchar, size = unicode_aswidechar('abc', 3) self.assertEquals(size, 3) self.assertEquals(wchar, 'abc') - wchar, size = test_aswidechar('abc', 4) + wchar, size = unicode_aswidechar('abc', 4) self.assertEquals(size, 3) self.assertEquals(wchar, 'abc\0') - wchar, size = test_aswidechar('abc', 10) + wchar, size = unicode_aswidechar('abc', 10) self.assertEquals(size, 3) self.assertEquals(wchar, 'abc\0') - wchar, size = test_aswidechar('abc\0def', 20) + wchar, size = unicode_aswidechar('abc\0def', 20) self.assertEquals(size, 7) self.assertEquals(wchar, 'abc\0def\0') @@ -1426,20 +1426,20 @@ else: # sizeof(c_wchar) == 4 buflen = 2 nchar = 1 - wchar, size = test_aswidechar(nonbmp, buflen) + wchar, size = unicode_aswidechar(nonbmp, buflen) self.assertEquals(size, nchar) self.assertEquals(wchar, nonbmp + '\0') # Test PyUnicode_AsWideCharString() def test_aswidecharstring(self): - from _testcapi import test_aswidecharstring + from _testcapi import unicode_aswidecharstring from ctypes import c_wchar, sizeof - wchar, size = test_aswidecharstring('abc') + wchar, size = unicode_aswidecharstring('abc') self.assertEquals(size, 3) self.assertEquals(wchar, 'abc\0') - wchar, size = test_aswidecharstring('abc\0def') + wchar, size = unicode_aswidecharstring('abc\0def') self.assertEquals(size, 7) self.assertEquals(wchar, 'abc\0def\0') @@ -1448,7 +1448,7 @@ nchar = 2 else: # sizeof(c_wchar) == 4 nchar = 1 - wchar, size = test_aswidecharstring(nonbmp) + wchar, size = unicode_aswidecharstring(nonbmp) self.assertEquals(size, nchar) self.assertEquals(wchar, nonbmp + '\0') Modified: python/branches/py3k/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k/Modules/_ctypes/cfield.c Sat Oct 2 13:25:35 2010 @@ -1203,6 +1203,7 @@ u_set(void *ptr, PyObject *value, Py_ssize_t size) { Py_ssize_t len; + wchar_t chars[2]; if (!PyUnicode_Check(value)) { PyErr_Format(PyExc_TypeError, "unicode string expected instead of %s instance", @@ -1211,7 +1212,7 @@ } else Py_INCREF(value); - len = PyUnicode_GET_SIZE(value); + len = PyUnicode_AsWideChar((PyUnicodeObject *)value, chars, 2); if (len != 1) { Py_DECREF(value); PyErr_SetString(PyExc_TypeError, @@ -1219,7 +1220,7 @@ return NULL; } - *(wchar_t *)ptr = PyUnicode_AS_UNICODE(value)[0]; + *(wchar_t *)ptr = chars[0]; Py_DECREF(value); _RET(value); Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Sat Oct 2 13:25:35 2010 @@ -1386,7 +1386,7 @@ } static PyObject * -test_aswidechar(PyObject *self, PyObject *args) +unicode_aswidechar(PyObject *self, PyObject *args) { PyObject *unicode, *result; Py_ssize_t buflen, size; @@ -1417,7 +1417,7 @@ } static PyObject * -test_aswidecharstring(PyObject *self, PyObject *args) +unicode_aswidecharstring(PyObject *self, PyObject *args) { PyObject *unicode, *result; Py_ssize_t size; @@ -2321,8 +2321,8 @@ {"test_u_code", (PyCFunction)test_u_code, METH_NOARGS}, {"test_Z_code", (PyCFunction)test_Z_code, METH_NOARGS}, {"test_widechar", (PyCFunction)test_widechar, METH_NOARGS}, - {"test_aswidechar", test_aswidechar, METH_VARARGS}, - {"test_aswidecharstring", test_aswidecharstring, METH_VARARGS}, + {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, + {"unicode_aswidecharstring",unicode_aswidecharstring, METH_VARARGS}, #ifdef WITH_THREAD {"_test_thread_state", test_thread_state, METH_VARARGS}, {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, From python-checkins at python.org Sat Oct 2 13:46:20 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 2 Oct 2010 13:46:20 +0200 (CEST) Subject: [Python-checkins] r85175 - in python/branches/py3k: Lib/test/test_unicode.py Modules/_testcapimodule.c Message-ID: <20101002114620.7F477D2AE@mail.python.org> Author: victor.stinner Date: Sat Oct 2 13:46:20 2010 New Revision: 85175 Log: Oops, revert unwanted ctypes changes of r85174 Modified: python/branches/py3k/Lib/test/test_unicode.py python/branches/py3k/Modules/_testcapimodule.c Modified: python/branches/py3k/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicode.py (original) +++ python/branches/py3k/Lib/test/test_unicode.py Sat Oct 2 13:46:20 2010 @@ -1396,26 +1396,26 @@ # Test PyUnicode_AsWideChar() def test_aswidechar(self): - from _testcapi import unicode_aswidechar + from _testcapi import test_aswidechar from ctypes import c_wchar, sizeof - wchar, size = unicode_aswidechar('abcdef', 2) + wchar, size = test_aswidechar('abcdef', 2) self.assertEquals(size, 2) self.assertEquals(wchar, 'ab') - wchar, size = unicode_aswidechar('abc', 3) + wchar, size = test_aswidechar('abc', 3) self.assertEquals(size, 3) self.assertEquals(wchar, 'abc') - wchar, size = unicode_aswidechar('abc', 4) + wchar, size = test_aswidechar('abc', 4) self.assertEquals(size, 3) self.assertEquals(wchar, 'abc\0') - wchar, size = unicode_aswidechar('abc', 10) + wchar, size = test_aswidechar('abc', 10) self.assertEquals(size, 3) self.assertEquals(wchar, 'abc\0') - wchar, size = unicode_aswidechar('abc\0def', 20) + wchar, size = test_aswidechar('abc\0def', 20) self.assertEquals(size, 7) self.assertEquals(wchar, 'abc\0def\0') @@ -1426,20 +1426,20 @@ else: # sizeof(c_wchar) == 4 buflen = 2 nchar = 1 - wchar, size = unicode_aswidechar(nonbmp, buflen) + wchar, size = test_aswidechar(nonbmp, buflen) self.assertEquals(size, nchar) self.assertEquals(wchar, nonbmp + '\0') # Test PyUnicode_AsWideCharString() def test_aswidecharstring(self): - from _testcapi import unicode_aswidecharstring + from _testcapi import test_aswidecharstring from ctypes import c_wchar, sizeof - wchar, size = unicode_aswidecharstring('abc') + wchar, size = test_aswidecharstring('abc') self.assertEquals(size, 3) self.assertEquals(wchar, 'abc\0') - wchar, size = unicode_aswidecharstring('abc\0def') + wchar, size = test_aswidecharstring('abc\0def') self.assertEquals(size, 7) self.assertEquals(wchar, 'abc\0def\0') @@ -1448,7 +1448,7 @@ nchar = 2 else: # sizeof(c_wchar) == 4 nchar = 1 - wchar, size = unicode_aswidecharstring(nonbmp) + wchar, size = test_aswidecharstring(nonbmp) self.assertEquals(size, nchar) self.assertEquals(wchar, nonbmp + '\0') Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Sat Oct 2 13:46:20 2010 @@ -1386,7 +1386,7 @@ } static PyObject * -unicode_aswidechar(PyObject *self, PyObject *args) +test_aswidechar(PyObject *self, PyObject *args) { PyObject *unicode, *result; Py_ssize_t buflen, size; @@ -1417,7 +1417,7 @@ } static PyObject * -unicode_aswidecharstring(PyObject *self, PyObject *args) +test_aswidecharstring(PyObject *self, PyObject *args) { PyObject *unicode, *result; Py_ssize_t size; @@ -2321,8 +2321,8 @@ {"test_u_code", (PyCFunction)test_u_code, METH_NOARGS}, {"test_Z_code", (PyCFunction)test_Z_code, METH_NOARGS}, {"test_widechar", (PyCFunction)test_widechar, METH_NOARGS}, - {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, - {"unicode_aswidecharstring",unicode_aswidecharstring, METH_VARARGS}, + {"test_aswidechar", test_aswidechar, METH_VARARGS}, + {"test_aswidecharstring", test_aswidecharstring, METH_VARARGS}, #ifdef WITH_THREAD {"_test_thread_state", test_thread_state, METH_VARARGS}, {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, From python-checkins at python.org Sat Oct 2 13:49:31 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 2 Oct 2010 13:49:31 +0200 (CEST) Subject: [Python-checkins] r85176 - in python/branches/py3k: Lib/test/test_unicode.py Modules/_testcapimodule.c Message-ID: <20101002114931.DB278D422@mail.python.org> Author: victor.stinner Date: Sat Oct 2 13:49:31 2010 New Revision: 85176 Log: Issue #8670: Rename testcapi unicode test methods * test_aswidechar() => unicode_aswidechar() * test_aswidecharstring() => unicode_aswidecharstring() Modified: python/branches/py3k/Lib/test/test_unicode.py python/branches/py3k/Modules/_testcapimodule.c Modified: python/branches/py3k/Lib/test/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicode.py (original) +++ python/branches/py3k/Lib/test/test_unicode.py Sat Oct 2 13:49:31 2010 @@ -1396,26 +1396,26 @@ # Test PyUnicode_AsWideChar() def test_aswidechar(self): - from _testcapi import test_aswidechar + from _testcapi import unicode_aswidechar from ctypes import c_wchar, sizeof - wchar, size = test_aswidechar('abcdef', 2) + wchar, size = unicode_aswidechar('abcdef', 2) self.assertEquals(size, 2) self.assertEquals(wchar, 'ab') - wchar, size = test_aswidechar('abc', 3) + wchar, size = unicode_aswidechar('abc', 3) self.assertEquals(size, 3) self.assertEquals(wchar, 'abc') - wchar, size = test_aswidechar('abc', 4) + wchar, size = unicode_aswidechar('abc', 4) self.assertEquals(size, 3) self.assertEquals(wchar, 'abc\0') - wchar, size = test_aswidechar('abc', 10) + wchar, size = unicode_aswidechar('abc', 10) self.assertEquals(size, 3) self.assertEquals(wchar, 'abc\0') - wchar, size = test_aswidechar('abc\0def', 20) + wchar, size = unicode_aswidechar('abc\0def', 20) self.assertEquals(size, 7) self.assertEquals(wchar, 'abc\0def\0') @@ -1426,20 +1426,20 @@ else: # sizeof(c_wchar) == 4 buflen = 2 nchar = 1 - wchar, size = test_aswidechar(nonbmp, buflen) + wchar, size = unicode_aswidechar(nonbmp, buflen) self.assertEquals(size, nchar) self.assertEquals(wchar, nonbmp + '\0') # Test PyUnicode_AsWideCharString() def test_aswidecharstring(self): - from _testcapi import test_aswidecharstring + from _testcapi import unicode_aswidecharstring from ctypes import c_wchar, sizeof - wchar, size = test_aswidecharstring('abc') + wchar, size = unicode_aswidecharstring('abc') self.assertEquals(size, 3) self.assertEquals(wchar, 'abc\0') - wchar, size = test_aswidecharstring('abc\0def') + wchar, size = unicode_aswidecharstring('abc\0def') self.assertEquals(size, 7) self.assertEquals(wchar, 'abc\0def\0') @@ -1448,7 +1448,7 @@ nchar = 2 else: # sizeof(c_wchar) == 4 nchar = 1 - wchar, size = test_aswidecharstring(nonbmp) + wchar, size = unicode_aswidecharstring(nonbmp) self.assertEquals(size, nchar) self.assertEquals(wchar, nonbmp + '\0') Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Sat Oct 2 13:49:31 2010 @@ -1386,7 +1386,7 @@ } static PyObject * -test_aswidechar(PyObject *self, PyObject *args) +unicode_aswidechar(PyObject *self, PyObject *args) { PyObject *unicode, *result; Py_ssize_t buflen, size; @@ -1417,7 +1417,7 @@ } static PyObject * -test_aswidecharstring(PyObject *self, PyObject *args) +unicode_aswidecharstring(PyObject *self, PyObject *args) { PyObject *unicode, *result; Py_ssize_t size; @@ -2321,8 +2321,8 @@ {"test_u_code", (PyCFunction)test_u_code, METH_NOARGS}, {"test_Z_code", (PyCFunction)test_Z_code, METH_NOARGS}, {"test_widechar", (PyCFunction)test_widechar, METH_NOARGS}, - {"test_aswidechar", test_aswidechar, METH_VARARGS}, - {"test_aswidecharstring", test_aswidecharstring, METH_VARARGS}, + {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, + {"unicode_aswidecharstring",unicode_aswidecharstring, METH_VARARGS}, #ifdef WITH_THREAD {"_test_thread_state", test_thread_state, METH_VARARGS}, {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, From python-checkins at python.org Sat Oct 2 13:50:49 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 2 Oct 2010 13:50:49 +0200 (CEST) Subject: [Python-checkins] r85177 - python/branches/py3k/Misc/NEWS Message-ID: <20101002115049.ADE45D536@mail.python.org> Author: victor.stinner Date: Sat Oct 2 13:50:49 2010 New Revision: 85177 Log: Update changelog for r85174 Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Oct 2 13:50:49 2010 @@ -10,6 +10,8 @@ Core and Builtins ----------------- +- Issue #8670: ctypes.c_wchar supports non-BMP characters with 32 bits wchar_t. + - Issue #8670: PyUnicode_AsWideChar() and PyUnicode_AsWideCharString() replace UTF-16 surrogate pairs by single non-BMP characters for 16 bits Py_UNICODE and 32 bits wchar_t (eg. Linux in narrow build). From python-checkins at python.org Sat Oct 2 13:51:41 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 2 Oct 2010 13:51:41 +0200 (CEST) Subject: [Python-checkins] r85175 - svn:log Message-ID: <20101002115141.CAF60DD08@mail.python.org> Author: victor.stinner Revision: 85175 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -Oops, revert unwanted ctypes changes of r85174 +Oops, revert unwanted _testcapi changes of r85174 From python-checkins at python.org Sat Oct 2 13:52:11 2010 From: python-checkins at python.org (victor.stinner) Date: Sat, 2 Oct 2010 13:52:11 +0200 (CEST) Subject: [Python-checkins] r85174 - svn:log Message-ID: <20101002115211.61B07DD08@mail.python.org> Author: victor.stinner Revision: 85174 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1,4 +1 @@ -Issue #8670: Rename testcapi unicode test methods - - * test_aswidechar() => unicode_aswidechar() - * test_aswidecharstring() => unicode_aswidecharstring() +Issue #8670: ctypes.c_wchar supports non-BMP characters with 32 bits wchar_t From python-checkins at python.org Sat Oct 2 14:52:55 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 14:52:55 +0200 Subject: [Python-checkins] distutils2: allow one-liner for packages Message-ID: tarek.ziade pushed d325e280f222 to distutils2: http://hg.python.org/distutils2/rev/d325e280f222 changeset: 733:d325e280f222 user: Tarek Ziade date: Sat Oct 02 14:52:16 2010 +0200 summary: allow one-liner for packages files: distutils2/config.py diff --git a/distutils2/config.py b/distutils2/config.py --- a/distutils2/config.py +++ b/distutils2/config.py @@ -105,7 +105,11 @@ self.dist.packages = [] self.dist.package_dir = {} - for package in files.get('packages', []): + packages = files.get('packages', []) + if isinstance(packages, str): + packages = [packages] + + for package in packages: if ':' in package: dir_, package = package.split(':') self.dist.package_dir[package] = dir_ -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 14:52:55 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 14:52:55 +0200 Subject: [Python-checkins] distutils2: removed setup.py from the list of files included by default, and make sure the Message-ID: tarek.ziade pushed 9fa805e588f3 to distutils2: http://hg.python.org/distutils2/rev/9fa805e588f3 changeset: 732:9fa805e588f3 user: Tarek Ziade date: Sat Oct 02 14:51:50 2010 +0200 summary: removed setup.py from the list of files included by default, and make sure the list builder dont die on a command files: distutils2/command/sdist.py, distutils2/tests/test_sdist.py diff --git a/distutils2/command/sdist.py b/distutils2/command/sdist.py --- a/distutils2/command/sdist.py +++ b/distutils2/command/sdist.py @@ -197,7 +197,6 @@ def add_defaults(self): """Add all the default files to self.filelist: - README or README.txt - - setup.py - test/test*.py - all pure Python modules mentioned in setup script - all files pointed by package_data (build_py) @@ -208,8 +207,7 @@ Warns if (README or README.txt) or setup.py are missing; everything else is optional. """ - - standards = [('README', 'README.txt'), self.distribution.script_name] + standards = [('README', 'README.txt')] for fn in standards: if isinstance(fn, tuple): alts = fn @@ -236,8 +234,12 @@ self.filelist.extend(files) for cmd_name in self.distribution.get_command_names(): - cmd_obj = self.get_finalized_command(cmd_name) - self.filelist.extend(cmd_obj.get_source_files()) + try: + cmd_obj = self.get_finalized_command(cmd_name) + except DistutilsOptionError: + pass + else: + self.filelist.extend(cmd_obj.get_source_files()) def prune_file_list(self): """Prune off branches that might slip into the file list as created diff --git a/distutils2/tests/test_sdist.py b/distutils2/tests/test_sdist.py --- a/distutils2/tests/test_sdist.py +++ b/distutils2/tests/test_sdist.py @@ -47,7 +47,6 @@ # file GENERATED by distutils, do NOT edit README inroot.txt -setup.py data%(sep)sdata.dt scripts%(sep)sscript.py some%(sep)sfile.txt @@ -138,7 +137,7 @@ zip_file.close() # making sure everything has been pruned correctly - self.assertEqual(len(content), 4) + self.assertEqual(len(content), 3) @unittest.skipUnless(zlib, "requires zlib") def test_make_distribution(self): @@ -233,7 +232,7 @@ zip_file.close() # making sure everything was added - self.assertEqual(len(content), 11) + self.assertEqual(len(content), 10) # checking the MANIFEST manifest = open(join(self.tmp_dir, 'MANIFEST')).read() @@ -361,7 +360,7 @@ finally: f.close() - self.assertEquals(len(manifest), 5) + self.assertEquals(len(manifest), 4) # adding a file self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#') @@ -381,7 +380,7 @@ f.close() # do we have the new file in MANIFEST ? - self.assertEquals(len(manifest2), 6) + self.assertEquals(len(manifest2), 5) self.assertIn('doc2.txt', manifest2[-1]) def test_manifest_marker(self): -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 14:52:55 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 14:52:55 +0200 Subject: [Python-checkins] distutils2: setting package manually - a automatic introspection does not work in a real Message-ID: tarek.ziade pushed d65a95478c76 to distutils2: http://hg.python.org/distutils2/rev/d65a95478c76 changeset: 734:d65a95478c76 tag: tip user: Tarek Ziade date: Sat Oct 02 14:52:49 2010 +0200 summary: setting package manually - a automatic introspection does not work in a real environment files: distutils2/mkpkg.py diff --git a/distutils2/mkpkg.py b/distutils2/mkpkg.py --- a/distutils2/mkpkg.py +++ b/distutils2/mkpkg.py @@ -60,7 +60,11 @@ for Linux under the PSF license. However, this can be a somewhat involved process. ''', - 'url': ''' + 'package': ''' +You can provide a package name contained in your project. +''', + + 'home_page': ''' The home page for the package, typically starting with "http://". ''', 'trove_license': ''' @@ -78,6 +82,7 @@ def ask_yn(question, default=None, helptext=None): + question += ' (y/n)' while True: answer = ask(question, default, helptext, required=True) if answer and answer[0].lower() in 'yn': @@ -143,7 +148,7 @@ self.classifiers = {} self.data = {} self.data['classifier'] = self.classifiers - self.data['packages'] = {} + self.data['packages'] = [] self.load_config_file() def lookup_option(self, key): @@ -212,24 +217,8 @@ self.data['name'] = m.group(1) self.data['version'] = m.group(2) - for root, dirs, files in os.walk(os.curdir): - for filename in files: - if root == os.curdir and filename == _FILENAME: - continue - self.inspect_file(os.path.join(root, filename)) - - if filename == '__init__.py': - trySrc = os.path.join(os.curdir, 'src') - tmpRoot = root - if tmpRoot.startswith(trySrc): - tmpRoot = tmpRoot[len(trySrc):] - if tmpRoot.startswith(os.path.sep): - tmpRoot = tmpRoot[len(os.path.sep):] - - self.data['packages'][tmpRoot] = root[1 + len(os.path.sep):] - def query_user(self): - self.data['name'] = ask('Package name', self.data['name'], + self.data['name'] = ask('Project name', self.data['name'], _helptext['name']) self.data['version'] = ask('Current version number', self.data.get('version'), _helptext['version']) @@ -240,13 +229,26 @@ self.data.get('author'), _helptext['author']) self.data['author_email'] = ask('Author e-mail address', self.data.get('author_email'), _helptext['author_email']) - self.data['url'] = ask('Project URL', - self.data.get('url'), _helptext['url'], required=False) + self.data['home_page'] = ask('Project Home Page', + self.data.get('home_page'), _helptext['home_page'], + required=False) + + while ask_yn('Do you want to add a package ?', + helptext=_helptext['package']) == 'y': + self.set_package() if ask_yn('Do you want to set Trove classifiers?', helptext=_helptext['do_classifier']) == 'y': self.set_classifier() + def set_package(self): + packages = self.data['packages'] + name = ask('Package name', helptext=_helptext['package']).strip() + if name == '': + return + if name not in packages: + packages.append(name) + def set_classifier(self): self.set_devel_status(self.classifiers) self.set_license(self.classifiers) @@ -378,12 +380,13 @@ fp.write('author = %s\n' % self.data['author']) fp.write('author_email = %s\n' % self.data['author_email']) fp.write('description = %s\n' % self.data['description']) - fp.write('home_url = %s\n' % self.data['url']) + fp.write('home_page = %s\n' % self.data['home_page']) fp.write('\n') - classifiers = '\n'.join([' %s' % clas for clas in - self.data['classifier']]) - fp.write('classifier = %s\n' % classifiers.strip()) - + if len(self.data['classifier']) > 0: + classifiers = '\n'.join([' %s' % clas for clas in + self.data['classifier']]) + fp.write('classifier = %s\n' % classifiers.strip()) + fp.write('\n') fp.write('[files]\n') packages = '\n'.join([' %s' % pkg for pkg in -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 14:53:54 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 14:53:54 +0200 Subject: [Python-checkins] distutils2: Added the ability to test for existence of a given field Message-ID: tarek.ziade pushed 88c3e9e6f9ba to distutils2: http://hg.python.org/distutils2/rev/88c3e9e6f9ba changeset: 735:88c3e9e6f9ba parent: 728:e94847294adf user: Jeremy Kloth date: Fri Oct 01 15:36:13 2010 -0600 summary: Added the ability to test for existence of a given field files: distutils2/metadata.py diff --git a/distutils2/metadata.py b/distutils2/metadata.py --- a/distutils2/metadata.py +++ b/distutils2/metadata.py @@ -179,6 +179,7 @@ _UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') +_MISSING = object() class DistributionMetadata(object): """The metadata of a release. @@ -228,9 +229,17 @@ return self.set(name, value) def __delitem__(self, name): - del self._fields[name] + field_name = self._convert_name(name) + try: + del self._fields[field_name] + except KeyError: + raise KeyError(name) self._set_best_version() + def __contains__(self, name): + return (name in self._fields or + self._convert_name(name) in self._fields) + def _convert_name(self, name): if name in _ALL_FIELDS: return name @@ -305,7 +314,7 @@ else: # single line value = msg[field] - if value is not None: + if value is not None and value != 'UNKNOWN': self.set(field, value) def write(self, filepath): @@ -376,7 +385,7 @@ if isinstance(value, str): value = [value] else: - value = None + value = [] if name in _PREDICATE_FIELDS and value is not None: for v in value: @@ -402,11 +411,13 @@ self._fields[name] = value self._set_best_version() - def get(self, name): + def get(self, name, default=_MISSING): """Get a metadata field.""" name = self._convert_name(name) if name not in self._fields: - return self._default_value(name) + if default is _MISSING: + default = self._default_value(name) + return default if name in _UNICODEFIELDS: value = self._fields[name] return self._encode_field(value) @@ -442,8 +453,7 @@ # XXX should check the versions (if the file was loaded) missing, warnings = [], [] for attr in ('Name', 'Version', 'Home-page'): - value = self[attr] - if value == 'UNKNOWN': + if attr not in self: missing.append(attr) if _HAS_DOCUTILS: @@ -463,11 +473,8 @@ (_VERSIONS_FIELDS, is_valid_versions), (_VERSION_FIELDS, is_valid_version)): for field in fields: - value = self[field] - if value == 'UNKNOWN': - continue - - if not controller(value): + value = self.get(field, None) + if value is not None and not controller(value): warnings.append('Wrong value for %r: %s' % (field, value)) return missing, warnings -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 14:53:54 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 14:53:54 +0200 Subject: [Python-checkins] distutils2: Branch merge Message-ID: tarek.ziade pushed 1a511df5623e to distutils2: http://hg.python.org/distutils2/rev/1a511df5623e changeset: 736:1a511df5623e parent: 731:f93fc80f6a71 parent: 735:88c3e9e6f9ba user: ?ric Araujo date: Sat Oct 02 14:04:31 2010 +0200 summary: Branch merge files: distutils2/metadata.py diff --git a/distutils2/metadata.py b/distutils2/metadata.py --- a/distutils2/metadata.py +++ b/distutils2/metadata.py @@ -179,6 +179,7 @@ _UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') +_MISSING = object() class DistributionMetadata(object): """The metadata of a release. @@ -228,9 +229,17 @@ return self.set(name, value) def __delitem__(self, name): - del self._fields[name] + field_name = self._convert_name(name) + try: + del self._fields[field_name] + except KeyError: + raise KeyError(name) self._set_best_version() + def __contains__(self, name): + return (name in self._fields or + self._convert_name(name) in self._fields) + def _convert_name(self, name): if name in _ALL_FIELDS: return name @@ -305,7 +314,7 @@ else: # single line value = msg[field] - if value is not None: + if value is not None and value != 'UNKNOWN': self.set(field, value) def write(self, filepath): @@ -376,7 +385,7 @@ if isinstance(value, str): value = [value] else: - value = None + value = [] if name in _PREDICATE_FIELDS and value is not None: for v in value: @@ -402,11 +411,13 @@ self._fields[name] = value self._set_best_version() - def get(self, name): + def get(self, name, default=_MISSING): """Get a metadata field.""" name = self._convert_name(name) if name not in self._fields: - return self._default_value(name) + if default is _MISSING: + default = self._default_value(name) + return default if name in _UNICODEFIELDS: value = self._fields[name] return self._encode_field(value) @@ -442,8 +453,7 @@ # XXX should check the versions (if the file was loaded) missing, warnings = [], [] for attr in ('Name', 'Version', 'Home-page'): - value = self[attr] - if value == 'UNKNOWN': + if attr not in self: missing.append(attr) if _HAS_DOCUTILS: @@ -463,11 +473,8 @@ (_VERSIONS_FIELDS, is_valid_versions), (_VERSION_FIELDS, is_valid_version)): for field in fields: - value = self[field] - if value == 'UNKNOWN': - continue - - if not controller(value): + value = self.get(field, None) + if value is not None and not controller(value): warnings.append('Wrong value for %r: %s' % (field, value)) return missing, warnings -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 14:53:54 2010 From: python-checkins at python.org (tarek.ziade) Date: Sat, 02 Oct 2010 14:53:54 +0200 Subject: [Python-checkins] distutils2: merged Message-ID: tarek.ziade pushed 6847e60e5823 to distutils2: http://hg.python.org/distutils2/rev/6847e60e5823 changeset: 737:6847e60e5823 tag: tip parent: 734:d65a95478c76 parent: 736:1a511df5623e user: Tarek Ziade date: Sat Oct 02 14:53:36 2010 +0200 summary: merged files: diff --git a/distutils2/metadata.py b/distutils2/metadata.py --- a/distutils2/metadata.py +++ b/distutils2/metadata.py @@ -179,6 +179,7 @@ _UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') +_MISSING = object() class DistributionMetadata(object): """The metadata of a release. @@ -228,9 +229,17 @@ return self.set(name, value) def __delitem__(self, name): - del self._fields[name] + field_name = self._convert_name(name) + try: + del self._fields[field_name] + except KeyError: + raise KeyError(name) self._set_best_version() + def __contains__(self, name): + return (name in self._fields or + self._convert_name(name) in self._fields) + def _convert_name(self, name): if name in _ALL_FIELDS: return name @@ -305,7 +314,7 @@ else: # single line value = msg[field] - if value is not None: + if value is not None and value != 'UNKNOWN': self.set(field, value) def write(self, filepath): @@ -376,7 +385,7 @@ if isinstance(value, str): value = [value] else: - value = None + value = [] if name in _PREDICATE_FIELDS and value is not None: for v in value: @@ -402,11 +411,13 @@ self._fields[name] = value self._set_best_version() - def get(self, name): + def get(self, name, default=_MISSING): """Get a metadata field.""" name = self._convert_name(name) if name not in self._fields: - return self._default_value(name) + if default is _MISSING: + default = self._default_value(name) + return default if name in _UNICODEFIELDS: value = self._fields[name] return self._encode_field(value) @@ -442,8 +453,7 @@ # XXX should check the versions (if the file was loaded) missing, warnings = [], [] for attr in ('Name', 'Version', 'Home-page'): - value = self[attr] - if value == 'UNKNOWN': + if attr not in self: missing.append(attr) if _HAS_DOCUTILS: @@ -463,11 +473,8 @@ (_VERSIONS_FIELDS, is_valid_versions), (_VERSION_FIELDS, is_valid_version)): for field in fields: - value = self[field] - if value == 'UNKNOWN': - continue - - if not controller(value): + value = self.get(field, None) + if value is not None and not controller(value): warnings.append('Wrong value for %r: %s' % (field, value)) return missing, warnings -- Repository URL: http://hg.python.org/distutils2 From python-checkins at python.org Sat Oct 2 15:29:13 2010 From: python-checkins at python.org (r.david.murray) Date: Sat, 2 Oct 2010 15:29:13 +0200 (CEST) Subject: [Python-checkins] r85178 - python/branches/py3k/Lib/test/test_sqlite.py Message-ID: <20101002132913.712DFD8A3@mail.python.org> Author: r.david.murray Date: Sat Oct 2 15:29:13 2010 New Revision: 85178 Log: Make the printing of sqlite version in verbose mode work with regrtest -w. Modified: python/branches/py3k/Lib/test/test_sqlite.py Modified: python/branches/py3k/Lib/test/test_sqlite.py ============================================================================== --- python/branches/py3k/Lib/test/test_sqlite.py (original) +++ python/branches/py3k/Lib/test/test_sqlite.py Sat Oct 2 15:29:13 2010 @@ -1,7 +1,7 @@ -from test.support import run_unittest, import_module, verbose +import test.support # Skip test if _sqlite3 module not installed -import_module('_sqlite3') +test.support.import_module('_sqlite3') import sqlite3 from sqlite3.test import (dbapi, types, userfunctions, @@ -9,13 +9,15 @@ dump) def test_main(): - if verbose: + if test.support.verbose: print("test_sqlite: testing with version", "{!r}, sqlite_version {!r}".format(sqlite3.version, sqlite3.sqlite_version)) - run_unittest(dbapi.suite(), types.suite(), userfunctions.suite(), - factory.suite(), transactions.suite(), - hooks.suite(), regression.suite(), dump.suite()) + test.support.run_unittest(dbapi.suite(), types.suite(), + userfunctions.suite(), + factory.suite(), transactions.suite(), + hooks.suite(), regression.suite(), + dump.suite()) if __name__ == "__main__": test_main() From python-checkins at python.org Sat Oct 2 17:58:26 2010 From: python-checkins at python.org (r.david.murray) Date: Sat, 2 Oct 2010 17:58:26 +0200 (CEST) Subject: [Python-checkins] r85179 - in python/branches/py3k: Lib/email/_parseaddr.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20101002155826.F3D88F0C3@mail.python.org> Author: r.david.murray Date: Sat Oct 2 17:58:26 2010 New Revision: 85179 Log: #1050268: make parseaddr 'quote' the contents of quoted strings in addresses. Also made the doc string for email._parseaddr's 'quote' function more accurate; I'd love to make the function match the old docstring instead, but other code uses it according the existing semantics. Modified: python/branches/py3k/Lib/email/_parseaddr.py python/branches/py3k/Lib/email/test/test_email.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/email/_parseaddr.py ============================================================================== --- python/branches/py3k/Lib/email/_parseaddr.py (original) +++ python/branches/py3k/Lib/email/_parseaddr.py Sat Oct 2 17:58:26 2010 @@ -160,7 +160,12 @@ def quote(str): - """Add quotes around a string.""" + """Prepare string to be used in a quoted string. + + Turns backslash and double quote characters into quoted pairs. These + are the only characters that need to be quoted inside a quoted string. + Does not add the surrounding double quotes. + """ return str.replace('\\', '\\\\').replace('"', '\\"') @@ -318,7 +323,7 @@ aslist.append('.') self.pos += 1 elif self.field[self.pos] == '"': - aslist.append('"%s"' % self.getquote()) + aslist.append('"%s"' % quote(self.getquote())) elif self.field[self.pos] in self.atomends: break else: 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 Sat Oct 2 17:58:26 2010 @@ -2287,6 +2287,24 @@ # formataddr() quotes the name if there's a dot in it self.assertEqual(utils.formataddr((a, b)), y) + def test_parseaddr_preserves_quoted_pairs_in_addresses(self): + # issue 10005. Note that in the third test the second pair of + # backslashes is not actually a quoted pair because it is not inside a + # comment or quoted string: the address being parsed has a quoted + # string containing a quoted backslash, followed by 'example' and two + # backslashes, followed by another quoted string containing a space and + # the word 'example'. parseaddr copies those two backslashes + # literally. Per rfc5322 this is not technically correct since a \ may + # not appear in an address outside of a quoted string. It is probably + # a sensible Postel interpretation, though. + eq = self.assertEqual + eq(utils.parseaddr('""example" example"@example.com'), + ('', '""example" example"@example.com')) + eq(utils.parseaddr('"\\"example\\" example"@example.com'), + ('', '"\\"example\\" example"@example.com')) + eq(utils.parseaddr('"\\\\"example\\\\" example"@example.com'), + ('', '"\\\\"example\\\\" example"@example.com')) + def test_multiline_from_comment(self): x = """\ Foo Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Oct 2 17:58:26 2010 @@ -87,6 +87,9 @@ Library ------- +- Issue #1050268: parseaddr now correctly quotes double quote and backslash + characters that appear inside quoted strings in email addresses. + - Issue #10004: quoprimime no longer generates a traceback when confronted with invalid characters after '=' in a Q-encoded word. From python-checkins at python.org Sat Oct 2 18:04:44 2010 From: python-checkins at python.org (r.david.murray) Date: Sat, 2 Oct 2010 18:04:44 +0200 (CEST) Subject: [Python-checkins] r85180 - in python/branches/release31-maint: Lib/email/_parseaddr.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20101002160444.C4FC3F538@mail.python.org> Author: r.david.murray Date: Sat Oct 2 18:04:44 2010 New Revision: 85180 Log: Merged revisions 85179 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85179 | r.david.murray | 2010-10-02 11:58:26 -0400 (Sat, 02 Oct 2010) | 6 lines #1050268: make parseaddr 'quote' the contents of quoted strings in addresses. Also made the doc string for email._parseaddr's 'quote' function more accurate; I'd love to make the function match the old docstring instead, but other code uses it according the existing semantics. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/email/_parseaddr.py python/branches/release31-maint/Lib/email/test/test_email.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/email/_parseaddr.py ============================================================================== --- python/branches/release31-maint/Lib/email/_parseaddr.py (original) +++ python/branches/release31-maint/Lib/email/_parseaddr.py Sat Oct 2 18:04:44 2010 @@ -160,7 +160,12 @@ def quote(str): - """Add quotes around a string.""" + """Prepare string to be used in a quoted string. + + Turns backslash and double quote characters into quoted pairs. These + are the only characters that need to be quoted inside a quoted string. + Does not add the surrounding double quotes. + """ return str.replace('\\', '\\\\').replace('"', '\\"') @@ -318,7 +323,7 @@ aslist.append('.') self.pos += 1 elif self.field[self.pos] == '"': - aslist.append('"%s"' % self.getquote()) + aslist.append('"%s"' % quote(self.getquote())) elif self.field[self.pos] in self.atomends: break else: 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 Sat Oct 2 18:04:44 2010 @@ -2283,6 +2283,24 @@ # formataddr() quotes the name if there's a dot in it self.assertEqual(utils.formataddr((a, b)), y) + def test_parseaddr_preserves_quoted_pairs_in_addresses(self): + # issue 10005. Note that in the third test the second pair of + # backslashes is not actually a quoted pair because it is not inside a + # comment or quoted string: the address being parsed has a quoted + # string containing a quoted backslash, followed by 'example' and two + # backslashes, followed by another quoted string containing a space and + # the word 'example'. parseaddr copies those two backslashes + # literally. Per rfc5322 this is not technically correct since a \ may + # not appear in an address outside of a quoted string. It is probably + # a sensible Postel interpretation, though. + eq = self.assertEqual + eq(utils.parseaddr('""example" example"@example.com'), + ('', '""example" example"@example.com')) + eq(utils.parseaddr('"\\"example\\" example"@example.com'), + ('', '"\\"example\\" example"@example.com')) + eq(utils.parseaddr('"\\\\"example\\\\" example"@example.com'), + ('', '"\\\\"example\\\\" example"@example.com')) + def test_multiline_from_comment(self): x = """\ Foo Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sat Oct 2 18:04:44 2010 @@ -121,6 +121,9 @@ Library ------- +- Issue #1050268: parseaddr now correctly quotes double quote and backslash + characters that appear inside quoted strings in email addresses. + - Issue #10004: quoprimime no longer generates a traceback when confronted with invalid characters after '=' in a Q-encoded word. From python-checkins at python.org Sat Oct 2 18:26:06 2010 From: python-checkins at python.org (r.david.murray) Date: Sat, 2 Oct 2010 18:26:06 +0200 (CEST) Subject: [Python-checkins] r85181 - in python/branches/release27-maint: Lib/email/_parseaddr.py Lib/email/test/test_email.py Misc/NEWS Message-ID: <20101002162606.32088F7BF@mail.python.org> Author: r.david.murray Date: Sat Oct 2 18:26:05 2010 New Revision: 85181 Log: Merged revisions 85179 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85179 | r.david.murray | 2010-10-02 11:58:26 -0400 (Sat, 02 Oct 2010) | 6 lines #1050268: make parseaddr 'quote' the contents of quoted strings in addresses. Also made the doc string for email._parseaddr's 'quote' function more accurate; I'd love to make the function match the old docstring instead, but other code uses it according the existing semantics. ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Lib/email/_parseaddr.py python/branches/release27-maint/Lib/email/test/test_email.py python/branches/release27-maint/Misc/NEWS Modified: python/branches/release27-maint/Lib/email/_parseaddr.py ============================================================================== --- python/branches/release27-maint/Lib/email/_parseaddr.py (original) +++ python/branches/release27-maint/Lib/email/_parseaddr.py Sat Oct 2 18:26:05 2010 @@ -160,7 +160,12 @@ def quote(str): - """Add quotes around a string.""" + """Prepare string to be used in a quoted string. + + Turns backslash and double quote characters into quoted pairs. These + are the only characters that need to be quoted inside a quoted string. + Does not add the surrounding double quotes. + """ return str.replace('\\', '\\\\').replace('"', '\\"') @@ -318,7 +323,7 @@ aslist.append('.') self.pos += 1 elif self.field[self.pos] == '"': - aslist.append('"%s"' % self.getquote()) + aslist.append('"%s"' % quote(self.getquote())) elif self.field[self.pos] in self.atomends: break else: Modified: python/branches/release27-maint/Lib/email/test/test_email.py ============================================================================== --- python/branches/release27-maint/Lib/email/test/test_email.py (original) +++ python/branches/release27-maint/Lib/email/test/test_email.py Sat Oct 2 18:26:05 2010 @@ -2287,6 +2287,24 @@ # formataddr() quotes the name if there's a dot in it self.assertEqual(Utils.formataddr((a, b)), y) + def test_parseaddr_preserves_quoted_pairs_in_addresses(self): + # issue 10005. Note that in the third test the second pair of + # backslashes is not actually a quoted pair because it is not inside a + # comment or quoted string: the address being parsed has a quoted + # string containing a quoted backslash, followed by 'example' and two + # backslashes, followed by another quoted string containing a space and + # the word 'example'. parseaddr copies those two backslashes + # literally. Per rfc5322 this is not technically correct since a \ may + # not appear in an address outside of a quoted string. It is probably + # a sensible Postel interpretation, though. + eq = self.assertEqual + eq(Utils.parseaddr('""example" example"@example.com'), + ('', '""example" example"@example.com')) + eq(Utils.parseaddr('"\\"example\\" example"@example.com'), + ('', '"\\"example\\" example"@example.com')) + eq(Utils.parseaddr('"\\\\"example\\\\" example"@example.com'), + ('', '"\\\\"example\\\\" example"@example.com')) + def test_multiline_from_comment(self): x = """\ Foo Modified: python/branches/release27-maint/Misc/NEWS ============================================================================== --- python/branches/release27-maint/Misc/NEWS (original) +++ python/branches/release27-maint/Misc/NEWS Sat Oct 2 18:26:05 2010 @@ -50,6 +50,9 @@ Library ------- +- Issue #1050268: parseaddr now correctly quotes double quote and backslash + characters that appear inside quoted strings in email addresses. + - Issue #10004: quoprimime no longer generates a traceback when confronted with invalid characters after '=' in a Q-encoded word. From python-checkins at python.org Sat Oct 2 19:55:48 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 2 Oct 2010 19:55:48 +0200 (CEST) Subject: [Python-checkins] r85182 - in python/branches/py3k: Lib/test/test_abc.py Misc/NEWS Message-ID: <20101002175548.41D63D536@mail.python.org> Author: benjamin.peterson Date: Sat Oct 2 19:55:47 2010 New Revision: 85182 Log: add a test and a note about metaclasses now being abcs Modified: python/branches/py3k/Lib/test/test_abc.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/test_abc.py ============================================================================== --- python/branches/py3k/Lib/test/test_abc.py (original) +++ python/branches/py3k/Lib/test/test_abc.py Sat Oct 2 19:55:47 2010 @@ -105,6 +105,19 @@ pass self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__") + def test_metaclass_abc(self): + # Metaclasses can be ABCs, too. + class A(metaclass=abc.ABCMeta): + @abc.abstractmethod + def x(self): + pass + self.assertEqual(A.__abstractmethods__, {"x"}) + class meta(type, A): + def x(self): + return 1 + class C(metaclass=meta): + pass + def test_registration_basics(self): class A(metaclass=abc.ABCMeta): pass Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Oct 2 19:55:47 2010 @@ -10,14 +10,15 @@ Core and Builtins ----------------- +- Issue #10006: type.__abstractmethods__ now raises an AttributeError. As a + result metaclasses can now be ABCs (see #9533). + - Issue #8670: ctypes.c_wchar supports non-BMP characters with 32 bits wchar_t. - Issue #8670: PyUnicode_AsWideChar() and PyUnicode_AsWideCharString() replace UTF-16 surrogate pairs by single non-BMP characters for 16 bits Py_UNICODE and 32 bits wchar_t (eg. Linux in narrow build). -- Issue #10006: type.__abstractmethods__ now raises an AttributeError. - - Issue #10003: Allow handling of SIGBREAK on Windows. Fixes a regression introduced by issue #9324. From python-checkins at python.org Sat Oct 2 20:04:55 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 2 Oct 2010 20:04:55 +0200 (CEST) Subject: [Python-checkins] r85183 - in python/branches/release31-maint: Lib/test/test_abc.py Misc/NEWS Objects/typeobject.c Message-ID: <20101002180455.DBBC1E42C@mail.python.org> Author: benjamin.peterson Date: Sat Oct 2 20:04:55 2010 New Revision: 85183 Log: Merged revisions 85154,85182 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85154 | benjamin.peterson | 2010-10-01 19:03:31 -0500 (Fri, 01 Oct 2010) | 1 line type.__abstractmethods__ should raise an AttributeError #10006 ........ r85182 | benjamin.peterson | 2010-10-02 12:55:47 -0500 (Sat, 02 Oct 2010) | 1 line add a test and a note about metaclasses now being abcs ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_abc.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Objects/typeobject.c Modified: python/branches/release31-maint/Lib/test/test_abc.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_abc.py (original) +++ python/branches/release31-maint/Lib/test/test_abc.py Sat Oct 2 20:04:55 2010 @@ -60,6 +60,26 @@ self.assertRaises(TypeError, F) # because bar is abstract now self.assertTrue(isabstract(F)) + def test_type_has_no_abstractmethods(self): + # type pretends not to have __abstractmethods__. + self.assertRaises(AttributeError, getattr, type, "__abstractmethods__") + class meta(type): + pass + self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__") + + def test_metaclass_abc(self): + # Metaclasses can be ABCs, too. + class A(metaclass=abc.ABCMeta): + @abc.abstractmethod + def x(self): + pass + self.assertEqual(A.__abstractmethods__, {"x"}) + class meta(type, A): + def x(self): + return 1 + class C(metaclass=meta): + pass + def test_registration_basics(self): class A(metaclass=abc.ABCMeta): pass Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sat Oct 2 20:04:55 2010 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #10006: type.__abstractmethods__ now raises an AttributeError. As a + result metaclasses can now be ABCs (see #9533). + - Issue #9930: Remove bogus subtype check that was causing (e.g.) float.__rdiv__(2.0, 3) to return NotImplemented instead of the expected 1.5. Modified: python/branches/release31-maint/Objects/typeobject.c ============================================================================== --- python/branches/release31-maint/Objects/typeobject.c (original) +++ python/branches/release31-maint/Objects/typeobject.c Sat Oct 2 20:04:55 2010 @@ -320,8 +320,11 @@ static PyObject * type_abstractmethods(PyTypeObject *type, void *context) { - PyObject *mod = PyDict_GetItemString(type->tp_dict, - "__abstractmethods__"); + PyObject *mod = NULL; + /* type its self has an __abstractmethods__ descriptor (this). Don't + return that. */ + if (type != &PyType_Type) + mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__"); if (!mod) { PyErr_Format(PyExc_AttributeError, "__abstractmethods__"); return NULL; From python-checkins at python.org Sat Oct 2 20:18:22 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 20:18:22 +0200 (CEST) Subject: [Python-checkins] r85184 - tracker/instances/python-dev/rietveld/settings.py Message-ID: <20101002181822.88E3AC5CA@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 20:18:22 2010 New Revision: 85184 Log: Fix typo. Modified: tracker/instances/python-dev/rietveld/settings.py Modified: tracker/instances/python-dev/rietveld/settings.py ============================================================================== --- tracker/instances/python-dev/rietveld/settings.py (original) +++ tracker/instances/python-dev/rietveld/settings.py Sat Oct 2 20:18:22 2010 @@ -15,7 +15,7 @@ _c = ConfigParser.ConfigParser({'password':'', 'port':''}) _c.read(os.path.dirname(__file__)+"/../config.ini") -TRACKER_COOKIE_NAME=re.sub('[^a-zA-Z]', '', _c.get('tracker','name')) +TRACKER_COOKIE_NAME='roundup_session_'+re.sub('[^a-zA-Z]', '', _c.get('tracker','name')) DATABASE_ENGINE = 'postgresql_psycopg2' DATABASE_NAME = _c.get('rdbms', 'name') From python-checkins at python.org Sat Oct 2 20:18:44 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 20:18:44 +0200 (CEST) Subject: [Python-checkins] r85185 - tracker/instances/python-dev/rietveld/roundup_helper/models.py Message-ID: <20101002181844.0BF94DD08@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 20:18:43 2010 New Revision: 85185 Log: Wrap Issue and File. Modified: tracker/instances/python-dev/rietveld/roundup_helper/models.py Modified: tracker/instances/python-dev/rietveld/roundup_helper/models.py ============================================================================== --- tracker/instances/python-dev/rietveld/roundup_helper/models.py (original) +++ tracker/instances/python-dev/rietveld/roundup_helper/models.py Sat Oct 2 20:18:43 2010 @@ -13,3 +13,19 @@ _address = models.CharField() class Meta: db_table = '_user' + +class File(models.Model): + _creator = models.IntegerField() + _creation = models.DateTimeField() + _branch = models.CharField() + _revision = models.CharField() + _patchset = models.CharField() + class Meta: + db_table = '_file' + +class Issue(models.Model): + _creator = models.IntegerField() + _creation = models.DateTimeField() + _status = models.IntegerField() + class Meta: + db_table = '_issue' From python-checkins at python.org Sat Oct 2 20:27:56 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 20:27:56 +0200 (CEST) Subject: [Python-checkins] r85186 - tracker/instances/python-dev/rietveld/gae2django.diff Message-ID: <20101002182756.466FDDD08@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 20:27:56 2010 New Revision: 85186 Log: Fix urlfetch redirect bug. Added: tracker/instances/python-dev/rietveld/gae2django.diff (contents, props changed) Added: tracker/instances/python-dev/rietveld/gae2django.diff ============================================================================== --- (empty file) +++ tracker/instances/python-dev/rietveld/gae2django.diff Sat Oct 2 20:27:56 2010 @@ -0,0 +1,18 @@ +Index: gaeapi/appengine/api/urlfetch.py +=================================================================== +--- gaeapi/appengine/api/urlfetch.py (Revision 134) ++++ gaeapi/appengine/api/urlfetch.py (Arbeitskopie) +@@ -76,10 +76,11 @@ + connection.close() + + if http_response.status in REDIRECT_STATUSES: +- url = http_response.getheader('Location', None) +- if url is None: ++ newurl = http_response.getheader('Location', None) ++ if newurl is None: + raise DownloadError('Redirect is missing Location header.') + else: ++ url = urlparse.urljoin(url, newurl) + method = 'GET' + else: + response = Response() From python-checkins at python.org Sat Oct 2 20:31:37 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 20:31:37 +0200 (CEST) Subject: [Python-checkins] r85187 - tracker/instances/python-dev/scripts/addpatchsets Message-ID: <20101002183137.73EB3E96E@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 20:31:37 2010 New Revision: 85187 Log: Script to install patches as patchsets. Added: tracker/instances/python-dev/scripts/addpatchsets (contents, props changed) Added: tracker/instances/python-dev/scripts/addpatchsets ============================================================================== --- (empty file) +++ tracker/instances/python-dev/scripts/addpatchsets Sat Oct 2 20:31:37 2010 @@ -0,0 +1,97 @@ +#!/usr/bin/python +import sys, os +basedir = os.path.dirname(os.path.dirname(__file__)) +sys.path.append(basedir+"/rietveld") +os.environ["DJANGO_SETTINGS_MODULE"]="settings" +import gae2django +gae2django.install(server_software='Django') + +verbose = False +if len(sys.argv)==2 and sys.argv[1]=='-v': + verbose=True + +from codereview.models import Repository, Branch, PatchSet, Issue +from django.contrib.auth.models import User +from codereview import engine +from roundup_helper.models import File, Issue as RoundupIssue +from django.db import connection, transaction +from google.appengine.ext import db as gae_db + +transaction.enter_transaction_management() +transaction.managed() +python = Repository.gql("WHERE name = 'Python'").get() + +_branches={} +def get_branch(branchname): + try: + return _branches[branchname] + except KeyError: + branch = Branch.gql("WHERE url = '%s%s/'" % (python.url, branchname[1:])).get() + _branches[branchname] = branch + return branch + +def fetch_patches(patches): + try: + # fetch base file for each patch + for patch in patches: + content = engine.FetchBase(branch.url, patch) + content.put() + patch.content = content + # success + return patches + except engine.FetchError, e: + if verbose: + print "Fetching base failed", e + return None + +c = connection.cursor() +c.execute("select id from _status where _name='closed'") +closed = c.fetchone()[0] + +for f in (File.objects.filter(_patchset__isnull=True, + _branch__isnull=False). + order_by('-id')): + branchname = f._branch + branch = get_branch(branchname) + if not branch: + if verbose: + print branchname,"not found", python.url + continue + c.execute("select nodeid from issue_files where linkid=%s", (f.id,)) + nodeid = c.fetchone()[0] + roundup = RoundupIssue.objects.get(id=nodeid) + if roundup._status == closed: + print "issue",nodeid,"is closed" + continue + issue = Issue.objects.get(id=nodeid) + filename = os.path.join(basedir, "db", "files", "file", + str(nodeid/1000), "file"+str(nodeid)) + if not os.path.exists(filename): + print filename,"not found" + continue + data = open(filename).read() + blob = gae_db.Blob(engine.UnifyLinebreaks(data)) + if verbose: + print "Doing", f.id + patchset = PatchSet(issue=issue, data=blob, parent=issue, + owner=User.objects.get(id=f._creator), + created=f._creation, modified=f._creation) + patchset.put() + issue.patchset=patchset + issue.put() + f._patchset = str(patchset.id) + f.save() + #import pdb;pdb.set_trace() + patches = engine.ParsePatchSet(patchset) + if patches: + patches = fetch_patches(patches) + if patches: + gae_db.put(patches) + transaction.commit() + if verbose: + print f.id, "succeeded" + else: + transaction.rollback() + print f.id, "failed" + +transaction.leave_transaction_management() From python-checkins at python.org Sat Oct 2 21:12:13 2010 From: python-checkins at python.org (phillip.eby) Date: Sat, 2 Oct 2010 21:12:13 +0200 (CEST) Subject: [Python-checkins] r85188 - in sandbox/trunk/setuptools/setuptools: archive_util.py command/easy_install.py Message-ID: <20101002191213.EE11EF542@mail.python.org> Author: phillip.eby Date: Sat Oct 2 21:12:13 2010 New Revision: 85188 Log: Tarfile link support, and handle .pyd/.dll files installed as data on win32. Modified: sandbox/trunk/setuptools/setuptools/archive_util.py sandbox/trunk/setuptools/setuptools/command/easy_install.py Modified: sandbox/trunk/setuptools/setuptools/archive_util.py ============================================================================== --- sandbox/trunk/setuptools/setuptools/archive_util.py (original) +++ sandbox/trunk/setuptools/setuptools/archive_util.py Sat Oct 2 21:12:13 2010 @@ -180,11 +180,15 @@ try: tarobj.chown = lambda *args: None # don't do any chowning! for member in tarobj: - if member.isfile() or member.isdir(): - name = member.name - # don't extract absolute paths or ones with .. in them - if not name.startswith('/') and '..' not in name: - dst = os.path.join(extract_dir, *name.split('/')) + name = member.name + # don't extract absolute paths or ones with .. in them + if not name.startswith('/') and '..' not in name: + dst = os.path.join(extract_dir, *name.split('/')) + + while member.islnk() or member.issym(): + member = tarobj._getmember(member.linkname, member) + + if member.isfile() or member.isdir(): dst = progress_filter(name, dst) if dst: if dst.endswith(os.sep): @@ -198,8 +202,4 @@ tarobj.close() - - extraction_drivers = unpack_directory, unpack_zipfile, unpack_tarfile - - Modified: sandbox/trunk/setuptools/setuptools/command/easy_install.py ============================================================================== --- sandbox/trunk/setuptools/setuptools/command/easy_install.py (original) +++ sandbox/trunk/setuptools/setuptools/command/easy_install.py Sat Oct 2 21:12:13 2010 @@ -1274,7 +1274,7 @@ prefixes = [ ('PURELIB/', ''), ('PLATLIB/pywin32_system32', ''), - ('PLATLIB/', ''), + ('PLATLIB/', ''), ('DATA/lib/site-packages/', ''), ('SCRIPTS/', 'EGG-INFO/scripts/') ] z = zipfile.ZipFile(exe_filename) From python-checkins at python.org Sat Oct 2 21:15:31 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 21:15:31 +0200 (CEST) Subject: [Python-checkins] r85189 - in tracker/instances/python-dev: rietveld/roundup_helper/models.py scripts/addpatchsets Message-ID: <20101002191531.A24DCE140@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 21:15:31 2010 New Revision: 85189 Log: Rename Issue to RoundupIssue, to avoid conflicts in GQL Modified: tracker/instances/python-dev/rietveld/roundup_helper/models.py tracker/instances/python-dev/scripts/addpatchsets Modified: tracker/instances/python-dev/rietveld/roundup_helper/models.py ============================================================================== --- tracker/instances/python-dev/rietveld/roundup_helper/models.py (original) +++ tracker/instances/python-dev/rietveld/roundup_helper/models.py Sat Oct 2 21:15:31 2010 @@ -23,7 +23,7 @@ class Meta: db_table = '_file' -class Issue(models.Model): +class RoundupIssue(models.Model): _creator = models.IntegerField() _creation = models.DateTimeField() _status = models.IntegerField() Modified: tracker/instances/python-dev/scripts/addpatchsets ============================================================================== --- tracker/instances/python-dev/scripts/addpatchsets (original) +++ tracker/instances/python-dev/scripts/addpatchsets Sat Oct 2 21:15:31 2010 @@ -13,7 +13,7 @@ from codereview.models import Repository, Branch, PatchSet, Issue from django.contrib.auth.models import User from codereview import engine -from roundup_helper.models import File, Issue as RoundupIssue +from roundup_helper.models import File, RoundupIssue from django.db import connection, transaction from google.appengine.ext import db as gae_db From python-checkins at python.org Sat Oct 2 21:16:45 2010 From: python-checkins at python.org (phillip.eby) Date: Sat, 2 Oct 2010 21:16:45 +0200 (CEST) Subject: [Python-checkins] r85190 - in sandbox/branches/setuptools-0.6: EasyInstall.txt setuptools/archive_util.py setuptools/command/easy_install.py Message-ID: <20101002191645.E0548F569@mail.python.org> Author: phillip.eby Date: Sat Oct 2 21:16:45 2010 New Revision: 85190 Log: Tarfile link support, and handle .pyd/.dll files installed as data on win32. Modified: sandbox/branches/setuptools-0.6/EasyInstall.txt sandbox/branches/setuptools-0.6/setuptools/archive_util.py sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Modified: sandbox/branches/setuptools-0.6/EasyInstall.txt ============================================================================== --- sandbox/branches/setuptools-0.6/EasyInstall.txt (original) +++ sandbox/branches/setuptools-0.6/EasyInstall.txt Sat Oct 2 21:16:45 2010 @@ -1226,6 +1226,11 @@ * Fix for recent Sourceforge downloading changes + * Handle .exe's containing .pyd or .dll files installed as "data" on win32 + + * Extract copies of hardlinked and symlinked files in tarballs when extracting + source + 0.6c11 * Fix installed script .exe files not working with 64-bit Python on Windows (wasn't actually released in 0.6c10 due to a lost checkin) Modified: sandbox/branches/setuptools-0.6/setuptools/archive_util.py ============================================================================== --- sandbox/branches/setuptools-0.6/setuptools/archive_util.py (original) +++ sandbox/branches/setuptools-0.6/setuptools/archive_util.py Sat Oct 2 21:16:45 2010 @@ -180,11 +180,15 @@ try: tarobj.chown = lambda *args: None # don't do any chowning! for member in tarobj: - if member.isfile() or member.isdir(): - name = member.name - # don't extract absolute paths or ones with .. in them - if not name.startswith('/') and '..' not in name: - dst = os.path.join(extract_dir, *name.split('/')) + name = member.name + # don't extract absolute paths or ones with .. in them + if not name.startswith('/') and '..' not in name: + dst = os.path.join(extract_dir, *name.split('/')) + + while member.islnk() or member.issym(): + member = tarobj._getmember(member.linkname, member) + + if member.isfile() or member.isdir(): dst = progress_filter(name, dst) if dst: if dst.endswith(os.sep): @@ -198,8 +202,4 @@ tarobj.close() - - extraction_drivers = unpack_directory, unpack_zipfile, unpack_tarfile - - Modified: sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py ============================================================================== --- sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py (original) +++ sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Sat Oct 2 21:16:45 2010 @@ -1274,7 +1274,7 @@ prefixes = [ ('PURELIB/', ''), ('PLATLIB/pywin32_system32', ''), - ('PLATLIB/', ''), + ('PLATLIB/', ''), ('DATA/lib/site-packages/', ''), ('SCRIPTS/', 'EGG-INFO/scripts/') ] z = zipfile.ZipFile(exe_filename) From python-checkins at python.org Sat Oct 2 21:40:49 2010 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 2 Oct 2010 21:40:49 +0200 (CEST) Subject: [Python-checkins] r85191 - in tracker/instances/python-dev: extensions/rietveldlink.py html/issue.item.html Message-ID: <20101002194049.34730DE47@mail.python.org> Author: martin.v.loewis Date: Sat Oct 2 21:40:49 2010 New Revision: 85191 Log: Add Rietveld links to files. Added: tracker/instances/python-dev/extensions/rietveldlink.py (contents, props changed) Modified: tracker/instances/python-dev/html/issue.item.html Added: tracker/instances/python-dev/extensions/rietveldlink.py ============================================================================== --- (empty file) +++ tracker/instances/python-dev/extensions/rietveldlink.py Sat Oct 2 21:40:49 2010 @@ -0,0 +1,7 @@ +def rietveldlink(request, issueid, fileid): + if request.client.db.file.get(fileid, 'patchset'): + return '/review/%s/show' % issueid + return "" + +def init(instance): + instance.registerUtil('rietveldlink', rietveldlink) Modified: tracker/instances/python-dev/html/issue.item.html ============================================================================== --- tracker/instances/python-dev/html/issue.item.html (original) +++ tracker/instances/python-dev/html/issue.item.html Sat Oct 2 21:40:49 2010 @@ -223,6 +223,9 @@ edit + + review +
Author: martin.v.loewis Date: Sat Oct 2 23:41:48 2010 New Revision: 85192 Log: Remove Google analytics stuff. Modified: tracker/instances/python-dev/rietveld/templates/base.html Modified: tracker/instances/python-dev/rietveld/templates/base.html ============================================================================== --- tracker/instances/python-dev/rietveld/templates/base.html (original) +++ tracker/instances/python-dev/rietveld/templates/base.html Sat Oct 2 23:41:48 2010 @@ -237,14 +237,5 @@
{%include "live_revision.html"%}
- - From python-checkins at python.org Sun Oct 3 04:13:39 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 3 Oct 2010 04:13:39 +0200 (CEST) Subject: [Python-checkins] r85193 - python/branches/py3k/Objects/typeobject.c Message-ID: <20101003021339.90C64FDD9@mail.python.org> Author: benjamin.peterson Date: Sun Oct 3 04:13:39 2010 New Revision: 85193 Log: typo Modified: 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 Sun Oct 3 04:13:39 2010 @@ -321,8 +321,8 @@ type_abstractmethods(PyTypeObject *type, void *context) { PyObject *mod = NULL; - /* type its self has an __abstractmethods__ descriptor (this). Don't - return that. */ + /* type itself has an __abstractmethods__ descriptor (this). Don't return + that. */ if (type != &PyType_Type) mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__"); if (!mod) { From python-checkins at python.org Sun Oct 3 04:17:04 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 3 Oct 2010 04:17:04 +0200 (CEST) Subject: [Python-checkins] r85194 - in python/branches/release27-maint: Objects/typeobject.c Message-ID: <20101003021704.7570FFDD9@mail.python.org> Author: benjamin.peterson Date: Sun Oct 3 04:17:04 2010 New Revision: 85194 Log: Merged revisions 85193 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85193 | benjamin.peterson | 2010-10-02 21:13:39 -0500 (Sat, 02 Oct 2010) | 1 line typo ........ Modified: python/branches/release27-maint/ (props changed) python/branches/release27-maint/Objects/typeobject.c Modified: python/branches/release27-maint/Objects/typeobject.c ============================================================================== --- python/branches/release27-maint/Objects/typeobject.c (original) +++ python/branches/release27-maint/Objects/typeobject.c Sun Oct 3 04:17:04 2010 @@ -308,8 +308,8 @@ type_abstractmethods(PyTypeObject *type, void *context) { PyObject *mod = NULL; - /* type its self has an __abstractmethods__ descriptor (this). Don't - return that. */ + /* type itself has an __abstractmethods__ descriptor (this). Don't return + that. */ if (type != &PyType_Type) mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__"); if (!mod) { From python-checkins at python.org Sun Oct 3 04:19:18 2010 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 3 Oct 2010 04:19:18 +0200 (CEST) Subject: [Python-checkins] r85195 - in python/branches/release31-maint: Objects/typeobject.c Message-ID: <20101003021918.A44FBFE58@mail.python.org> Author: benjamin.peterson Date: Sun Oct 3 04:19:18 2010 New Revision: 85195 Log: Merged revisions 85193 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r85193 | benjamin.peterson | 2010-10-02 21:13:39 -0500 (Sat, 02 Oct 2010) | 1 line typo ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Objects/typeobject.c Modified: python/branches/release31-maint/Objects/typeobject.c ============================================================================== --- python/branches/release31-maint/Objects/typeobject.c (original) +++ python/branches/release31-maint/Objects/typeobject.c Sun Oct 3 04:19:18 2010 @@ -321,8 +321,8 @@ type_abstractmethods(PyTypeObject *type, void *context) { PyObject *mod = NULL; - /* type its self has an __abstractmethods__ descriptor (this). Don't - return that. */ + /* type itself has an __abstractmethods__ descriptor (this). Don't return + that. */ if (type != &PyType_Type) mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__"); if (!mod) { From solipsis at pitrou.net Sun Oct 3 04:47:30 2010 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 03 Oct 2010 04:47:30 +0200 Subject: [Python-checkins] Daily py3k reference leaks (r85182): sum=0 Message-ID: py3k results for svn r85182 (hg cset 332bee5a9486) -------------------------------------------------- Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog0QhVgA', '-x'] From python-checkins at python.org Sun Oct 3 11:50:25 2010 From: python-checkins at python.org (tarek.ziade) Date: Sun, 03 Oct 2010 11:50:25 +0200 Subject: [Python-checkins] distutils2: make depgraph.main print out the dependencies in the standard output - Message-ID: tarek.ziade pushed 9faea5e66727 to distutils2: http://hg.python.org/distutils2/rev/9faea5e66727 changeset: 738:9faea5e66727 tag: tip user: Tarek Ziade date: Sun Oct 03 11:50:18 2010 +0200 summary: make depgraph.main print out the dependencies in the standard output - outputing a dot file is done via -d files: distutils2/depgraph.py, distutils2/tests/test_depgraph.py diff --git a/distutils2/depgraph.py b/distutils2/depgraph.py --- a/distutils2/depgraph.py +++ b/distutils2/depgraph.py @@ -1,7 +1,8 @@ """Analyse the relationships between the distributions in the system and generate a dependency graph. """ - +import sys +from StringIO import StringIO from distutils2.errors import DistutilsError from distutils2.version import VersionPredicate @@ -65,6 +66,20 @@ """ self.missing[distribution].append(requirement) + def __repr__(self): + """Representation of the graph""" + def _repr_dist(dist): + return '%s %s' % (dist.name, dist.metadata['Version']) + output = [] + for dist, adjs in self.adjacency_list.iteritems(): + output.append(_repr_dist(dist)) + for other, label in adjs: + dist = _repr_dist(other) + if label is not None: + dist = '%s [%s]' % (dist, label) + output.append(' %s' % dist) + return '\n'.join(output) + def graph_to_dot(graph, f, skip_disconnected=True): """Writes a DOT output for the graph to the provided file *f*. @@ -176,13 +191,52 @@ dep.pop(0) # remove dist from dep, was there to prevent infinite loops return dep -if __name__ == '__main__': +def main(): from distutils2._backport.pkgutil import get_distributions - dists = list(get_distributions(use_egg_info=True)) - graph = generate_graph(dists) + tempout = StringIO() + try: + old = sys.stderr + sys.stderr = tempout + try: + dists = list(get_distributions(use_egg_info=True)) + graph = generate_graph(dists) + finally: + sys.stderr = old + except Exception, e: + tempout.seek(0) + tempout = tempout.read() + print('Could not generate the graph\n%s\n%s\n' % (tempout, str(e))) + sys.exit(1) + for dist, reqs in graph.missing.iteritems(): if len(reqs) > 0: - print("Missing dependencies for %s: %s" % (dist.name, + print("Warning: Missing dependencies for %s: %s" % (dist.name, ", ".join(reqs))) - f = open('output.dot', 'w') - graph_to_dot(graph, f, True) + # XXX replace with argparse + if len(sys.argv) == 1: + print('Dependency graph:') + print(' ' + repr(graph).replace('\n', '\n ')) + sys.exit(0) + elif len(sys.argv) > 1 and sys.argv[1] in ('-d', '--dot'): + if len(sys.argv) > 2: + filename = sys.argv[2] + else: + filename = 'depgraph.dot' + + f = open(filename, 'w') + try: + graph_to_dot(graph, f, True) + finally: + f.close() + tempout.seek(0) + tempout = tempout.read() + print(tempout) + print('Dot file written at "%s"' % filename) + sys.exit(0) + else: + print('Supported option: -d [filename]') + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/distutils2/tests/test_depgraph.py b/distutils2/tests/test_depgraph.py --- a/distutils2/tests/test_depgraph.py +++ b/distutils2/tests/test_depgraph.py @@ -21,6 +21,11 @@ r'"(?P.*)" -> "(?P.*)" \[label="(?P