Merge lp:~cjwatson/launchpadlib/tox into lp:launchpadlib

Proposed by Colin Watson
Status: Merged
Merged at revision: 169
Proposed branch: lp:~cjwatson/launchpadlib/tox
Merge into: lp:launchpadlib
Diff against target: 925 lines (+284/-427)
18 files modified
.bzrignore (+8/-9)
HACKING.rst (+1/-25)
MANIFEST.in (+4/-4)
NEWS.rst (+4/-0)
bootstrap.py (+0/-260)
buildout.cfg (+0/-25)
setup.py (+18/-9)
src/launchpadlib/__init__.py (+3/-1)
src/launchpadlib/docs/Makefile (+20/-0)
src/launchpadlib/docs/conf.py (+171/-0)
src/launchpadlib/docs/index.rst (+13/-0)
src/launchpadlib/docs/people.rst (+7/-3)
src/launchpadlib/docs/toplevel.rst (+4/-0)
src/launchpadlib/testing/launchpad.py (+7/-4)
src/launchpadlib/tests/test_launchpad.py (+5/-2)
src/launchpadlib/version.txt (+1/-0)
tox.ini (+18/-0)
versions.cfg (+0/-85)
To merge this branch: bzr merge lp:~cjwatson/launchpadlib/tox
Reviewer Review Type Date Requested Status
Kristian Glass (community) Approve
LAZR Developers Pending
Review via email: mp+375278@code.launchpad.net

Commit message

Add tox testing support and drop buildout.

To post a comment you must log in.
Revision history for this message
Kristian Glass (doismellburning) wrote :

This feels like it bundles a few things on top of the tox change, including Python 2/3 compatibility (collections import), and a Sphinx migration - how intentional is this, and could it be split...?

That aside, it all looks good, thanks

review: Approve
Revision history for this message
Colin Watson (cjwatson) wrote :

I normally do the Sphinx migration as part of migrating to tox, because normally buildout.cfg sets up a recipe involving z3c.recipe.sphinxdoc and I have to do something with that. In this case that happens not to have been the case, but I mostly just copied bits from previous tox migrations I've done and it was easier this way.

The collections.abc.Callable thing was something I noticed while running tox, but you're probably right that it should be separated, not least because it deserves its own NEWS file entries. I've split that out as https://code.launchpad.net/~cjwatson/launchpadlib/py3-callable/+merge/375893.

Revision history for this message
Kristian Glass (doismellburning) wrote :

