Merge lp:~barry/lazr.smtptest/lp1096475 into lp:lazr.smtptest
- lp1096475
- Merge into devel
Status: | Merged |
---|---|
Merged at revision: | 64 |
Proposed branch: | lp:~barry/lazr.smtptest/lp1096475 |
Merge into: | lp:lazr.smtptest |
Diff against target: |
2051 lines (+780/-881) 28 files modified
HACKING.rst (+17/-3) MANIFEST.in (+2/-3) README.rst (+3/-3) _bootstrap/COPYRIGHT.txt (+0/-9) _bootstrap/LICENSE.txt (+0/-54) _bootstrap/bootstrap.py (+0/-77) buildout-templates/bin/lint.sh.in (+0/-4) buildout.cfg (+0/-47) distribute_setup.py (+546/-0) ez_setup.py (+0/-241) lazr/__init__.py (+12/-8) lazr/smtptest/NEWS.rst (+10/-0) lazr/smtptest/README.rst (+1/-1) lazr/smtptest/README_fixture.py (+27/-0) lazr/smtptest/__init__.py (+1/-1) lazr/smtptest/controller.py (+9/-3) lazr/smtptest/docs/fixture.py (+34/-0) lazr/smtptest/docs/queue.rst (+14/-9) lazr/smtptest/docs/queue_fixture.py (+27/-0) lazr/smtptest/docs/usage.rst (+17/-11) lazr/smtptest/docs/usage_fixture.py (+27/-0) lazr/smtptest/server.py (+10/-7) lazr/smtptest/tests/__init__.py (+0/-16) lazr/smtptest/version.txt (+1/-1) pylint.rc (+0/-310) setup.cfg (+8/-0) setup.py (+14/-21) src/lazr/smtptest/tests/test_docs.py (+0/-52) |
To merge this branch: | bzr merge lp:~barry/lazr.smtptest/lp1096475 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Curtis Hovey (community) | code | Approve | |
Gary Poster | Pending | ||
Review via email: mp+142024@code.launchpad.net |
Commit message
Description of the change
Ported to Python 3. This should now work on 3.3, 3.2, 2.7, and 2.6
I did a bunch of other cleanups, which may or may not be controversial, but makes things much simpler for me.
* Removed the dependency on zc.buildout. I didn't really feel this was buying us much and more standard Python tools like virtualenv and distribute do just fine.
* Moved the lazr directory up one. `src` wasn't buying us much.
* Ported the test suite to nosetests. See HACKING.rst for details.
* Ported to distribute.
* Yes, renamed all documentation to .rst files for better editor support (i.e. rst-mode)
* Updated copyright years.
* Got rid of pylint. Too many false positives to be useful (should be pretty pyflakes clean though).
* Under Python 3.3, use PEP 420 style namespace package for `lazr`.
Barry Warsaw (barry) wrote : | # |
- 72. By Barry Warsaw
-
Update the manifest.
Curtis Hovey (sinzui) wrote : | # |
Thank you Barry.
This looks good for merge and release.
Preview Diff
1 | === renamed file 'HACKING.txt' => 'HACKING.rst' |
2 | --- HACKING.txt 2009-06-22 22:40:16 +0000 |
3 | +++ HACKING.rst 2013-01-07 01:00:29 +0000 |
4 | @@ -13,8 +13,6 @@ |
5 | You should have received a copy of the GNU Lesser General Public License |
6 | along with lazr.smtptest. If not, see <http://www.gnu.org/licenses/>. |
7 | |
8 | -This project uses zc.buildout for development. |
9 | - |
10 | ============ |
11 | Introduction |
12 | ============ |
13 | @@ -26,7 +24,7 @@ |
14 | |
15 | |
16 | Getting help |
17 | ------------- |
18 | +============ |
19 | |
20 | If you find bugs in this package, you can report them here: |
21 | |
22 | @@ -39,3 +37,19 @@ |
23 | or send a message to: |
24 | |
25 | lazr-users@lists.launchpad.net |
26 | + |
27 | + |
28 | +Running the tests |
29 | +================= |
30 | + |
31 | +The tests suite requires nose_ and is compatible with both Python 2 and |
32 | +Python 3. To run the full test suite:: |
33 | + |
34 | + $ python setup.py nosetests |
35 | + |
36 | +Where ``python`` is the Python executable to use for the tests. E.g. this |
37 | +might be ``python3`` for Python 3, or the Python executable from a |
38 | +virtualenv_. |
39 | + |
40 | +.. _nose: https://nose.readthedocs.org/en/latest/ |
41 | +.. _virtualenv: http://www.virtualenv.org/en/latest/ |
42 | |
43 | === modified file 'MANIFEST.in' |
44 | --- MANIFEST.in 2009-06-22 22:40:16 +0000 |
45 | +++ MANIFEST.in 2013-01-07 01:00:29 +0000 |
46 | @@ -1,4 +1,3 @@ |
47 | include *.py *.rc *.txt |
48 | -recursive-include src *.txt |
49 | -exclude MANIFEST.in buildout.cfg bootstrap.py .bzrignore |
50 | -prune _bootstrap |
51 | +recursive-include *.txt |
52 | +exclude MANIFEST.in .bzrignore |
53 | |
54 | === renamed file 'README.txt' => 'README.rst' |
55 | --- README.txt 2009-06-23 00:27:13 +0000 |
56 | +++ README.rst 2013-01-07 01:00:29 +0000 |
57 | @@ -7,9 +7,9 @@ |
58 | under the terms of the GNU Lesser General Public License as published by |
59 | the Free Software Foundation, version 3 of the License. |
60 | |
61 | - lazr.smtptest is distributed in the hope that it will be useful, but WITHOUT |
62 | - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
63 | - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
64 | + lazr.smtptest is distributed in the hope that it will be useful, but |
65 | + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
66 | + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
67 | License for more details. |
68 | |
69 | You should have received a copy of the GNU Lesser General Public License |
70 | |
71 | === removed directory '_bootstrap' |
72 | === removed file '_bootstrap/COPYRIGHT.txt' |
73 | --- _bootstrap/COPYRIGHT.txt 2009-03-23 19:12:50 +0000 |
74 | +++ _bootstrap/COPYRIGHT.txt 1970-01-01 00:00:00 +0000 |
75 | @@ -1,9 +0,0 @@ |
76 | -Copyright (c) 2004-2009 Zope Corporation and Contributors. |
77 | -All Rights Reserved. |
78 | - |
79 | -This software is subject to the provisions of the Zope Public License, |
80 | -Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
81 | -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
82 | -WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
83 | -WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
84 | -FOR A PARTICULAR PURPOSE. |
85 | |
86 | === removed file '_bootstrap/LICENSE.txt' |
87 | --- _bootstrap/LICENSE.txt 2009-03-23 19:12:50 +0000 |
88 | +++ _bootstrap/LICENSE.txt 1970-01-01 00:00:00 +0000 |
89 | @@ -1,54 +0,0 @@ |
90 | -Zope Public License (ZPL) Version 2.1 |
91 | -------------------------------------- |
92 | - |
93 | -A copyright notice accompanies this license document that |
94 | -identifies the copyright holders. |
95 | - |
96 | -This license has been certified as open source. It has also |
97 | -been designated as GPL compatible by the Free Software |
98 | -Foundation (FSF). |
99 | - |
100 | -Redistribution and use in source and binary forms, with or |
101 | -without modification, are permitted provided that the |
102 | -following conditions are met: |
103 | - |
104 | -1. Redistributions in source code must retain the |
105 | - accompanying copyright notice, this list of conditions, |
106 | - and the following disclaimer. |
107 | - |
108 | -2. Redistributions in binary form must reproduce the accompanying |
109 | - copyright notice, this list of conditions, and the |
110 | - following disclaimer in the documentation and/or other |
111 | - materials provided with the distribution. |
112 | - |
113 | -3. Names of the copyright holders must not be used to |
114 | - endorse or promote products derived from this software |
115 | - without prior written permission from the copyright |
116 | - holders. |
117 | - |
118 | -4. The right to distribute this software or to use it for |
119 | - any purpose does not give you the right to use |
120 | - Servicemarks (sm) or Trademarks (tm) of the copyright |
121 | - holders. Use of them is covered by separate agreement |
122 | - with the copyright holders. |
123 | - |
124 | -5. If any files are modified, you must cause the modified |
125 | - files to carry prominent notices stating that you changed |
126 | - the files and the date of any change. |
127 | - |
128 | -Disclaimer |
129 | - |
130 | - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' |
131 | - AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT |
132 | - NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
133 | - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN |
134 | - NO EVENT SHALL THE COPYRIGHT HOLDERS BE |
135 | - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
136 | - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
137 | - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
138 | - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
139 | - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
140 | - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
141 | - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
142 | - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
143 | - DAMAGE. |
144 | \ No newline at end of file |
145 | |
146 | === removed file '_bootstrap/bootstrap.py' |
147 | --- _bootstrap/bootstrap.py 2009-03-23 19:12:50 +0000 |
148 | +++ _bootstrap/bootstrap.py 1970-01-01 00:00:00 +0000 |
149 | @@ -1,77 +0,0 @@ |
150 | -############################################################################## |
151 | -# |
152 | -# Copyright (c) 2006 Zope Corporation and Contributors. |
153 | -# All Rights Reserved. |
154 | -# |
155 | -# This software is subject to the provisions of the Zope Public License, |
156 | -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
157 | -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
158 | -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
159 | -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
160 | -# FOR A PARTICULAR PURPOSE. |
161 | -# |
162 | -############################################################################## |
163 | -"""Bootstrap a buildout-based project |
164 | - |
165 | -Simply run this script in a directory containing a buildout.cfg. |
166 | -The script accepts buildout command-line options, so you can |
167 | -use the -c option to specify an alternate configuration file. |
168 | - |
169 | -$Id$ |
170 | -""" |
171 | - |
172 | -import os, shutil, sys, tempfile, urllib2 |
173 | - |
174 | -tmpeggs = tempfile.mkdtemp() |
175 | - |
176 | -is_jython = sys.platform.startswith('java') |
177 | - |
178 | -try: |
179 | - import pkg_resources |
180 | -except ImportError: |
181 | - ez = {} |
182 | - exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' |
183 | - ).read() in ez |
184 | - ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) |
185 | - |
186 | - import pkg_resources |
187 | - |
188 | -if sys.platform == 'win32': |
189 | - def quote(c): |
190 | - if ' ' in c: |
191 | - return '"%s"' % c # work around spawn lamosity on windows |
192 | - else: |
193 | - return c |
194 | -else: |
195 | - def quote (c): |
196 | - return c |
197 | - |
198 | -cmd = 'from setuptools.command.easy_install import main; main()' |
199 | -ws = pkg_resources.working_set |
200 | - |
201 | -if is_jython: |
202 | - import subprocess |
203 | - |
204 | - assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd', |
205 | - quote(tmpeggs), 'zc.buildout'], |
206 | - env=dict(os.environ, |
207 | - PYTHONPATH= |
208 | - ws.find(pkg_resources.Requirement.parse('setuptools')).location |
209 | - ), |
210 | - ).wait() == 0 |
211 | - |
212 | -else: |
213 | - assert os.spawnle( |
214 | - os.P_WAIT, sys.executable, quote (sys.executable), |
215 | - '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout', |
216 | - dict(os.environ, |
217 | - PYTHONPATH= |
218 | - ws.find(pkg_resources.Requirement.parse('setuptools')).location |
219 | - ), |
220 | - ) == 0 |
221 | - |
222 | -ws.add_entry(tmpeggs) |
223 | -ws.require('zc.buildout') |
224 | -import zc.buildout.buildout |
225 | -zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap']) |
226 | -shutil.rmtree(tmpeggs) |
227 | |
228 | === removed symlink 'bootstrap.py' |
229 | === target was u'_bootstrap/bootstrap.py' |
230 | === removed directory 'buildout-templates' |
231 | === removed directory 'buildout-templates/bin' |
232 | === removed file 'buildout-templates/bin/lint.sh.in' |
233 | --- buildout-templates/bin/lint.sh.in 2009-06-22 22:40:16 +0000 |
234 | +++ buildout-templates/bin/lint.sh.in 1970-01-01 00:00:00 +0000 |
235 | @@ -1,4 +0,0 @@ |
236 | -#! /bin/bash |
237 | - |
238 | -export PYTHONPATH=${os-paths} |
239 | -bin/pylint ${package} --rcfile=pylint.rc |
240 | |
241 | === removed file 'buildout.cfg' |
242 | --- buildout.cfg 2009-06-22 22:40:16 +0000 |
243 | +++ buildout.cfg 1970-01-01 00:00:00 +0000 |
244 | @@ -1,47 +0,0 @@ |
245 | -[buildout] |
246 | -parts = |
247 | - interpreter |
248 | - test |
249 | - docs |
250 | - tags |
251 | - filetemplates |
252 | - pylint |
253 | -unzip = true |
254 | - |
255 | -develop = . |
256 | - |
257 | -[test] |
258 | -recipe = zc.recipe.testrunner |
259 | -eggs = lazr.smtptest |
260 | -defaults = '--tests-pattern ^tests --exit-with-status --suite-name additional_tests'.split() |
261 | - |
262 | -[docs] |
263 | -recipe = z3c.recipe.sphinxdoc |
264 | -eggs = lazr.smtptest [docs] |
265 | -index-doc = README |
266 | -default.css = |
267 | -layout.html = |
268 | - |
269 | -[interpreter] |
270 | -recipe = zc.recipe.egg |
271 | -interpreter = py |
272 | -eggs = lazr.smtptest |
273 | - docutils |
274 | - |
275 | -[tags] |
276 | -recipe = z3c.recipe.tag:tags |
277 | -eggs = lazr.smtptest |
278 | - |
279 | -[filetemplates] |
280 | -recipe = z3c.recipe.filetemplate |
281 | -source-directory = buildout-templates |
282 | -package = lazr.smtptest |
283 | -eggs = lazr.smtptest |
284 | - |
285 | -[pylint] |
286 | -recipe = zc.recipe.egg |
287 | -eggs = |
288 | - logilab.pylintinstaller |
289 | - pylint==0.15.2 |
290 | -entry-points = pylint=pylint.lint:Run |
291 | -arguments = sys.argv[1:] |
292 | |
293 | === added file 'distribute_setup.py' |
294 | --- distribute_setup.py 1970-01-01 00:00:00 +0000 |
295 | +++ distribute_setup.py 2013-01-07 01:00:29 +0000 |
296 | @@ -0,0 +1,546 @@ |
297 | +#!python |
298 | +"""Bootstrap distribute installation |
299 | + |
300 | +If you want to use setuptools in your package's setup.py, just include this |
301 | +file in the same directory with it, and add this to the top of your setup.py:: |
302 | + |
303 | + from distribute_setup import use_setuptools |
304 | + use_setuptools() |
305 | + |
306 | +If you want to require a specific version of setuptools, set a download |
307 | +mirror, or use an alternate download directory, you can do so by supplying |
308 | +the appropriate options to ``use_setuptools()``. |
309 | + |
310 | +This file can also be run as a script to install or upgrade setuptools. |
311 | +""" |
312 | +import os |
313 | +import shutil |
314 | +import sys |
315 | +import time |
316 | +import fnmatch |
317 | +import tempfile |
318 | +import tarfile |
319 | +import optparse |
320 | + |
321 | +from distutils import log |
322 | + |
323 | +try: |
324 | + from site import USER_SITE |
325 | +except ImportError: |
326 | + USER_SITE = None |
327 | + |
328 | +try: |
329 | + import subprocess |
330 | + |
331 | + def _python_cmd(*args): |
332 | + args = (sys.executable,) + args |
333 | + return subprocess.call(args) == 0 |
334 | + |
335 | +except ImportError: |
336 | + # will be used for python 2.3 |
337 | + def _python_cmd(*args): |
338 | + args = (sys.executable,) + args |
339 | + # quoting arguments if windows |
340 | + if sys.platform == 'win32': |
341 | + def quote(arg): |
342 | + if ' ' in arg: |
343 | + return '"%s"' % arg |
344 | + return arg |
345 | + args = [quote(arg) for arg in args] |
346 | + return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 |
347 | + |
348 | +DEFAULT_VERSION = "0.6.34" |
349 | +DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" |
350 | +SETUPTOOLS_FAKED_VERSION = "0.6c11" |
351 | + |
352 | +SETUPTOOLS_PKG_INFO = """\ |
353 | +Metadata-Version: 1.0 |
354 | +Name: setuptools |
355 | +Version: %s |
356 | +Summary: xxxx |
357 | +Home-page: xxx |
358 | +Author: xxx |
359 | +Author-email: xxx |
360 | +License: xxx |
361 | +Description: xxx |
362 | +""" % SETUPTOOLS_FAKED_VERSION |
363 | + |
364 | + |
365 | +def _install(tarball, install_args=()): |
366 | + # extracting the tarball |
367 | + tmpdir = tempfile.mkdtemp() |
368 | + log.warn('Extracting in %s', tmpdir) |
369 | + old_wd = os.getcwd() |
370 | + try: |
371 | + os.chdir(tmpdir) |
372 | + tar = tarfile.open(tarball) |
373 | + _extractall(tar) |
374 | + tar.close() |
375 | + |
376 | + # going in the directory |
377 | + subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) |
378 | + os.chdir(subdir) |
379 | + log.warn('Now working in %s', subdir) |
380 | + |
381 | + # installing |
382 | + log.warn('Installing Distribute') |
383 | + if not _python_cmd('setup.py', 'install', *install_args): |
384 | + log.warn('Something went wrong during the installation.') |
385 | + log.warn('See the error message above.') |
386 | + # exitcode will be 2 |
387 | + return 2 |
388 | + finally: |
389 | + os.chdir(old_wd) |
390 | + shutil.rmtree(tmpdir) |
391 | + |
392 | + |
393 | +def _build_egg(egg, tarball, to_dir): |
394 | + # extracting the tarball |
395 | + tmpdir = tempfile.mkdtemp() |
396 | + log.warn('Extracting in %s', tmpdir) |
397 | + old_wd = os.getcwd() |
398 | + try: |
399 | + os.chdir(tmpdir) |
400 | + tar = tarfile.open(tarball) |
401 | + _extractall(tar) |
402 | + tar.close() |
403 | + |
404 | + # going in the directory |
405 | + subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) |
406 | + os.chdir(subdir) |
407 | + log.warn('Now working in %s', subdir) |
408 | + |
409 | + # building an egg |
410 | + log.warn('Building a Distribute egg in %s', to_dir) |
411 | + _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) |
412 | + |
413 | + finally: |
414 | + os.chdir(old_wd) |
415 | + shutil.rmtree(tmpdir) |
416 | + # returning the result |
417 | + log.warn(egg) |
418 | + if not os.path.exists(egg): |
419 | + raise IOError('Could not build the egg.') |
420 | + |
421 | + |
422 | +def _do_download(version, download_base, to_dir, download_delay): |
423 | + egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg' |
424 | + % (version, sys.version_info[0], sys.version_info[1])) |
425 | + if not os.path.exists(egg): |
426 | + tarball = download_setuptools(version, download_base, |
427 | + to_dir, download_delay) |
428 | + _build_egg(egg, tarball, to_dir) |
429 | + sys.path.insert(0, egg) |
430 | + import setuptools |
431 | + setuptools.bootstrap_install_from = egg |
432 | + |
433 | + |
434 | +def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, |
435 | + to_dir=os.curdir, download_delay=15, no_fake=True): |
436 | + # making sure we use the absolute path |
437 | + to_dir = os.path.abspath(to_dir) |
438 | + was_imported = 'pkg_resources' in sys.modules or \ |
439 | + 'setuptools' in sys.modules |
440 | + try: |
441 | + try: |
442 | + import pkg_resources |
443 | + if not hasattr(pkg_resources, '_distribute'): |
444 | + if not no_fake: |
445 | + _fake_setuptools() |
446 | + raise ImportError |
447 | + except ImportError: |
448 | + return _do_download(version, download_base, to_dir, download_delay) |
449 | + try: |
450 | + pkg_resources.require("distribute>=" + version) |
451 | + return |
452 | + except pkg_resources.VersionConflict: |
453 | + e = sys.exc_info()[1] |
454 | + if was_imported: |
455 | + sys.stderr.write( |
456 | + "The required version of distribute (>=%s) is not available,\n" |
457 | + "and can't be installed while this script is running. Please\n" |
458 | + "install a more recent version first, using\n" |
459 | + "'easy_install -U distribute'." |
460 | + "\n\n(Currently using %r)\n" % (version, e.args[0])) |
461 | + sys.exit(2) |
462 | + else: |
463 | + del pkg_resources, sys.modules['pkg_resources'] # reload ok |
464 | + return _do_download(version, download_base, to_dir, |
465 | + download_delay) |
466 | + except pkg_resources.DistributionNotFound: |
467 | + return _do_download(version, download_base, to_dir, |
468 | + download_delay) |
469 | + finally: |
470 | + if not no_fake: |
471 | + _create_fake_setuptools_pkg_info(to_dir) |
472 | + |
473 | + |
474 | +def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, |
475 | + to_dir=os.curdir, delay=15): |
476 | + """Download distribute from a specified location and return its filename |
477 | + |
478 | + `version` should be a valid distribute version number that is available |
479 | + as an egg for download under the `download_base` URL (which should end |
480 | + with a '/'). `to_dir` is the directory where the egg will be downloaded. |
481 | + `delay` is the number of seconds to pause before an actual download |
482 | + attempt. |
483 | + """ |
484 | + # making sure we use the absolute path |
485 | + to_dir = os.path.abspath(to_dir) |
486 | + try: |
487 | + from urllib.request import urlopen |
488 | + except ImportError: |
489 | + from urllib2 import urlopen |
490 | + tgz_name = "distribute-%s.tar.gz" % version |
491 | + url = download_base + tgz_name |
492 | + saveto = os.path.join(to_dir, tgz_name) |
493 | + src = dst = None |
494 | + if not os.path.exists(saveto): # Avoid repeated downloads |
495 | + try: |
496 | + log.warn("Downloading %s", url) |
497 | + src = urlopen(url) |
498 | + # Read/write all in one block, so we don't create a corrupt file |
499 | + # if the download is interrupted. |
500 | + data = src.read() |
501 | + dst = open(saveto, "wb") |
502 | + dst.write(data) |
503 | + finally: |
504 | + if src: |
505 | + src.close() |
506 | + if dst: |
507 | + dst.close() |
508 | + return os.path.realpath(saveto) |
509 | + |
510 | + |
511 | +def _no_sandbox(function): |
512 | + def __no_sandbox(*args, **kw): |
513 | + try: |
514 | + from setuptools.sandbox import DirectorySandbox |
515 | + if not hasattr(DirectorySandbox, '_old'): |
516 | + def violation(*args): |
517 | + pass |
518 | + DirectorySandbox._old = DirectorySandbox._violation |
519 | + DirectorySandbox._violation = violation |
520 | + patched = True |
521 | + else: |
522 | + patched = False |
523 | + except ImportError: |
524 | + patched = False |
525 | + |
526 | + try: |
527 | + return function(*args, **kw) |
528 | + finally: |
529 | + if patched: |
530 | + DirectorySandbox._violation = DirectorySandbox._old |
531 | + del DirectorySandbox._old |
532 | + |
533 | + return __no_sandbox |
534 | + |
535 | + |
536 | +def _patch_file(path, content): |
537 | + """Will backup the file then patch it""" |
538 | + f = open(path) |
539 | + existing_content = f.read() |
540 | + f.close() |
541 | + if existing_content == content: |
542 | + # already patched |
543 | + log.warn('Already patched.') |
544 | + return False |
545 | + log.warn('Patching...') |
546 | + _rename_path(path) |
547 | + f = open(path, 'w') |
548 | + try: |
549 | + f.write(content) |
550 | + finally: |
551 | + f.close() |
552 | + return True |
553 | + |
554 | +_patch_file = _no_sandbox(_patch_file) |
555 | + |
556 | + |
557 | +def _same_content(path, content): |
558 | + f = open(path) |
559 | + existing_content = f.read() |
560 | + f.close() |
561 | + return existing_content == content |
562 | + |
563 | + |
564 | +def _rename_path(path): |
565 | + new_name = path + '.OLD.%s' % time.time() |
566 | + log.warn('Renaming %s to %s', path, new_name) |
567 | + os.rename(path, new_name) |
568 | + return new_name |
569 | + |
570 | + |
571 | +def _remove_flat_installation(placeholder): |
572 | + if not os.path.isdir(placeholder): |
573 | + log.warn('Unkown installation at %s', placeholder) |
574 | + return False |
575 | + found = False |
576 | + for file in os.listdir(placeholder): |
577 | + if fnmatch.fnmatch(file, 'setuptools*.egg-info'): |
578 | + found = True |
579 | + break |
580 | + if not found: |
581 | + log.warn('Could not locate setuptools*.egg-info') |
582 | + return |
583 | + |
584 | + log.warn('Moving elements out of the way...') |
585 | + pkg_info = os.path.join(placeholder, file) |
586 | + if os.path.isdir(pkg_info): |
587 | + patched = _patch_egg_dir(pkg_info) |
588 | + else: |
589 | + patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO) |
590 | + |
591 | + if not patched: |
592 | + log.warn('%s already patched.', pkg_info) |
593 | + return False |
594 | + # now let's move the files out of the way |
595 | + for element in ('setuptools', 'pkg_resources.py', 'site.py'): |
596 | + element = os.path.join(placeholder, element) |
597 | + if os.path.exists(element): |
598 | + _rename_path(element) |
599 | + else: |
600 | + log.warn('Could not find the %s element of the ' |
601 | + 'Setuptools distribution', element) |
602 | + return True |
603 | + |
604 | +_remove_flat_installation = _no_sandbox(_remove_flat_installation) |
605 | + |
606 | + |
607 | +def _after_install(dist): |
608 | + log.warn('After install bootstrap.') |
609 | + placeholder = dist.get_command_obj('install').install_purelib |
610 | + _create_fake_setuptools_pkg_info(placeholder) |
611 | + |
612 | + |
613 | +def _create_fake_setuptools_pkg_info(placeholder): |
614 | + if not placeholder or not os.path.exists(placeholder): |
615 | + log.warn('Could not find the install location') |
616 | + return |
617 | + pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1]) |
618 | + setuptools_file = 'setuptools-%s-py%s.egg-info' % \ |
619 | + (SETUPTOOLS_FAKED_VERSION, pyver) |
620 | + pkg_info = os.path.join(placeholder, setuptools_file) |
621 | + if os.path.exists(pkg_info): |
622 | + log.warn('%s already exists', pkg_info) |
623 | + return |
624 | + |
625 | + log.warn('Creating %s', pkg_info) |
626 | + try: |
627 | + f = open(pkg_info, 'w') |
628 | + except EnvironmentError: |
629 | + log.warn("Don't have permissions to write %s, skipping", pkg_info) |
630 | + return |
631 | + try: |
632 | + f.write(SETUPTOOLS_PKG_INFO) |
633 | + finally: |
634 | + f.close() |
635 | + |
636 | + pth_file = os.path.join(placeholder, 'setuptools.pth') |
637 | + log.warn('Creating %s', pth_file) |
638 | + f = open(pth_file, 'w') |
639 | + try: |
640 | + f.write(os.path.join(os.curdir, setuptools_file)) |
641 | + finally: |
642 | + f.close() |
643 | + |
644 | +_create_fake_setuptools_pkg_info = _no_sandbox( |
645 | + _create_fake_setuptools_pkg_info |
646 | +) |
647 | + |
648 | + |
649 | +def _patch_egg_dir(path): |
650 | + # let's check if it's already patched |
651 | + pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') |
652 | + if os.path.exists(pkg_info): |
653 | + if _same_content(pkg_info, SETUPTOOLS_PKG_INFO): |
654 | + log.warn('%s already patched.', pkg_info) |
655 | + return False |
656 | + _rename_path(path) |
657 | + os.mkdir(path) |
658 | + os.mkdir(os.path.join(path, 'EGG-INFO')) |
659 | + pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') |
660 | + f = open(pkg_info, 'w') |
661 | + try: |
662 | + f.write(SETUPTOOLS_PKG_INFO) |
663 | + finally: |
664 | + f.close() |
665 | + return True |
666 | + |
667 | +_patch_egg_dir = _no_sandbox(_patch_egg_dir) |
668 | + |
669 | + |
670 | +def _before_install(): |
671 | + log.warn('Before install bootstrap.') |
672 | + _fake_setuptools() |
673 | + |
674 | + |
675 | +def _under_prefix(location): |
676 | + if 'install' not in sys.argv: |
677 | + return True |
678 | + args = sys.argv[sys.argv.index('install') + 1:] |
679 | + for index, arg in enumerate(args): |
680 | + for option in ('--root', '--prefix'): |
681 | + if arg.startswith('%s=' % option): |
682 | + top_dir = arg.split('root=')[-1] |
683 | + return location.startswith(top_dir) |
684 | + elif arg == option: |
685 | + if len(args) > index: |
686 | + top_dir = args[index + 1] |
687 | + return location.startswith(top_dir) |
688 | + if arg == '--user' and USER_SITE is not None: |
689 | + return location.startswith(USER_SITE) |
690 | + return True |
691 | + |
692 | + |
693 | +def _fake_setuptools(): |
694 | + log.warn('Scanning installed packages') |
695 | + try: |
696 | + import pkg_resources |
697 | + except ImportError: |
698 | + # we're cool |
699 | + log.warn('Setuptools or Distribute does not seem to be installed.') |
700 | + return |
701 | + ws = pkg_resources.working_set |
702 | + try: |
703 | + setuptools_dist = ws.find( |
704 | + pkg_resources.Requirement.parse('setuptools', replacement=False) |
705 | + ) |
706 | + except TypeError: |
707 | + # old distribute API |
708 | + setuptools_dist = ws.find( |
709 | + pkg_resources.Requirement.parse('setuptools') |
710 | + ) |
711 | + |
712 | + if setuptools_dist is None: |
713 | + log.warn('No setuptools distribution found') |
714 | + return |
715 | + # detecting if it was already faked |
716 | + setuptools_location = setuptools_dist.location |
717 | + log.warn('Setuptools installation detected at %s', setuptools_location) |
718 | + |
719 | + # if --root or --preix was provided, and if |
720 | + # setuptools is not located in them, we don't patch it |
721 | + if not _under_prefix(setuptools_location): |
722 | + log.warn('Not patching, --root or --prefix is installing Distribute' |
723 | + ' in another location') |
724 | + return |
725 | + |
726 | + # let's see if its an egg |
727 | + if not setuptools_location.endswith('.egg'): |
728 | + log.warn('Non-egg installation') |
729 | + res = _remove_flat_installation(setuptools_location) |
730 | + if not res: |
731 | + return |
732 | + else: |
733 | + log.warn('Egg installation') |
734 | + pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO') |
735 | + if (os.path.exists(pkg_info) and |
736 | + _same_content(pkg_info, SETUPTOOLS_PKG_INFO)): |
737 | + log.warn('Already patched.') |
738 | + return |
739 | + log.warn('Patching...') |
740 | + # let's create a fake egg replacing setuptools one |
741 | + res = _patch_egg_dir(setuptools_location) |
742 | + if not res: |
743 | + return |
744 | + log.warn('Patching complete.') |
745 | + _relaunch() |
746 | + |
747 | + |
748 | +def _relaunch(): |
749 | + log.warn('Relaunching...') |
750 | + # we have to relaunch the process |
751 | + # pip marker to avoid a relaunch bug |
752 | + _cmd1 = ['-c', 'install', '--single-version-externally-managed'] |
753 | + _cmd2 = ['-c', 'install', '--record'] |
754 | + if sys.argv[:3] == _cmd1 or sys.argv[:3] == _cmd2: |
755 | + sys.argv[0] = 'setup.py' |
756 | + args = [sys.executable] + sys.argv |
757 | + sys.exit(subprocess.call(args)) |
758 | + |
759 | + |
760 | +def _extractall(self, path=".", members=None): |
761 | + """Extract all members from the archive to the current working |
762 | + directory and set owner, modification time and permissions on |
763 | + directories afterwards. `path' specifies a different directory |
764 | + to extract to. `members' is optional and must be a subset of the |
765 | + list returned by getmembers(). |
766 | + """ |
767 | + import copy |
768 | + import operator |
769 | + from tarfile import ExtractError |
770 | + directories = [] |
771 | + |
772 | + if members is None: |
773 | + members = self |
774 | + |
775 | + for tarinfo in members: |
776 | + if tarinfo.isdir(): |
777 | + # Extract directories with a safe mode. |
778 | + directories.append(tarinfo) |
779 | + tarinfo = copy.copy(tarinfo) |
780 | + tarinfo.mode = 448 # decimal for oct 0700 |
781 | + self.extract(tarinfo, path) |
782 | + |
783 | + # Reverse sort directories. |
784 | + if sys.version_info < (2, 4): |
785 | + def sorter(dir1, dir2): |
786 | + return cmp(dir1.name, dir2.name) |
787 | + directories.sort(sorter) |
788 | + directories.reverse() |
789 | + else: |
790 | + directories.sort(key=operator.attrgetter('name'), reverse=True) |
791 | + |
792 | + # Set correct owner, mtime and filemode on directories. |
793 | + for tarinfo in directories: |
794 | + dirpath = os.path.join(path, tarinfo.name) |
795 | + try: |
796 | + self.chown(tarinfo, dirpath) |
797 | + self.utime(tarinfo, dirpath) |
798 | + self.chmod(tarinfo, dirpath) |
799 | + except ExtractError: |
800 | + e = sys.exc_info()[1] |
801 | + if self.errorlevel > 1: |
802 | + raise |
803 | + else: |
804 | + self._dbg(1, "tarfile: %s" % e) |
805 | + |
806 | + |
807 | +def _build_install_args(options): |
808 | + """ |
809 | + Build the arguments to 'python setup.py install' on the distribute package |
810 | + """ |
811 | + install_args = [] |
812 | + if options.user_install: |
813 | + if sys.version_info < (2, 6): |
814 | + log.warn("--user requires Python 2.6 or later") |
815 | + raise SystemExit(1) |
816 | + install_args.append('--user') |
817 | + return install_args |
818 | + |
819 | +def _parse_args(): |
820 | + """ |
821 | + Parse the command line for options |
822 | + """ |
823 | + parser = optparse.OptionParser() |
824 | + parser.add_option( |
825 | + '--user', dest='user_install', action='store_true', default=False, |
826 | + help='install in user site package (requires Python 2.6 or later)') |
827 | + parser.add_option( |
828 | + '--download-base', dest='download_base', metavar="URL", |
829 | + default=DEFAULT_URL, |
830 | + help='alternative URL from where to download the distribute package') |
831 | + options, args = parser.parse_args() |
832 | + # positional arguments are ignored |
833 | + return options |
834 | + |
835 | +def main(version=DEFAULT_VERSION): |
836 | + """Install or upgrade setuptools and EasyInstall""" |
837 | + options = _parse_args() |
838 | + tarball = download_setuptools(download_base=options.download_base) |
839 | + return _install(tarball, _build_install_args(options)) |
840 | + |
841 | +if __name__ == '__main__': |
842 | + sys.exit(main()) |
843 | |
844 | === removed file 'ez_setup.py' |
845 | --- ez_setup.py 2009-03-16 15:17:16 +0000 |
846 | +++ ez_setup.py 1970-01-01 00:00:00 +0000 |
847 | @@ -1,241 +0,0 @@ |
848 | -#!python |
849 | -"""Bootstrap setuptools installation |
850 | - |
851 | -If you want to use setuptools in your package's setup.py, just include this |
852 | -file in the same directory with it, and add this to the top of your setup.py:: |
853 | - |
854 | - from ez_setup import use_setuptools |
855 | - use_setuptools() |
856 | - |
857 | -If you want to require a specific version of setuptools, set a download |
858 | -mirror, or use an alternate download directory, you can do so by supplying |
859 | -the appropriate options to ``use_setuptools()``. |
860 | - |
861 | -This file can also be run as a script to install or upgrade setuptools. |
862 | -""" |
863 | -import sys |
864 | -DEFAULT_VERSION = "0.6c8" |
865 | -DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] |
866 | - |
867 | -md5_data = { |
868 | - 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', |
869 | - 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', |
870 | - 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', |
871 | - 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', |
872 | - 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', |
873 | - 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', |
874 | - 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', |
875 | - 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', |
876 | - 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', |
877 | - 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', |
878 | - 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', |
879 | - 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', |
880 | - 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', |
881 | - 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', |
882 | - 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', |
883 | - 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', |
884 | - 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', |
885 | - 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', |
886 | - 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', |
887 | - 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', |
888 | - 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', |
889 | - 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', |
890 | - 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', |
891 | - 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', |
892 | - 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', |
893 | - 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', |
894 | - 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', |
895 | - 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', |
896 | - 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', |
897 | - 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', |
898 | -} |
899 | - |
900 | -import sys, os |
901 | - |
902 | -def _validate_md5(egg_name, data): |
903 | - if egg_name in md5_data: |
904 | - from md5 import md5 |
905 | - digest = md5(data).hexdigest() |
906 | - if digest != md5_data[egg_name]: |
907 | - print >>sys.stderr, ( |
908 | - "md5 validation of %s failed! (Possible download problem?)" |
909 | - % egg_name |
910 | - ) |
911 | - sys.exit(2) |
912 | - return data |
913 | - |
914 | - |
915 | -def use_setuptools( |
916 | - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, |
917 | - download_delay=15, min_version=None |
918 | -): |
919 | - """Automatically find/download setuptools and make it available on sys.path |
920 | - |
921 | - `version` should be a valid setuptools version number that is available |
922 | - as an egg for download under the `download_base` URL (which should end with |
923 | - a '/'). `to_dir` is the directory where setuptools will be downloaded, if |
924 | - it is not already available. If `download_delay` is specified, it should |
925 | - be the number of seconds that will be paused before initiating a download, |
926 | - should one be required. If an older version of setuptools is installed, |
927 | - this routine will print a message to ``sys.stderr`` and raise SystemExit in |
928 | - an attempt to abort the calling script. |
929 | - """ |
930 | - # Work around a hack in the ez_setup.py file from simplejson==1.7.3. |
931 | - if min_version: |
932 | - version = min_version |
933 | - |
934 | - was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules |
935 | - def do_download(): |
936 | - egg = download_setuptools(version, download_base, to_dir, download_delay) |
937 | - sys.path.insert(0, egg) |
938 | - import setuptools; setuptools.bootstrap_install_from = egg |
939 | - try: |
940 | - import pkg_resources |
941 | - except ImportError: |
942 | - return do_download() |
943 | - try: |
944 | - pkg_resources.require("setuptools>="+version); return |
945 | - except pkg_resources.VersionConflict, e: |
946 | - if was_imported: |
947 | - print >>sys.stderr, ( |
948 | - "The required version of setuptools (>=%s) is not available, and\n" |
949 | - "can't be installed while this script is running. Please install\n" |
950 | - " a more recent version first, using 'easy_install -U setuptools'." |
951 | - "\n\n(Currently using %r)" |
952 | - ) % (version, e.args[0]) |
953 | - sys.exit(2) |
954 | - else: |
955 | - del pkg_resources, sys.modules['pkg_resources'] # reload ok |
956 | - return do_download() |
957 | - except pkg_resources.DistributionNotFound: |
958 | - return do_download() |
959 | - |
960 | -def download_setuptools( |
961 | - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, |
962 | - delay = 15 |
963 | -): |
964 | - """Download setuptools from a specified location and return its filename |
965 | - |
966 | - `version` should be a valid setuptools version number that is available |
967 | - as an egg for download under the `download_base` URL (which should end |
968 | - with a '/'). `to_dir` is the directory where the egg will be downloaded. |
969 | - `delay` is the number of seconds to pause before an actual download attempt. |
970 | - """ |
971 | - import urllib2, shutil |
972 | - egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) |
973 | - url = download_base + egg_name |
974 | - saveto = os.path.join(to_dir, egg_name) |
975 | - src = dst = None |
976 | - if not os.path.exists(saveto): # Avoid repeated downloads |
977 | - try: |
978 | - from distutils import log |
979 | - if delay: |
980 | - log.warn(""" |
981 | ---------------------------------------------------------------------------- |
982 | -This script requires setuptools version %s to run (even to display |
983 | -help). I will attempt to download it for you (from |
984 | -%s), but |
985 | -you may need to enable firewall access for this script first. |
986 | -I will start the download in %d seconds. |
987 | - |
988 | -(Note: if this machine does not have network access, please obtain the file |
989 | - |
990 | - %s |
991 | - |
992 | -and place it in this directory before rerunning this script.) |
993 | ----------------------------------------------------------------------------""", |
994 | - version, download_base, delay, url |
995 | - ); from time import sleep; sleep(delay) |
996 | - log.warn("Downloading %s", url) |
997 | - src = urllib2.urlopen(url) |
998 | - # Read/write all in one block, so we don't create a corrupt file |
999 | - # if the download is interrupted. |
1000 | - data = _validate_md5(egg_name, src.read()) |
1001 | - dst = open(saveto,"wb"); dst.write(data) |
1002 | - finally: |
1003 | - if src: src.close() |
1004 | - if dst: dst.close() |
1005 | - return os.path.realpath(saveto) |
1006 | - |
1007 | -def main(argv, version=DEFAULT_VERSION): |
1008 | - """Install or upgrade setuptools and EasyInstall""" |
1009 | - try: |
1010 | - import setuptools |
1011 | - except ImportError: |
1012 | - egg = None |
1013 | - try: |
1014 | - egg = download_setuptools(version, delay=0) |
1015 | - sys.path.insert(0,egg) |
1016 | - from setuptools.command.easy_install import main |
1017 | - return main(list(argv)+[egg]) # we're done here |
1018 | - finally: |
1019 | - if egg and os.path.exists(egg): |
1020 | - os.unlink(egg) |
1021 | - else: |
1022 | - if setuptools.__version__ == '0.0.1': |
1023 | - print >>sys.stderr, ( |
1024 | - "You have an obsolete version of setuptools installed. Please\n" |
1025 | - "remove it from your system entirely before rerunning this script." |
1026 | - ) |
1027 | - sys.exit(2) |
1028 | - |
1029 | - req = "setuptools>="+version |
1030 | - import pkg_resources |
1031 | - try: |
1032 | - pkg_resources.require(req) |
1033 | - except pkg_resources.VersionConflict: |
1034 | - try: |
1035 | - from setuptools.command.easy_install import main |
1036 | - except ImportError: |
1037 | - from easy_install import main |
1038 | - main(list(argv)+[download_setuptools(delay=0)]) |
1039 | - sys.exit(0) # try to force an exit |
1040 | - else: |
1041 | - if argv: |
1042 | - from setuptools.command.easy_install import main |
1043 | - main(argv) |
1044 | - else: |
1045 | - print "Setuptools version",version,"or greater has been installed." |
1046 | - print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' |
1047 | - |
1048 | -def update_md5(filenames): |
1049 | - """Update our built-in md5 registry""" |
1050 | - |
1051 | - import re |
1052 | - from md5 import md5 |
1053 | - |
1054 | - for name in filenames: |
1055 | - base = os.path.basename(name) |
1056 | - f = open(name,'rb') |
1057 | - md5_data[base] = md5(f.read()).hexdigest() |
1058 | - f.close() |
1059 | - |
1060 | - data = [" %r: %r,\n" % it for it in md5_data.items()] |
1061 | - data.sort() |
1062 | - repl = "".join(data) |
1063 | - |
1064 | - import inspect |
1065 | - srcfile = inspect.getsourcefile(sys.modules[__name__]) |
1066 | - f = open(srcfile, 'rb'); src = f.read(); f.close() |
1067 | - |
1068 | - match = re.search("\nmd5_data = {\n([^}]+)}", src) |
1069 | - if not match: |
1070 | - print >>sys.stderr, "Internal error!" |
1071 | - sys.exit(2) |
1072 | - |
1073 | - src = src[:match.start(1)] + repl + src[match.end(1):] |
1074 | - f = open(srcfile,'w') |
1075 | - f.write(src) |
1076 | - f.close() |
1077 | - |
1078 | - |
1079 | -if __name__=='__main__': |
1080 | - if len(sys.argv)>2 and sys.argv[1]=='--md5update': |
1081 | - update_md5(sys.argv[2:]) |
1082 | - else: |
1083 | - main(sys.argv[1:]) |
1084 | - |
1085 | - |
1086 | - |
1087 | - |
1088 | - |
1089 | |
1090 | === renamed directory 'src/lazr' => 'lazr' |
1091 | === modified file 'lazr/__init__.py' |
1092 | --- src/lazr/__init__.py 2009-06-09 03:00:20 +0000 |
1093 | +++ lazr/__init__.py 2013-01-07 01:00:29 +0000 |
1094 | @@ -1,4 +1,4 @@ |
1095 | -# Copyright 2009 Canonical Ltd. All rights reserved. |
1096 | +# Copyright 2009-2013 Canonical Ltd. All rights reserved. |
1097 | # |
1098 | # This file is part of lazr.smtptest. |
1099 | # |
1100 | @@ -14,10 +14,14 @@ |
1101 | # You should have received a copy of the GNU Lesser General Public License |
1102 | # along with lazr.smtptest. If not, see <http://www.gnu.org/licenses/>. |
1103 | |
1104 | -# this is a namespace package |
1105 | -try: |
1106 | - import pkg_resources |
1107 | - pkg_resources.declare_namespace(__name__) |
1108 | -except ImportError: |
1109 | - import pkgutil |
1110 | - __path__ = pkgutil.extend_path(__path__, __name__) |
1111 | +# This is a namespace package, however under >= Python 3.3, let it be a true |
1112 | +# namespace package (i.e. this cruft isn't necessary). |
1113 | +import sys |
1114 | + |
1115 | +if sys.hexversion < 0x30300f0: |
1116 | + try: |
1117 | + import pkg_resources |
1118 | + pkg_resources.declare_namespace(__name__) |
1119 | + except ImportError: |
1120 | + import pkgutil |
1121 | + __path__ = pkgutil.extend_path(__path__, __name__) |
1122 | |
1123 | === renamed file 'src/lazr/smtptest/NEWS.txt' => 'lazr/smtptest/NEWS.rst' |
1124 | --- src/lazr/smtptest/NEWS.txt 2011-07-06 21:06:55 +0000 |
1125 | +++ lazr/smtptest/NEWS.rst 2013-01-07 01:00:29 +0000 |
1126 | @@ -2,6 +2,16 @@ |
1127 | NEWS for lazr.smtptest |
1128 | ====================== |
1129 | |
1130 | +2.0 (2013-01-05) |
1131 | +================ |
1132 | + |
1133 | +- Ported to Python 3. Now support Python 2.6, 2.7, 3.2, and 3.3. |
1134 | + |
1135 | +- Removed the dependency on zc.buildout. |
1136 | + |
1137 | +- Use nose for testing. |
1138 | + |
1139 | + |
1140 | 1.3 (2011-06-07) |
1141 | ================ |
1142 | |
1143 | |
1144 | === renamed file 'src/lazr/smtptest/README.txt' => 'lazr/smtptest/README.rst' |
1145 | --- src/lazr/smtptest/README.txt 2009-06-23 00:29:31 +0000 |
1146 | +++ lazr/smtptest/README.rst 2013-01-07 01:00:29 +0000 |
1147 | @@ -36,7 +36,7 @@ |
1148 | The lazr.smtptest package is importable, and has a version number. |
1149 | |
1150 | >>> import lazr.smtptest |
1151 | - >>> print 'VERSION:', lazr.smtptest.__version__ |
1152 | + >>> print('VERSION:', lazr.smtptest.__version__) |
1153 | VERSION: ... |
1154 | |
1155 | More information |
1156 | |
1157 | === added file 'lazr/smtptest/README_fixture.py' |
1158 | --- lazr/smtptest/README_fixture.py 1970-01-01 00:00:00 +0000 |
1159 | +++ lazr/smtptest/README_fixture.py 2013-01-07 01:00:29 +0000 |
1160 | @@ -0,0 +1,27 @@ |
1161 | +# Copyright 2009-2013 Canonical Ltd. All rights reserved. |
1162 | +# |
1163 | +# This file is part of lazr.smtptest |
1164 | +# |
1165 | +# lazr.smtptest is free software: you can redistribute it and/or modify it |
1166 | +# under the terms of the GNU Lesser General Public License as published by |
1167 | +# the Free Software Foundation, version 3 of the License. |
1168 | +# |
1169 | +# lazr.smtptest is distributed in the hope that it will be useful, but WITHOUT |
1170 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
1171 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
1172 | +# License for more details. |
1173 | +# |
1174 | +# You should have received a copy of the GNU Lesser General Public License |
1175 | +# along with lazr.smtptest. If not, see <http://www.gnu.org/licenses/>. |
1176 | + |
1177 | +"""Doctest fixtures for running under nose.""" |
1178 | + |
1179 | +from __future__ import absolute_import, print_function, unicode_literals |
1180 | + |
1181 | +__metaclass__ = type |
1182 | +__all__ = [ |
1183 | + 'globs', |
1184 | + ] |
1185 | + |
1186 | + |
1187 | +from lazr.smtptest.docs.fixture import globs |
1188 | |
1189 | === modified file 'lazr/smtptest/__init__.py' |
1190 | --- src/lazr/smtptest/__init__.py 2009-09-04 19:06:38 +0000 |
1191 | +++ lazr/smtptest/__init__.py 2013-01-07 01:00:29 +0000 |
1192 | @@ -1,4 +1,4 @@ |
1193 | -# Copyright 2009 Canonical Ltd. All rights reserved. |
1194 | +# Copyright 2009-2013 Canonical Ltd. All rights reserved. |
1195 | # |
1196 | # This file is part of lazr.smtptest |
1197 | # |
1198 | |
1199 | === modified file 'lazr/smtptest/controller.py' |
1200 | --- src/lazr/smtptest/controller.py 2009-06-30 00:40:38 +0000 |
1201 | +++ lazr/smtptest/controller.py 2013-01-07 01:00:29 +0000 |
1202 | @@ -1,4 +1,4 @@ |
1203 | -# Copyright 2009 Canonical Ltd. All rights reserved. |
1204 | +# Copyright 2009-2013 Canonical Ltd. All rights reserved. |
1205 | # |
1206 | # This file is part of lazr.smtptest |
1207 | # |
1208 | @@ -16,6 +16,9 @@ |
1209 | |
1210 | """The SMTP test controller.""" |
1211 | |
1212 | +from __future__ import absolute_import, print_function, unicode_literals |
1213 | + |
1214 | + |
1215 | __metaclass__ = type |
1216 | __all__ = [ |
1217 | 'Controller', |
1218 | @@ -27,12 +30,15 @@ |
1219 | import smtplib |
1220 | import threading |
1221 | |
1222 | -from Queue import Empty, Queue |
1223 | +try: |
1224 | + from queue import Empty, Queue |
1225 | +except ImportError: |
1226 | + # Python 2 |
1227 | + from Queue import Empty, Queue |
1228 | |
1229 | from lazr.smtptest.server import QueueServer |
1230 | |
1231 | |
1232 | -# pylint: disable-msg=C0103 |
1233 | log = logging.getLogger('lazr.smtptest') |
1234 | |
1235 | |
1236 | |
1237 | === added file 'lazr/smtptest/docs/fixture.py' |
1238 | --- lazr/smtptest/docs/fixture.py 1970-01-01 00:00:00 +0000 |
1239 | +++ lazr/smtptest/docs/fixture.py 2013-01-07 01:00:29 +0000 |
1240 | @@ -0,0 +1,34 @@ |
1241 | +# Copyright 2009-2013 Canonical Ltd. All rights reserved. |
1242 | +# |
1243 | +# This file is part of lazr.smtptest |
1244 | +# |
1245 | +# lazr.smtptest is free software: you can redistribute it and/or modify it |
1246 | +# under the terms of the GNU Lesser General Public License as published by |
1247 | +# the Free Software Foundation, version 3 of the License. |
1248 | +# |
1249 | +# lazr.smtptest is distributed in the hope that it will be useful, but WITHOUT |
1250 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
1251 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
1252 | +# License for more details. |
1253 | +# |
1254 | +# You should have received a copy of the GNU Lesser General Public License |
1255 | +# along with lazr.smtptest. If not, see <http://www.gnu.org/licenses/>. |
1256 | + |
1257 | +"""Doctest fixtures for running under nose.""" |
1258 | + |
1259 | +from __future__ import absolute_import, print_function, unicode_literals |
1260 | + |
1261 | +__metaclass__ = type |
1262 | +__all__ = [ |
1263 | + 'globs', |
1264 | + ] |
1265 | + |
1266 | + |
1267 | +def globs(globs): |
1268 | + """Set up globals for doctests.""" |
1269 | + # Enable future statements to make Python 2 act more like Python 3. |
1270 | + globs['absolute_import'] = absolute_import |
1271 | + globs['print_function'] = print_function |
1272 | + globs['unicode_literals'] = unicode_literals |
1273 | + # Provide a convenient way to clean things up at the end of the test. |
1274 | + return globs |
1275 | |
1276 | === renamed file 'src/lazr/smtptest/docs/queue.txt' => 'lazr/smtptest/docs/queue.rst' |
1277 | --- src/lazr/smtptest/docs/queue.txt 2009-06-30 00:40:38 +0000 |
1278 | +++ lazr/smtptest/docs/queue.rst 2013-01-07 01:00:29 +0000 |
1279 | @@ -13,7 +13,11 @@ |
1280 | |
1281 | First, you need a queue. |
1282 | |
1283 | - >>> from Queue import Queue |
1284 | + >>> try: |
1285 | + ... from queue import Empty, Queue |
1286 | + ... except ImportError: |
1287 | + ... # Python 2 |
1288 | + ... from Queue import Empty, Queue |
1289 | >>> queue = Queue() |
1290 | |
1291 | Then you need a server. |
1292 | @@ -34,8 +38,9 @@ |
1293 | |
1294 | >>> import smtplib |
1295 | >>> smtpd = smtplib.SMTP() |
1296 | - >>> smtpd.connect('localhost', 9025) |
1297 | - (220, '... Python SMTP proxy version ...') |
1298 | + >>> code, helo = smtpd.connect('localhost', 9025) |
1299 | + >>> print(code, str(helo)) |
1300 | + 220 ... Python SMTP proxy version ... |
1301 | |
1302 | >>> smtpd.sendmail('iperson@example.com', ['jperson@example.com'], """\ |
1303 | ... From: Irie Person <iperson@example.com> |
1304 | @@ -69,13 +74,12 @@ |
1305 | |
1306 | All of these messages are available in the queue. |
1307 | |
1308 | - >>> from Queue import Empty |
1309 | >>> while True: |
1310 | ... try: |
1311 | ... message = queue.get_nowait() |
1312 | ... except Empty: |
1313 | ... break |
1314 | - ... print message['message-id'] |
1315 | + ... print(message['message-id']) |
1316 | <elephant> |
1317 | <falcon> |
1318 | <goat> |
1319 | @@ -95,8 +99,9 @@ |
1320 | >>> controller.start() |
1321 | |
1322 | >>> smtpd = smtplib.SMTP() |
1323 | - >>> smtpd.connect('localhost', 9025) |
1324 | - (220, '... Python SMTP proxy version ...') |
1325 | + >>> code, helo = smtpd.connect('localhost', 9025) |
1326 | + >>> print(code, str(helo)) |
1327 | + 220 ... Python SMTP proxy version ... |
1328 | |
1329 | We now have an SMTP server that we can send some messages to. |
1330 | |
1331 | @@ -133,7 +138,7 @@ |
1332 | And we can dump out all the messages from the controller. |
1333 | |
1334 | >>> for message in controller: |
1335 | - ... print message['message-id'] |
1336 | + ... print(message['message-id']) |
1337 | <horse> |
1338 | <iguana> |
1339 | <jackel> |
1340 | @@ -151,7 +156,7 @@ |
1341 | {} |
1342 | |
1343 | >>> for message in controller: |
1344 | - ... print message['message-id'] |
1345 | + ... print(message['message-id']) |
1346 | <kangaroo> |
1347 | |
1348 | |
1349 | |
1350 | === added file 'lazr/smtptest/docs/queue_fixture.py' |
1351 | --- lazr/smtptest/docs/queue_fixture.py 1970-01-01 00:00:00 +0000 |
1352 | +++ lazr/smtptest/docs/queue_fixture.py 2013-01-07 01:00:29 +0000 |
1353 | @@ -0,0 +1,27 @@ |
1354 | +# Copyright 2009-2013 Canonical Ltd. All rights reserved. |
1355 | +# |
1356 | +# This file is part of lazr.smtptest |
1357 | +# |
1358 | +# lazr.smtptest is free software: you can redistribute it and/or modify it |
1359 | +# under the terms of the GNU Lesser General Public License as published by |
1360 | +# the Free Software Foundation, version 3 of the License. |
1361 | +# |
1362 | +# lazr.smtptest is distributed in the hope that it will be useful, but WITHOUT |
1363 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
1364 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
1365 | +# License for more details. |
1366 | +# |
1367 | +# You should have received a copy of the GNU Lesser General Public License |
1368 | +# along with lazr.smtptest. If not, see <http://www.gnu.org/licenses/>. |
1369 | + |
1370 | +"""Doctest fixtures for running under nose.""" |
1371 | + |
1372 | +from __future__ import absolute_import, print_function, unicode_literals |
1373 | + |
1374 | +__metaclass__ = type |
1375 | +__all__ = [ |
1376 | + 'globs', |
1377 | + ] |
1378 | + |
1379 | + |
1380 | +from lazr.smtptest.docs.fixture import globs |
1381 | |
1382 | === renamed file 'src/lazr/smtptest/docs/usage.txt' => 'lazr/smtptest/docs/usage.rst' |
1383 | --- src/lazr/smtptest/docs/usage.txt 2009-06-18 05:12:56 +0000 |
1384 | +++ lazr/smtptest/docs/usage.rst 2013-01-07 01:00:29 +0000 |
1385 | @@ -15,7 +15,11 @@ |
1386 | message. For example, you might want to pass the message between the threads |
1387 | via a Queue. |
1388 | |
1389 | - >>> from Queue import Queue |
1390 | + >>> try: |
1391 | + ... from queue import Queue |
1392 | + ... except ImportError: |
1393 | + ... # Python 2 |
1394 | + ... from Queue import Queue |
1395 | >>> queue = Queue() |
1396 | |
1397 | >>> class MyServer(Server): |
1398 | @@ -32,8 +36,9 @@ |
1399 | |
1400 | >>> from smtplib import SMTP |
1401 | >>> smtpd = SMTP() |
1402 | - >>> smtpd.connect('localhost', 9025) |
1403 | - (220, '... Python SMTP proxy version ...') |
1404 | + >>> code, helo = smtpd.connect('localhost', 9025) |
1405 | + >>> print(code, str(helo)) |
1406 | + 220 ... Python SMTP proxy version ... |
1407 | |
1408 | ...and send it a message. |
1409 | |
1410 | @@ -50,7 +55,7 @@ |
1411 | Now print the message that the server has just received. |
1412 | |
1413 | >>> message = queue.get() |
1414 | - >>> print message.as_string() |
1415 | + >>> print(message.as_string()) |
1416 | From: Abby Person <aperson@example.com> |
1417 | To: Bart Person <bperson@example.com> |
1418 | Subject: A test |
1419 | @@ -71,9 +76,9 @@ |
1420 | >>> import socket |
1421 | >>> try: |
1422 | ... smtpd.connect('localhost', 9025) |
1423 | - ... except socket.error, error: |
1424 | - ... errno, message = error |
1425 | - ... print message |
1426 | + ... except socket.error as error: |
1427 | + ... errno, message = error.args |
1428 | + ... print(message) |
1429 | Connection refused |
1430 | |
1431 | |
1432 | @@ -109,8 +114,9 @@ |
1433 | Now we can send a couple of messages to the server. |
1434 | |
1435 | >>> smtpd = SMTP() |
1436 | - >>> smtpd.connect('localhost', 9025) |
1437 | - (220, '... Python SMTP proxy version ...') |
1438 | + >>> code, helo = smtpd.connect('localhost', 9025) |
1439 | + >>> print(code, str(helo)) |
1440 | + 220 ... Python SMTP proxy version ... |
1441 | |
1442 | >>> smtpd.sendmail('cperson@example.com', ['dperson@example.com'], """\ |
1443 | ... From: Cris Person <cperson@example.com> |
1444 | @@ -146,7 +152,7 @@ |
1445 | |
1446 | >>> for message_id in sorted(message['message-id'] |
1447 | ... for message in mailbox.Maildir(mailbox_dir)): |
1448 | - ... print message_id |
1449 | + ... print(message_id) |
1450 | <badger> |
1451 | <cougar> |
1452 | <dingo> |
1453 | @@ -155,7 +161,7 @@ |
1454 | |
1455 | >>> for message_id in sorted(message['message-id'] |
1456 | ... for message in mailbox.Maildir(mailbox_dir)): |
1457 | - ... print message_id |
1458 | + ... print(message_id) |
1459 | <badger> |
1460 | <cougar> |
1461 | <dingo> |
1462 | |
1463 | === added file 'lazr/smtptest/docs/usage_fixture.py' |
1464 | --- lazr/smtptest/docs/usage_fixture.py 1970-01-01 00:00:00 +0000 |
1465 | +++ lazr/smtptest/docs/usage_fixture.py 2013-01-07 01:00:29 +0000 |
1466 | @@ -0,0 +1,27 @@ |
1467 | +# Copyright 2009-2013 Canonical Ltd. All rights reserved. |
1468 | +# |
1469 | +# This file is part of lazr.smtptest |
1470 | +# |
1471 | +# lazr.smtptest is free software: you can redistribute it and/or modify it |
1472 | +# under the terms of the GNU Lesser General Public License as published by |
1473 | +# the Free Software Foundation, version 3 of the License. |
1474 | +# |
1475 | +# lazr.smtptest is distributed in the hope that it will be useful, but WITHOUT |
1476 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
1477 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
1478 | +# License for more details. |
1479 | +# |
1480 | +# You should have received a copy of the GNU Lesser General Public License |
1481 | +# along with lazr.smtptest. If not, see <http://www.gnu.org/licenses/>. |
1482 | + |
1483 | +"""Doctest fixtures for running under nose.""" |
1484 | + |
1485 | +from __future__ import absolute_import, print_function, unicode_literals |
1486 | + |
1487 | +__metaclass__ = type |
1488 | +__all__ = [ |
1489 | + 'globs', |
1490 | + ] |
1491 | + |
1492 | + |
1493 | +from lazr.smtptest.docs.fixture import globs |
1494 | |
1495 | === modified file 'lazr/smtptest/server.py' |
1496 | --- src/lazr/smtptest/server.py 2011-07-06 21:06:55 +0000 |
1497 | +++ lazr/smtptest/server.py 2013-01-07 01:00:29 +0000 |
1498 | @@ -1,4 +1,4 @@ |
1499 | -# Copyright 2009 Canonical Ltd. All rights reserved. |
1500 | +# Copyright 2009-2013 Canonical Ltd. All rights reserved. |
1501 | # |
1502 | # This file is part of lazr.smtptest |
1503 | # |
1504 | @@ -16,6 +16,9 @@ |
1505 | |
1506 | """The SMTP test server.""" |
1507 | |
1508 | +from __future__ import absolute_import, print_function, unicode_literals |
1509 | + |
1510 | + |
1511 | __metaclass__ = type |
1512 | __all__ = [ |
1513 | 'QueueServer', |
1514 | @@ -28,12 +31,16 @@ |
1515 | import logging |
1516 | import asyncore |
1517 | |
1518 | -from Queue import Empty |
1519 | +try: |
1520 | + from queue import Empty |
1521 | +except ImportError: |
1522 | + # Python 2 |
1523 | + from Queue import Empty |
1524 | + |
1525 | from email import message_from_string |
1526 | |
1527 | |
1528 | COMMASPACE = ', ' |
1529 | -# pylint: disable-msg=C0103 |
1530 | log = logging.getLogger('lazr.smtptest') |
1531 | |
1532 | |
1533 | @@ -44,7 +51,6 @@ |
1534 | self._server = server |
1535 | smtpd.SMTPChannel.__init__(self, server, connection, address) |
1536 | |
1537 | - # pylint: disable-msg=W0613 |
1538 | def smtp_EXIT(self, argument): |
1539 | """EXIT - a new SMTP command to cleanly stop the server.""" |
1540 | self.push('250 Ok') |
1541 | @@ -61,7 +67,6 @@ |
1542 | # asynchat/asyncore doesn't do it. |
1543 | try: |
1544 | return smtpd.SMTPChannel.send(self, data) |
1545 | - # pylint: disable-msg=W0704 |
1546 | except socket.error: |
1547 | # Nothing here can affect the outcome. |
1548 | pass |
1549 | @@ -123,7 +128,6 @@ |
1550 | log.info('[SMTPServer] processed message: %s', |
1551 | message.get('message-id', 'n/a')) |
1552 | |
1553 | - # pylint: disable-msg=R0201 |
1554 | def start(self): |
1555 | """Start the asyncore loop.""" |
1556 | log.info('[SMTPServer] starting asyncore loop') |
1557 | @@ -134,7 +138,6 @@ |
1558 | asyncore.close_all(map=self.socket_map) |
1559 | self.close() |
1560 | |
1561 | - # pylint: disable-msg=R0201 |
1562 | def reset(self): |
1563 | """Do whatever you need to do on a reset.""" |
1564 | log.info('[SMTPServer] reset') |
1565 | |
1566 | === modified file 'lazr/smtptest/tests/__init__.py' |
1567 | --- src/lazr/smtptest/tests/__init__.py 2009-06-09 03:00:20 +0000 |
1568 | +++ lazr/smtptest/tests/__init__.py 2013-01-07 01:00:29 +0000 |
1569 | @@ -1,16 +0,0 @@ |
1570 | -# Copyright 2009 Canonical Ltd. All rights reserved. |
1571 | -# |
1572 | -# This file is part of lazr.smtptest |
1573 | -# |
1574 | -# lazr.smtptest is free software: you can redistribute it and/or modify it |
1575 | -# under the terms of the GNU Lesser General Public License as published by |
1576 | -# the Free Software Foundation, version 3 of the License. |
1577 | -# |
1578 | -# lazr.smtptest is distributed in the hope that it will be useful, but WITHOUT |
1579 | -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
1580 | -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
1581 | -# License for more details. |
1582 | -# |
1583 | -# You should have received a copy of the GNU Lesser General Public License |
1584 | -# along with lazr.smtptest. If not, see <http://www.gnu.org/licenses/>. |
1585 | -"The lazr.smtptest tests." |
1586 | |
1587 | === modified file 'lazr/smtptest/version.txt' |
1588 | --- src/lazr/smtptest/version.txt 2011-07-06 21:06:55 +0000 |
1589 | +++ lazr/smtptest/version.txt 2013-01-07 01:00:29 +0000 |
1590 | @@ -1,1 +1,1 @@ |
1591 | -1.3 |
1592 | +2.0 |
1593 | |
1594 | === removed file 'pylint.rc' |
1595 | --- pylint.rc 2009-06-17 02:41:00 +0000 |
1596 | +++ pylint.rc 1970-01-01 00:00:00 +0000 |
1597 | @@ -1,310 +0,0 @@ |
1598 | -# lint Python modules using external checkers. |
1599 | -# |
1600 | -# This is the main checker controlling the other ones and the reports |
1601 | -# generation. It is itself both a raw checker and an astng checker in order |
1602 | -# to: |
1603 | -# * handle message activation / deactivation at the module level |
1604 | -# * handle some basic but necessary stats'data (number of classes, methods...) |
1605 | -# |
1606 | -[MASTER] |
1607 | - |
1608 | -# Specify a configuration file. |
1609 | -#rcfile= |
1610 | - |
1611 | -# Python code to execute, usually for sys.path manipulation such as |
1612 | -# pygtk.require(). |
1613 | -#init-hook= |
1614 | - |
1615 | -# Profiled execution. |
1616 | -profile=no |
1617 | - |
1618 | -# Add <file or directory> to the black list. It should be a base name, not a |
1619 | -# path. You may set this option multiple times. |
1620 | -ignore=CVS |
1621 | - |
1622 | -# Pickle collected data for later comparisons. |
1623 | -persistent=no |
1624 | - |
1625 | -# Set the cache size for astng objects. |
1626 | -cache-size=500 |
1627 | - |
1628 | -# List of plugins (as comma separated values of python modules names) to load, |
1629 | -# usually to register additional checkers. |
1630 | -load-plugins= |
1631 | - |
1632 | - |
1633 | -[MESSAGES CONTROL] |
1634 | - |
1635 | -# Enable only checker(s) with the given id(s). This option conflicts with the |
1636 | -# disable-checker option |
1637 | -#enable-checker= |
1638 | - |
1639 | -# Enable all checker(s) except those with the given id(s). This option |
1640 | -# conflicts with the enable-checker option |
1641 | -#disable-checker= |
1642 | - |
1643 | -# Enable all messages in the listed categories. |
1644 | -#enable-msg-cat= |
1645 | - |
1646 | -# Disable all messages in the listed categories. |
1647 | -#disable-msg-cat= |
1648 | - |
1649 | -# Enable the message(s) with the given id(s). |
1650 | -#enable-msg= |
1651 | - |
1652 | -# Disable the message(s) with the given id(s). |
1653 | -# I0011: *Locally disabling %s* |
1654 | -disable-msg=I0011 |
1655 | - |
1656 | - |
1657 | -[REPORTS] |
1658 | - |
1659 | -# Set the output format. Available formats are text, parseable, colorized, msvs |
1660 | -# (visual studio) and html |
1661 | -output-format=parseable |
1662 | - |
1663 | -# Include message's id in output |
1664 | -include-ids=yes |
1665 | - |
1666 | -# Put messages in a separate file for each module / package specified on the |
1667 | -# command line instead of printing them on stdout. Reports (if any) will be |
1668 | -# written in a file name "pylint_global.[txt|html]". |
1669 | -files-output=no |
1670 | - |
1671 | -# Tells wether to display a full report or only the messages |
1672 | -reports=no |
1673 | - |
1674 | -# Python expression which should return a note less than 10 (10 is the highest |
1675 | -# note). You have access to the variables errors warning, statement which |
1676 | -# respectivly contain the number of errors / warnings messages and the total |
1677 | -# number of statements analyzed. This is used by the global evaluation report |
1678 | -# (R0004). |
1679 | -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) |
1680 | - |
1681 | -# Add a comment according to your evaluation note. This is used by the global |
1682 | -# evaluation report (R0004). |
1683 | -comment=no |
1684 | - |
1685 | -# Enable the report(s) with the given id(s). |
1686 | -#enable-report= |
1687 | - |
1688 | -# Disable the report(s) with the given id(s). |
1689 | -#disable-report= |
1690 | - |
1691 | - |
1692 | -# checks for : |
1693 | -# * doc strings |
1694 | -# * modules / classes / functions / methods / arguments / variables name |
1695 | -# * number of arguments, local variables, branchs, returns and statements in |
1696 | -# functions, methods |
1697 | -# * required module attributes |
1698 | -# * dangerous default values as arguments |
1699 | -# * redefinition of function / method / class |
1700 | -# * uses of the global statement |
1701 | -# |
1702 | -[BASIC] |
1703 | - |
1704 | -# Required attributes for module, separated by a comma |
1705 | -required-attributes= |
1706 | - |
1707 | -# Regular expression which should only match functions or classes name which do |
1708 | -# not require a docstring |
1709 | -no-docstring-rgx=__.*__ |
1710 | - |
1711 | -# Regular expression which should only match correct module names |
1712 | -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ |
1713 | - |
1714 | -# Regular expression which should only match correct module level names |
1715 | -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ |
1716 | - |
1717 | -# Regular expression which should only match correct class names |
1718 | -class-rgx=[A-Z_][a-zA-Z0-9]+$ |
1719 | - |
1720 | -# Regular expression which should only match correct function names |
1721 | -function-rgx=[a-z_][a-z0-9_]{2,30}$ |
1722 | - |
1723 | -# Regular expression which should only match correct method names |
1724 | -method-rgx=[a-z_][a-z0-9_]{2,30}$ |
1725 | - |
1726 | -# Regular expression which should only match correct instance attribute names |
1727 | -attr-rgx=[a-z_][a-z0-9_]{2,30}$ |
1728 | - |
1729 | -# Regular expression which should only match correct argument names |
1730 | -argument-rgx=[a-z_][a-z0-9_]{2,30}$ |
1731 | - |
1732 | -# Regular expression which should only match correct variable names |
1733 | -variable-rgx=[a-z_][a-z0-9_]{2,30}$ |
1734 | - |
1735 | -# Regular expression which should only match correct list comprehension / |
1736 | -# generator expression variable names |
1737 | -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ |
1738 | - |
1739 | -# Good variable names which should always be accepted, separated by a comma |
1740 | -good-names=i,j,k,ex,Run,_ |
1741 | - |
1742 | -# Bad variable names which should always be refused, separated by a comma |
1743 | -bad-names=foo,bar,baz,toto,tutu,tata |
1744 | - |
1745 | -# List of builtins function names that should not be used, separated by a comma |
1746 | -bad-functions=map,filter,apply,input |
1747 | - |
1748 | - |
1749 | -# try to find bugs in the code using type inference |
1750 | -# |
1751 | -[TYPECHECK] |
1752 | - |
1753 | -# Tells wether missing members accessed in mixin class should be ignored. A |
1754 | -# mixin class is detected if its name ends with "mixin" (case insensitive). |
1755 | -ignore-mixin-members=yes |
1756 | - |
1757 | -# List of classes names for which member attributes should not be checked |
1758 | -# (useful for classes with attributes dynamicaly set). |
1759 | -ignored-classes=SQLObject |
1760 | - |
1761 | -# When zope mode is activated, add a predefined set of Zope acquired attributes |
1762 | -# to generated-members. |
1763 | -zope=no |
1764 | - |
1765 | -# List of members which are set dynamically and missed by pylint inference |
1766 | -# system, and so shouldn't trigger E0201 when accessed. |
1767 | -generated-members=REQUEST,acl_users,aq_parent |
1768 | - |
1769 | - |
1770 | -# checks for |
1771 | -# * unused variables / imports |
1772 | -# * undefined variables |
1773 | -# * redefinition of variable from builtins or from an outer scope |
1774 | -# * use of variable before assigment |
1775 | -# |
1776 | -[VARIABLES] |
1777 | - |
1778 | -# Tells wether we should check for unused import in __init__ files. |
1779 | -init-import=no |
1780 | - |
1781 | -# A regular expression matching names used for dummy variables (i.e. not used). |
1782 | -dummy-variables-rgx=_|dummy |
1783 | - |
1784 | -# List of additional names supposed to be defined in builtins. Remember that |
1785 | -# you should avoid to define new builtins when possible. |
1786 | -additional-builtins= |
1787 | - |
1788 | - |
1789 | -# checks for : |
1790 | -# * methods without self as first argument |
1791 | -# * overridden methods signature |
1792 | -# * access only to existant members via self |
1793 | -# * attributes not defined in the __init__ method |
1794 | -# * supported interfaces implementation |
1795 | -# * unreachable code |
1796 | -# |
1797 | -[CLASSES] |
1798 | - |
1799 | -# List of interface methods to ignore, separated by a comma. This is used for |
1800 | -# instance to not check methods defines in Zope's Interface base class. |
1801 | -ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by |
1802 | - |
1803 | -# List of method names used to declare (i.e. assign) instance attributes. |
1804 | -defining-attr-methods=__init__,__new__,setUp |
1805 | - |
1806 | - |
1807 | -# checks for sign of poor/misdesign: |
1808 | -# * number of methods, attributes, local variables... |
1809 | -# * size, complexity of functions, methods |
1810 | -# |
1811 | -[DESIGN] |
1812 | - |
1813 | -# Maximum number of arguments for function / method |
1814 | -max-args=5 |
1815 | - |
1816 | -# Maximum number of locals for function / method body |
1817 | -max-locals=15 |
1818 | - |
1819 | -# Maximum number of return / yield for function / method body |
1820 | -max-returns=6 |
1821 | - |
1822 | -# Maximum number of branch for function / method body |
1823 | -max-branchs=12 |
1824 | - |
1825 | -# Maximum number of statements in function / method body |
1826 | -max-statements=50 |
1827 | - |
1828 | -# Maximum number of parents for a class (see R0901). |
1829 | -max-parents=7 |
1830 | - |
1831 | -# Maximum number of attributes for a class (see R0902). |
1832 | -max-attributes=7 |
1833 | - |
1834 | -# Minimum number of public methods for a class (see R0903). |
1835 | -min-public-methods=2 |
1836 | - |
1837 | -# Maximum number of public methods for a class (see R0904). |
1838 | -max-public-methods=50 |
1839 | - |
1840 | - |
1841 | -# checks for |
1842 | -# * external modules dependencies |
1843 | -# * relative / wildcard imports |
1844 | -# * cyclic imports |
1845 | -# * uses of deprecated modules |
1846 | -# |
1847 | -[IMPORTS] |
1848 | - |
1849 | -# Deprecated modules which should not be used, separated by a comma |
1850 | -deprecated-modules=regsub,string,TERMIOS,Bastion,rexec |
1851 | - |
1852 | -# Create a graph of every (i.e. internal and external) dependencies in the |
1853 | -# given file (report R0402 must not be disabled) |
1854 | -import-graph= |
1855 | - |
1856 | -# Create a graph of external dependencies in the given file (report R0402 must |
1857 | -# not be disabled) |
1858 | -ext-import-graph= |
1859 | - |
1860 | -# Create a graph of internal dependencies in the given file (report R0402 must |
1861 | -# not be disabled) |
1862 | -int-import-graph= |
1863 | - |
1864 | - |
1865 | -# checks for : |
1866 | -# * unauthorized constructions |
1867 | -# * strict indentation |
1868 | -# * line length |
1869 | -# * use of <> instead of != |
1870 | -# |
1871 | -[FORMAT] |
1872 | - |
1873 | -# Maximum number of characters on a single line. |
1874 | -max-line-length=80 |
1875 | - |
1876 | -# Maximum number of lines in a module |
1877 | -max-module-lines=1000 |
1878 | - |
1879 | -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 |
1880 | -# tab). |
1881 | -indent-string=' ' |
1882 | - |
1883 | - |
1884 | -# checks for: |
1885 | -# * warning notes in the code like FIXME, XXX |
1886 | -# * PEP 263: source code with non ascii character but no encoding declaration |
1887 | -# |
1888 | -[MISCELLANEOUS] |
1889 | - |
1890 | -# List of note tags to take in consideration, separated by a comma. |
1891 | -notes=FIXME,XXX,TODO |
1892 | - |
1893 | - |
1894 | -# checks for similarities and duplicated code. This computation may be |
1895 | -# memory / CPU intensive, so you should disable it if you experiments some |
1896 | -# problems. |
1897 | -# |
1898 | -[SIMILARITIES] |
1899 | - |
1900 | -# Minimum lines number of a similarity. |
1901 | -min-similarity-lines=4 |
1902 | - |
1903 | -# Ignore comments when computing similarities. |
1904 | -ignore-comments=yes |
1905 | - |
1906 | -# Ignore docstrings when computing similarities. |
1907 | -ignore-docstrings=yes |
1908 | |
1909 | === added file 'setup.cfg' |
1910 | --- setup.cfg 1970-01-01 00:00:00 +0000 |
1911 | +++ setup.cfg 2013-01-07 01:00:29 +0000 |
1912 | @@ -0,0 +1,8 @@ |
1913 | +[nosetests] |
1914 | +verbosity=3 |
1915 | +with-coverage=1 |
1916 | +with-doctest=1 |
1917 | +doctest-extension=.rst |
1918 | +doctest-options=+ELLIPSIS,+NORMALIZE_WHITESPACE,+REPORT_NDIFF |
1919 | +doctest-fixtures=_fixture |
1920 | +cover-package=lazr.smtptest |
1921 | |
1922 | === modified file 'setup.py' |
1923 | --- setup.py 2009-09-04 19:06:38 +0000 |
1924 | +++ setup.py 2013-01-07 01:00:29 +0000 |
1925 | @@ -1,6 +1,4 @@ |
1926 | -#!/usr/bin/env python |
1927 | - |
1928 | -# Copyright 2009 Canonical Ltd. All rights reserved. |
1929 | +# Copyright 2009-2013 Canonical Ltd. All rights reserved. |
1930 | # |
1931 | # This file is part of lazr.smtptest |
1932 | # |
1933 | @@ -16,10 +14,9 @@ |
1934 | # You should have received a copy of the GNU Lesser General Public License |
1935 | # along with lazr.smtptest. If not, see <http://www.gnu.org/licenses/>. |
1936 | |
1937 | -import ez_setup |
1938 | -ez_setup.use_setuptools() |
1939 | +import distribute_setup |
1940 | +distribute_setup.use_setuptools() |
1941 | |
1942 | -import sys |
1943 | from setuptools import setup, find_packages |
1944 | |
1945 | # generic helpers primarily for the long_description |
1946 | @@ -36,22 +33,21 @@ |
1947 | return '\n'.join(res) |
1948 | # end generic helpers |
1949 | |
1950 | -__version__ = open("src/lazr/smtptest/version.txt").read().strip() |
1951 | +__version__ = open("lazr/smtptest/version.txt").read().strip() |
1952 | |
1953 | setup( |
1954 | name='lazr.smtptest', |
1955 | version=__version__, |
1956 | namespace_packages=['lazr'], |
1957 | - packages=find_packages('src'), |
1958 | - package_dir={'':'src'}, |
1959 | + packages=find_packages(), |
1960 | include_package_data=True, |
1961 | zip_safe=False, |
1962 | maintainer='LAZR Developers', |
1963 | maintainer_email='lazr-developers@lists.launchpad.net', |
1964 | - description=open('README.txt').readline().strip(), |
1965 | + description=open('README.rst').readline().strip(), |
1966 | long_description=generate( |
1967 | - 'src/lazr/smtptest/README.txt', |
1968 | - 'src/lazr/smtptest/NEWS.txt'), |
1969 | + 'lazr/smtptest/README.rst', |
1970 | + 'lazr/smtptest/NEWS.rst'), |
1971 | license='LGPL v3', |
1972 | install_requires=[ |
1973 | 'setuptools', |
1974 | @@ -64,13 +60,10 @@ |
1975 | "Intended Audience :: Developers", |
1976 | "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", |
1977 | "Operating System :: OS Independent", |
1978 | - "Programming Language :: Python"], |
1979 | - extras_require=dict( |
1980 | - docs=['Sphinx', |
1981 | - 'z3c.recipe.sphinxdoc'] |
1982 | - ), |
1983 | - # This does not play nicely with buildout because it downloads but does |
1984 | - # not cache the package. |
1985 | - #setup_requires=['eggtestinfo', 'setuptools_bzr'], |
1986 | - test_suite='lazr.smtptest.tests', |
1987 | + 'Programming Language :: Python', |
1988 | + 'Programming Language :: Python :: 2.6', |
1989 | + 'Programming Language :: Python :: 2.7', |
1990 | + 'Programming Language :: Python :: 3', |
1991 | + ], |
1992 | + test_suite='nose.collector', |
1993 | ) |
1994 | |
1995 | === removed directory 'src' |
1996 | === removed file 'src/lazr/smtptest/tests/test_docs.py' |
1997 | --- src/lazr/smtptest/tests/test_docs.py 2009-06-17 02:41:00 +0000 |
1998 | +++ src/lazr/smtptest/tests/test_docs.py 1970-01-01 00:00:00 +0000 |
1999 | @@ -1,52 +0,0 @@ |
2000 | -# Copyright 2009 Canonical Ltd. All rights reserved. |
2001 | -# |
2002 | -# This file is part of lazr.smtptest |
2003 | -# |
2004 | -# lazr.smtptest is free software: you can redistribute it and/or modify it |
2005 | -# under the terms of the GNU Lesser General Public License as published by |
2006 | -# the Free Software Foundation, version 3 of the License. |
2007 | -# |
2008 | -# lazr.smtptest is distributed in the hope that it will be useful, but WITHOUT |
2009 | -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
2010 | -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
2011 | -# License for more details. |
2012 | -# |
2013 | -# You should have received a copy of the GNU Lesser General Public License |
2014 | -# along with lazr.smtptest. If not, see <http://www.gnu.org/licenses/>. |
2015 | -"Test harness for doctests." |
2016 | - |
2017 | -# pylint: disable-msg=E0611,W0142 |
2018 | - |
2019 | -__metaclass__ = type |
2020 | -__all__ = [ |
2021 | - 'additional_tests', |
2022 | - ] |
2023 | - |
2024 | -import atexit |
2025 | -import doctest |
2026 | -import os |
2027 | -# pylint: disable-msg=F0401 |
2028 | -from pkg_resources import ( |
2029 | - resource_filename, resource_exists, resource_listdir, cleanup_resources) |
2030 | -import unittest |
2031 | - |
2032 | -DOCTEST_FLAGS = ( |
2033 | - doctest.ELLIPSIS | |
2034 | - doctest.NORMALIZE_WHITESPACE | |
2035 | - doctest.REPORT_NDIFF) |
2036 | - |
2037 | - |
2038 | -def additional_tests(): |
2039 | - "Run the doc tests (README.txt and docs/*, if any exist)" |
2040 | - doctest_files = [ |
2041 | - os.path.abspath(resource_filename('lazr.smtptest', 'README.txt'))] |
2042 | - if resource_exists('lazr.smtptest', 'docs'): |
2043 | - for name in resource_listdir('lazr.smtptest', 'docs'): |
2044 | - if name.endswith('.txt'): |
2045 | - doctest_files.append( |
2046 | - os.path.abspath( |
2047 | - resource_filename('lazr.smtptest', 'docs/%s' % name))) |
2048 | - kwargs = dict(module_relative=False, optionflags=DOCTEST_FLAGS) |
2049 | - atexit.register(cleanup_resources) |
2050 | - return unittest.TestSuite(( |
2051 | - doctest.DocFileSuite(*doctest_files, **kwargs))) |
Oh yeah, bumped the version number to 2.0
I'll happily do a PyPI release once this lands.