Makes sense, thanks!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2010-05-22 12:48:48 +0000
3+++ .bzrignore 2019-11-07 17:42:03 +0000
4@@ -1,13 +1,12 @@
5+*.egg-info
6+*.pyc
7+.tox
8 bin
9-develop-eggs
10-.installed.cfg
11-develop-eggs
12-parts
13-*.egg-info
14-tags
15-TAGS
16 build
17-*.egg
18+develop-eggs
19 dist
20-eggs
21+src/launchpadlib/docs/_build
22+TAGS
23+tags
24 _trial_temp
25+__pycache__
26
27=== renamed file 'HACKING.txt' => 'HACKING.rst'
28--- HACKING.txt 2011-11-21 15:07:01 +0000
29+++ HACKING.rst 2019-11-07 17:42:03 +0000
30@@ -13,19 +13,11 @@
31 You should have received a copy of the GNU Lesser General Public License
32 along with lazr.launchpadlib. If not, see <http://www.gnu.org/licenses/>.
33
34-This project uses zc.buildout for development.
35-
36 ============
37 Introduction
38 ============
39
40-These are guidelines for hacking on the lazr.launchpadlib project. But first,
41-please see the common hacking guidelines at:
42-
43- https://dev.launchpad.net/HackingLazrLibraries
44-
45-These guidelines will tell you how to run the tests, use in-development
46-versions of libraries, land your branches and get them released.
47+To run this project's tests, use `tox <https://tox.readthedocs.io/en/latest/>`.
48
49
50 Getting help
51@@ -42,19 +34,3 @@
52 or send a message to:
53
54 lazr-developers@lists.launchpad.net
55-
56-
57-========
58-Building
59-========
60-
61-As mentioned above, this project uses zc.buildout, which requires a
62-few steps to build some necessary files.
63-
64-The following two steps will create some necessary files, including a
65-bin directory.
66-% python bootstrap.py
67-% bin/buildout
68-
69-Once built you can run all of the tests with:
70-% bin/test
71
72=== modified file 'MANIFEST.in'
73--- MANIFEST.in 2015-11-17 18:29:23 +0000
74+++ MANIFEST.in 2019-11-07 17:42:03 +0000
75@@ -1,4 +1,4 @@
76-exclude MANIFEST.in buildout.cfg bootstrap.py .bzrignore
77-global-include *.txt *.xsl *.png
78-prune _bootstrap
79-prune eggs
80+exclude MANIFEST.in .bzrignore
81+global-include *.txt *.rst *.xml *.xsl *.png
82+include src/launchpadlib/docs/Makefile
83+prune src/launchpadlib/docs/_build
84
85=== renamed file 'NEWS.txt' => 'NEWS.rst'
86--- NEWS.txt 2019-11-04 22:50:46 +0000
87+++ NEWS.rst 2019-11-07 17:42:03 +0000
88@@ -2,6 +2,10 @@
89 NEWS for launchpadlib
90 =====================
91
92+1.10.8
93+======
94+- Switch from buildout to tox.
95+
96 1.10.7 (2019-05-22)
97 ===================
98 - Change 'dev' URLs from launchpad.dev to launchpad.test.
99
100=== renamed file 'README.txt' => 'README.rst'
101=== removed file 'bootstrap.py'
102--- bootstrap.py 2010-10-13 20:09:38 +0000
103+++ bootstrap.py 1970-01-01 00:00:00 +0000
104@@ -1,260 +0,0 @@
105-##############################################################################
106-#
107-# Copyright (c) 2006 Zope Foundation and Contributors.
108-# All Rights Reserved.
109-#
110-# This software is subject to the provisions of the Zope Public License,
111-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
112-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
113-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
114-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
115-# FOR A PARTICULAR PURPOSE.
116-#
117-##############################################################################
118-"""Bootstrap a buildout-based project
119-
120-Simply run this script in a directory containing a buildout.cfg.
121-The script accepts buildout command-line options, so you can
122-use the -c option to specify an alternate configuration file.
123-"""
124-
125-import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
126-from optparse import OptionParser
127-
128-if sys.platform == 'win32':
129- def quote(c):
130- if ' ' in c:
131- return '"%s"' % c # work around spawn lamosity on windows
132- else:
133- return c
134-else:
135- quote = str
136-
137-# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
138-stdout, stderr = subprocess.Popen(
139- [sys.executable, '-Sc',
140- 'try:\n'
141- ' import ConfigParser\n'
142- 'except ImportError:\n'
143- ' print 1\n'
144- 'else:\n'
145- ' print 0\n'],
146- stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
147-has_broken_dash_S = bool(int(stdout.strip()))
148-
149-# In order to be more robust in the face of system Pythons, we want to
150-# run without site-packages loaded. This is somewhat tricky, in
151-# particular because Python 2.6's distutils imports site, so starting
152-# with the -S flag is not sufficient. However, we'll start with that:
153-if not has_broken_dash_S and 'site' in sys.modules:
154- # We will restart with python -S.
155- args = sys.argv[:]
156- args[0:0] = [sys.executable, '-S']
157- args = map(quote, args)
158- os.execv(sys.executable, args)
159-# Now we are running with -S. We'll get the clean sys.path, import site
160-# because distutils will do it later, and then reset the path and clean
161-# out any namespace packages from site-packages that might have been
162-# loaded by .pth files.
163-clean_path = sys.path[:]
164-import site
165-sys.path[:] = clean_path
166-for k, v in sys.modules.items():
167- if k in ('setuptools', 'pkg_resources') or (
168- hasattr(v, '__path__') and
169- len(v.__path__)==1 and
170- not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
171- # This is a namespace package. Remove it.
172- sys.modules.pop(k)
173-
174-is_jython = sys.platform.startswith('java')
175-
176-setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
177-distribute_source = 'http://python-distribute.org/distribute_setup.py'
178-
179-# parsing arguments
180-def normalize_to_url(option, opt_str, value, parser):
181- if value:
182- if '://' not in value: # It doesn't smell like a URL.
183- value = 'file://%s' % (
184- urllib.pathname2url(
185- os.path.abspath(os.path.expanduser(value))),)
186- if opt_str == '--download-base' and not value.endswith('/'):
187- # Download base needs a trailing slash to make the world happy.
188- value += '/'
189- else:
190- value = None
191- name = opt_str[2:].replace('-', '_')
192- setattr(parser.values, name, value)
193-
194-usage = '''\
195-[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
196-
197-Bootstraps a buildout-based project.
198-
199-Simply run this script in a directory containing a buildout.cfg, using the
200-Python that you want bin/buildout to use.
201-
202-Note that by using --setup-source and --download-base to point to
203-local resources, you can keep this script from going over the network.
204-'''
205-
206-parser = OptionParser(usage=usage)
207-parser.add_option("-v", "--version", dest="version",
208- help="use a specific zc.buildout version")
209-parser.add_option("-d", "--distribute",
210- action="store_true", dest="use_distribute", default=False,
211- help="Use Distribute rather than Setuptools.")
212-parser.add_option("--setup-source", action="callback", dest="setup_source",
213- callback=normalize_to_url, nargs=1, type="string",
214- help=("Specify a URL or file location for the setup file. "
215- "If you use Setuptools, this will default to " +
216- setuptools_source + "; if you use Distribute, this "
217- "will default to " + distribute_source +"."))
218-parser.add_option("--download-base", action="callback", dest="download_base",
219- callback=normalize_to_url, nargs=1, type="string",
220- help=("Specify a URL or directory for downloading "
221- "zc.buildout and either Setuptools or Distribute. "
222- "Defaults to PyPI."))
223-parser.add_option("--eggs",
224- help=("Specify a directory for storing eggs. Defaults to "
225- "a temporary directory that is deleted when the "
226- "bootstrap script completes."))
227-parser.add_option("-t", "--accept-buildout-test-releases",
228- dest='accept_buildout_test_releases',
229- action="store_true", default=False,
230- help=("Normally, if you do not specify a --version, the "
231- "bootstrap script and buildout gets the newest "
232- "*final* versions of zc.buildout and its recipes and "
233- "extensions for you. If you use this flag, "
234- "bootstrap and buildout will get the newest releases "
235- "even if they are alphas or betas."))
236-parser.add_option("-c", None, action="store", dest="config_file",
237- help=("Specify the path to the buildout configuration "
238- "file to be used."))
239-
240-options, args = parser.parse_args()
241-
242-# if -c was provided, we push it back into args for buildout's main function
243-if options.config_file is not None:
244- args += ['-c', options.config_file]
245-
246-if options.eggs:
247- eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
248-else:
249- eggs_dir = tempfile.mkdtemp()
250-
251-if options.setup_source is None:
252- if options.use_distribute:
253- options.setup_source = distribute_source
254- else:
255- options.setup_source = setuptools_source
256-
257-if options.accept_buildout_test_releases:
258- args.append('buildout:accept-buildout-test-releases=true')
259-args.append('bootstrap')
260-
261-try:
262- import pkg_resources
263- import setuptools # A flag. Sometimes pkg_resources is installed alone.
264- if not hasattr(pkg_resources, '_distribute'):
265- raise ImportError
266-except ImportError:
267- ez_code = urllib2.urlopen(
268- options.setup_source).read().replace('\r\n', '\n')
269- ez = {}
270- exec ez_code in ez
271- setup_args = dict(to_dir=eggs_dir, download_delay=0)
272- if options.download_base:
273- setup_args['download_base'] = options.download_base
274- if options.use_distribute:
275- setup_args['no_fake'] = True
276- ez['use_setuptools'](**setup_args)
277- if 'pkg_resources' in sys.modules:
278- reload(sys.modules['pkg_resources'])
279- import pkg_resources
280- # This does not (always?) update the default working set. We will
281- # do it.
282- for path in sys.path:
283- if path not in pkg_resources.working_set.entries:
284- pkg_resources.working_set.add_entry(path)
285-
286-cmd = [quote(sys.executable),
287- '-c',
288- quote('from setuptools.command.easy_install import main; main()'),
289- '-mqNxd',
290- quote(eggs_dir)]
291-
292-if not has_broken_dash_S:
293- cmd.insert(1, '-S')
294-
295-find_links = options.download_base
296-if not find_links:
297- find_links = os.environ.get('bootstrap-testing-find-links')
298-if find_links:
299- cmd.extend(['-f', quote(find_links)])
300-
301-if options.use_distribute:
302- setup_requirement = 'distribute'
303-else:
304- setup_requirement = 'setuptools'
305-ws = pkg_resources.working_set
306-setup_requirement_path = ws.find(
307- pkg_resources.Requirement.parse(setup_requirement)).location
308-env = dict(
309- os.environ,
310- PYTHONPATH=setup_requirement_path)
311-
312-requirement = 'zc.buildout'
313-version = options.version
314-if version is None and not options.accept_buildout_test_releases:
315- # Figure out the most recent final version of zc.buildout.
316- import setuptools.package_index
317- _final_parts = '*final-', '*final'
318- def _final_version(parsed_version):
319- for part in parsed_version:
320- if (part[:1] == '*') and (part not in _final_parts):
321- return False
322- return True
323- index = setuptools.package_index.PackageIndex(
324- search_path=[setup_requirement_path])
325- if find_links:
326- index.add_find_links((find_links,))
327- req = pkg_resources.Requirement.parse(requirement)
328- if index.obtain(req) is not None:
329- best = []
330- bestv = None
331- for dist in index[req.project_name]:
332- distv = dist.parsed_version
333- if _final_version(distv):
334- if bestv is None or distv > bestv:
335- best = [dist]
336- bestv = distv
337- elif distv == bestv:
338- best.append(dist)
339- if best:
340- best.sort()
341- version = best[-1].version
342-if version:
343- requirement = '=='.join((requirement, version))
344-cmd.append(requirement)
345-
346-if is_jython:
347- import subprocess
348- exitcode = subprocess.Popen(cmd, env=env).wait()
349-else: # Windows prefers this, apparently; otherwise we would prefer subprocess
350- exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
351-if exitcode != 0:
352- sys.stdout.flush()
353- sys.stderr.flush()
354- print ("An error occurred when trying to install zc.buildout. "
355- "Look above this message for any errors that "
356- "were output by easy_install.")
357- sys.exit(exitcode)
358-
359-ws.add_entry(eggs_dir)
360-ws.require(requirement)
361-import zc.buildout.buildout
362-zc.buildout.buildout.main(args)
363-if not options.eggs: # clean up temporary egg directory
364- shutil.rmtree(eggs_dir)
365
366=== removed file 'buildout.cfg'
367--- buildout.cfg 2014-07-04 14:55:48 +0000
368+++ buildout.cfg 1970-01-01 00:00:00 +0000
369@@ -1,25 +0,0 @@
370-[buildout]
371-extends = versions.cfg
372-parts =
373- interpreter
374- test
375- tags
376-unzip = true
377-include-site-packages = false
378-exec-sitecustomize = false
379-develop = .
380-
381-[test]
382-recipe = zc.recipe.testrunner
383-eggs = launchpadlib
384-defaults = '--tests-pattern ^tests --exit-with-status'.split()
385-
386-[interpreter]
387-recipe = z3c.recipe.scripts
388-interpreter = py
389-eggs = launchpadlib
390- docutils
391-
392-[tags]
393-recipe = z3c.recipe.tag:tags
394-eggs = launchpadlib
395
396=== modified file 'setup.py'
397--- setup.py 2019-11-04 22:50:46 +0000
398+++ setup.py 2019-11-07 17:42:03 +0000
399@@ -23,20 +23,23 @@
400
401 # generic helpers primarily for the long_description
402 def generate(*docname_or_string):
403+ marker = '.. pypi description ends here'
404 res = []
405 for value in docname_or_string:
406- if value.endswith('.txt'):
407- f = open(value)
408- value = f.read()
409- f.close()
410+ if value.endswith('.rst'):
411+ with open(value) as f:
412+ value = f.read()
413+ idx = value.find(marker)
414+ if idx >= 0:
415+ value = value[:idx]
416 res.append(value)
417 if not value.endswith('\n'):
418 res.append('')
419 return '\n'.join(res)
420 # end generic helpers
421
422-sys.path.insert(0, 'src')
423-from launchpadlib import __version__
424+with open("src/launchpadlib/version.txt") as version_file:
425+ __version__ = version_file.read().strip()
426
427 install_requires = [
428 'httplib2',
429@@ -62,10 +65,10 @@
430 maintainer='LAZR Developers',
431 maintainer_email='lazr-developers@lists.launchpad.net',
432 download_url= 'https://launchpad.net/launchpadlib/+download',
433- description=open('README.txt').readline().strip(),
434+ description=open('README.rst').readline().strip(),
435 long_description=generate(
436- 'src/launchpadlib/README.txt',
437- 'NEWS.txt'),
438+ 'src/launchpadlib/docs/index.rst',
439+ 'NEWS.rst'),
440 license='LGPL v3',
441 install_requires=install_requires,
442 url='https://help.launchpad.net/API/launchpadlib',
443@@ -76,7 +79,13 @@
444 "Operating System :: OS Independent",
445 "Programming Language :: Python",
446 "Programming Language :: Python :: 2",
447+ "Programming Language :: Python :: 2.7",
448 "Programming Language :: Python :: 3",
449+ "Programming Language :: Python :: 3.5",
450+ "Programming Language :: Python :: 3.6",
451+ "Programming Language :: Python :: 3.7",
452+ "Programming Language :: Python :: 3.8",
453 ],
454+ extras_require={'docs': ['Sphinx']},
455 test_suite='launchpadlib.tests',
456 )
457
458=== modified file 'src/launchpadlib/__init__.py'
459--- src/launchpadlib/__init__.py 2019-05-22 14:42:44 +0000
460+++ src/launchpadlib/__init__.py 2019-11-07 17:42:03 +0000
461@@ -14,4 +14,6 @@
462 # You should have received a copy of the GNU Lesser General Public License
463 # along with launchpadlib. If not, see <http://www.gnu.org/licenses/>.
464
465-__version__ = '1.10.7'
466+import pkg_resources
467+__version__ = pkg_resources.resource_string(
468+ "launchpadlib", "version.txt").strip()
469
470=== added file 'src/launchpadlib/docs/Makefile'
471--- src/launchpadlib/docs/Makefile 1970-01-01 00:00:00 +0000
472+++ src/launchpadlib/docs/Makefile 2019-11-07 17:42:03 +0000
473@@ -0,0 +1,20 @@
474+# Minimal makefile for Sphinx documentation
475+#
476+
477+# You can set these variables from the command line.
478+SPHINXOPTS =
479+SPHINXBUILD = sphinx-build
480+SPHINXPROJ = launchpadlib
481+SOURCEDIR = .
482+BUILDDIR = _build
483+
484+# Put it first so that "make" without argument is like "make help".
485+help:
486+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
487+
488+.PHONY: help Makefile
489+
490+# Catch-all target: route all unknown targets to Sphinx using the new
491+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
492+%: Makefile
493+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
494\ No newline at end of file
495
496=== added symlink 'src/launchpadlib/docs/NEWS.rst'
497=== target is u'../../../NEWS.rst'
498=== renamed file 'src/launchpadlib/docs/command-line.txt' => 'src/launchpadlib/docs/command-line.rst'
499=== added file 'src/launchpadlib/docs/conf.py'
500--- src/launchpadlib/docs/conf.py 1970-01-01 00:00:00 +0000
501+++ src/launchpadlib/docs/conf.py 2019-11-07 17:42:03 +0000
502@@ -0,0 +1,171 @@
503+# -*- coding: utf-8 -*-
504+#
505+# launchpadlib documentation build configuration file, created by
506+# sphinx-quickstart on Tue Nov 5 23:48:15 2019.
507+#
508+# This file is execfile()d with the current directory set to its
509+# containing dir.
510+#
511+# Note that not all possible configuration values are present in this
512+# autogenerated file.
513+#
514+# All configuration values have a default; values that are commented out
515+# serve to show the default.
516+
517+with open('../version.txt') as version_file:
518+ _version = version_file.read().strip()
519+
520+# If extensions (or modules to document with autodoc) are in another directory,
521+# add these directories to sys.path here. If the directory is relative to the
522+# documentation root, use os.path.abspath to make it absolute, like shown here.
523+#
524+# import os
525+# import sys
526+# sys.path.insert(0, os.path.abspath('.'))
527+
528+
529+# -- General configuration ------------------------------------------------
530+
531+# If your documentation needs a minimal Sphinx version, state it here.
532+#
533+# needs_sphinx = '1.0'
534+
535+# Add any Sphinx extension module names here, as strings. They can be
536+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
537+# ones.
538+extensions = []
539+
540+# Add any paths that contain templates here, relative to this directory.
541+templates_path = ['_templates']
542+
543+# The suffix(es) of source filenames.
544+# You can specify multiple suffix as a list of string:
545+#
546+# source_suffix = ['.rst', '.md']
547+source_suffix = '.rst'
548+
549+# The master toctree document.
550+master_doc = 'index'
551+
552+# General information about the project.
553+project = u'launchpadlib'
554+copyright = u'2008-2019, Canonical Ltd.'
555+author = u'LAZR Developers <lazr-developers@lists.launchpad.net>'
556+
557+# The version info for the project you're documenting, acts as replacement for
558+# |version| and |release|, also used in various other places throughout the
559+# built documents.
560+#
561+# The short X.Y version.
562+version = _version
563+# The full version, including alpha/beta/rc tags.
564+release = _version
565+
566+# The language for content autogenerated by Sphinx. Refer to documentation
567+# for a list of supported languages.
568+#
569+# This is also used if you do content translation via gettext catalogs.
570+# Usually you set "language" from the command line for these cases.
571+language = None
572+
573+# List of patterns, relative to source directory, that match files and
574+# directories to ignore when looking for source files.
575+# This patterns also effect to html_static_path and html_extra_path
576+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
577+
578+# The name of the Pygments (syntax highlighting) style to use.
579+pygments_style = 'sphinx'
580+
581+# If true, `todo` and `todoList` produce output, else they produce nothing.
582+todo_include_todos = False
583+
584+
585+# -- Options for HTML output ----------------------------------------------
586+
587+# The theme to use for HTML and HTML Help pages. See the documentation for
588+# a list of builtin themes.
589+#
590+html_theme = 'alabaster'
591+
592+# Theme options are theme-specific and customize the look and feel of a theme
593+# further. For a list of options available for each theme, see the
594+# documentation.
595+#
596+# html_theme_options = {}
597+
598+# Add any paths that contain custom static files (such as style sheets) here,
599+# relative to this directory. They are copied after the builtin static files,
600+# so a file named "default.css" will overwrite the builtin "default.css".
601+html_static_path = ['_static']
602+
603+# Custom sidebar templates, must be a dictionary that maps document names
604+# to template names.
605+#
606+# This is required for the alabaster theme
607+# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
608+html_sidebars = {
609+ '**': [
610+ 'relations.html', # needs 'show_related': True theme option to display
611+ 'searchbox.html',
612+ ]
613+}
614+
615+
616+# -- Options for HTMLHelp output ------------------------------------------
617+
618+# Output file base name for HTML help builder.
619+htmlhelp_basename = 'launchpadlibdoc'
620+
621+
622+# -- Options for LaTeX output ---------------------------------------------
623+
624+latex_elements = {
625+ # The paper size ('letterpaper' or 'a4paper').
626+ #
627+ # 'papersize': 'letterpaper',
628+
629+ # The font size ('10pt', '11pt' or '12pt').
630+ #
631+ # 'pointsize': '10pt',
632+
633+ # Additional stuff for the LaTeX preamble.
634+ #
635+ # 'preamble': '',
636+
637+ # Latex figure (float) alignment
638+ #
639+ # 'figure_align': 'htbp',
640+}
641+
642+# Grouping the document tree into LaTeX files. List of tuples
643+# (source start file, target name, title,
644+# author, documentclass [howto, manual, or own class]).
645+latex_documents = [
646+ (master_doc, 'launchpadlib.tex', u'launchpadlib Documentation',
647+ u'LAZR Developers \\textless{}lazr-developers@lists.launchpad.net\\textgreater{}', 'manual'),
648+]
649+
650+
651+# -- Options for manual page output ---------------------------------------
652+
653+# One entry per manual page. List of tuples
654+# (source start file, name, description, authors, manual section).
655+man_pages = [
656+ (master_doc, 'launchpadlib', u'launchpadlib Documentation',
657+ [author], 1)
658+]
659+
660+
661+# -- Options for Texinfo output -------------------------------------------
662+
663+# Grouping the document tree into Texinfo files. List of tuples
664+# (source start file, target name, title, author,
665+# dir menu entry, description, category)
666+texinfo_documents = [
667+ (master_doc, 'launchpadlib', u'launchpadlib Documentation',
668+ author, 'launchpadlib', 'One line description of project.',
669+ 'Miscellaneous'),
670+]
671+
672+
673+
674
675=== renamed file 'src/launchpadlib/docs/hosted-files.txt' => 'src/launchpadlib/docs/hosted-files.rst'
676=== renamed file 'src/launchpadlib/README.txt' => 'src/launchpadlib/docs/index.rst'
677--- src/launchpadlib/README.txt 2009-03-20 20:46:06 +0000
678+++ src/launchpadlib/docs/index.rst 2019-11-07 17:42:03 +0000
679@@ -17,3 +17,16 @@
680 ************
681
682 See https://help.launchpad.net/API/launchpadlib .
683+
684+.. pypi description ends here
685+
686+.. toctree::
687+ :glob:
688+
689+ introduction
690+ operations
691+ toplevel
692+ people
693+ hosted-files
694+ command-line
695+ NEWS
696
697=== renamed file 'src/launchpadlib/docs/introduction.txt' => 'src/launchpadlib/docs/introduction.rst'
698=== renamed file 'src/launchpadlib/docs/operations.txt' => 'src/launchpadlib/docs/operations.rst'
699=== renamed file 'src/launchpadlib/docs/people.txt' => 'src/launchpadlib/docs/people.rst'
700--- src/launchpadlib/docs/people.txt 2016-07-12 14:56:47 +0000
701+++ src/launchpadlib/docs/people.rst 2019-11-07 17:42:03 +0000
702@@ -1,4 +1,6 @@
703-= People and Teams =
704+****************
705+People and Teams
706+****************
707
708 The Launchpad web service, like Launchpad itself, exposes a unified
709 interface to people and teams. In other words, people and teams
710@@ -7,7 +9,8 @@
711 dealing with a person or a team.
712
713
714-== People ==
715+People
716+======
717
718 You can access Launchpad people through the web service interface.
719 The list of people is available from the service root.
720@@ -103,7 +106,8 @@
721 u'Public'
722
723
724-== Teams ==
725+Teams
726+=====
727
728 You also access teams using the same interface.
729
730
731=== renamed file 'src/launchpadlib/docs/toplevel.txt' => 'src/launchpadlib/docs/toplevel.rst'
732--- src/launchpadlib/docs/toplevel.txt 2011-07-27 05:33:26 +0000
733+++ src/launchpadlib/docs/toplevel.rst 2019-11-07 17:42:03 +0000
734@@ -1,3 +1,7 @@
735+*********************
736+Top-level collections
737+*********************
738+
739 The launchpad web service's top-level collections provide access to
740 Launchpad-wide objects like projects and people.
741
742
743=== modified file 'src/launchpadlib/testing/launchpad.py'
744--- src/launchpadlib/testing/launchpad.py 2014-07-14 20:29:51 +0000
745+++ src/launchpadlib/testing/launchpad.py 2019-11-07 17:42:03 +0000
746@@ -66,7 +66,10 @@
747 """
748
749 from datetime import datetime
750-import collections
751+try:
752+ from collections.abc import Callable
753+except ImportError:
754+ from collections import Callable
755 import sys
756 if sys.version_info[0] >= 3:
757 basestring = str
758@@ -205,7 +208,7 @@
759 result = self._children.get(name, _marker)
760 if result is _marker:
761 result = self._values.get(name, _marker)
762- if isinstance(result, collections.Callable):
763+ if isinstance(result, Callable):
764 return self._wrap_method(name, result)
765 if name in self.special_methods:
766 return lambda: True
767@@ -280,7 +283,7 @@
768 attributes and methods.
769 """
770 for name, value in partial_object.items():
771- if isinstance(value, collections.Callable):
772+ if isinstance(value, Callable):
773 # Performs an integrity check.
774 self._get_method(resource_type, name)
775 else:
776@@ -306,7 +309,7 @@
777 if name == "entries":
778 name, child_resource_type = (
779 self._check_entries(resource_type, value))
780- elif isinstance(value, collections.Callable):
781+ elif isinstance(value, Callable):
782 # Performs an integrity check.
783 self._get_method(resource_type, name)
784 else:
785
786=== modified file 'src/launchpadlib/tests/test_launchpad.py'
787--- src/launchpadlib/tests/test_launchpad.py 2015-07-10 22:42:14 +0000
788+++ src/launchpadlib/tests/test_launchpad.py 2019-11-07 17:42:03 +0000
789@@ -529,12 +529,15 @@
790 def test_None_launchpadlib_dir(self):
791 # If no launchpadlib_dir is passed in to login_with,
792 # $HOME/.launchpadlib is used.
793- old_home = os.environ['HOME']
794+ old_home = os.environ.get('HOME')
795 os.environ['HOME'] = self.temp_dir
796 launchpad = NoNetworkLaunchpad.login_with(
797 'app name', service_root=SERVICE_ROOT)
798 # Reset the environment to the old value.
799- os.environ['HOME'] = old_home
800+ if old_home is not None:
801+ os.environ['HOME'] = old_home
802+ else:
803+ del os.environ['HOME']
804
805 cache_dir = launchpad.passed_in_args['cache']
806 launchpadlib_dir = os.path.abspath(
807
808=== added file 'src/launchpadlib/version.txt'
809--- src/launchpadlib/version.txt 1970-01-01 00:00:00 +0000
810+++ src/launchpadlib/version.txt 2019-11-07 17:42:03 +0000
811@@ -0,0 +1,1 @@
812+1.10.7
813
814=== added file 'tox.ini'
815--- tox.ini 1970-01-01 00:00:00 +0000
816+++ tox.ini 2019-11-07 17:42:03 +0000
817@@ -0,0 +1,18 @@
818+[tox]
819+envlist =
820+ py27,py35,py36,py37,py38,docs
821+
822+[testenv]
823+commands =
824+ zope-testrunner --test-path src --tests-pattern ^tests {posargs}
825+deps =
826+ .
827+ zope.testrunner
828+
829+[testenv:docs]
830+basepython =
831+ python2.7
832+commands =
833+ sphinx-build -b html -d src/launchpadlib/docs/_build/doctrees src/launchpadlib/docs src/launchpadlib/docs/_build/html
834+deps =
835+ .[docs]
836
837=== removed file 'versions.cfg'
838--- versions.cfg 2014-07-04 14:55:48 +0000
839+++ versions.cfg 1970-01-01 00:00:00 +0000
840@@ -1,85 +0,0 @@
841-[buildout]
842-versions = versions
843-allow-picked-versions = false
844-use-dependency-links = false
845-
846-
847-[versions]
848-# Alphabetical, case-SENSITIVE, blank line after this comment
849-
850-Jinja2 = 2.5.5
851-Pygments = 1.4
852-RestrictedPython = 3.6.0
853-Sphinx = 1.0.1
854-ZConfig = 2.7.1
855-ZODB3 = 3.9.2
856-distribute = 0.6.27
857-docutils = 0.5
858-elementtree = 1.2.7-20070827-preview
859-epydoc = 3.0.1
860-fixtures = 0.3.9
861-grokcore.component = 1.6
862-httplib2 = 0.7.4
863-lazr.authentication = 0.1.2
864-lazr.batchnavigator = 1.2.7
865-lazr.delegates = 1.2.0
866-lazr.enum = 1.1.2
867-lazr.lifecycle = 1.0
868-lazr.restful = 0.19.7
869-lazr.uri = 1.0.2
870-lazr.restfulclient = 0.13.3
871-testresources = 0.2.7
872-keyring = 3.8
873-lxml = 2.2.7
874-martian = 0.11
875-oauth = 1.0.1
876-pytz = 2010o
877-setuptools = 0.6c11
878-simplejson = 2.5.0
879-testtools = 0.9.11
880-transaction = 1.0.0
881-van.testing = 3.0.0
882-wadllib = 1.2.0
883-wsgi-intercept = 0.5.1
884-wsgiref = 0.1.2
885-z3c.recipe.scripts = 1.0.1
886-z3c.recipe.sphinxdoc = 0.0.8
887-z3c.recipe.staticlxml = 0.7.1
888-z3c.recipe.tag = 0.2.0
889-zc.buildout = 1.5.2
890-zc.lockfile = 1.0.0
891-zc.recipe.cmmi = 1.3.1
892-zc.recipe.egg = 1.3.2
893-zc.recipe.testrunner = 1.4.0
894-zdaemon = 2.0.4
895-zope.annotation = 3.5.0
896-zope.app.pagetemplate = 3.11.2
897-zope.browser = 1.3
898-zope.browserpage = 3.12.2
899-zope.cachedescriptors = 3.5.1
900-zope.component = 3.10.0
901-zope.configuration = 3.6.0
902-zope.contenttype = 3.5.1
903-zope.copy = 3.5.0
904-zope.datetime = 3.4.0
905-zope.dublincore = 3.8.1
906-zope.event = 3.5.0-1
907-zope.exceptions = 3.5.2
908-zope.hookable = 3.4.1
909-zope.i18n = 3.7.4
910-zope.i18nmessageid = 3.5.3
911-zope.interface = 3.5.2
912-zope.lifecycleevent = 3.6.2
913-zope.location = 3.9.0
914-zope.pagetemplate = 3.5.2
915-zope.processlifetime = 1.0
916-zope.proxy = 3.6.1
917-zope.publisher = 3.12.6
918-zope.schema = 3.7.1
919-zope.security = 3.8.0
920-zope.size = 3.4.1
921-zope.tal = 3.5.2
922-zope.tales = 3.5.1
923-zope.testing = 3.10.2
924-zope.testrunner = 4.0.0b5
925-zope.traversing = 3.13.1

Subscribers

People subscribed via source and target branches