Merge lp:~lvh/divmod.org/modernize-axiom-packaging into lp:divmod.org
- modernize-axiom-packaging
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 2718 |
Proposed branch: | lp:~lvh/divmod.org/modernize-axiom-packaging |
Merge into: | lp:divmod.org |
Diff against target: |
167 lines (+95/-26) 7 files modified
Axiom/.coveragerc (+8/-0) Axiom/axiom/__init__.py (+7/-4) Axiom/axiom/_version.py (+1/-3) Axiom/requirements-testing.txt (+2/-0) Axiom/requirements.txt (+5/-7) Axiom/setup.py (+48/-12) Axiom/tox.ini (+24/-0) |
To merge this branch: | bzr merge lp:~lvh/divmod.org/modernize-axiom-packaging |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tristan Seligmann | Needs Fixing | ||
Jean-Paul Calderone | Needs Fixing | ||
Review via email: mp+180311@code.launchpad.net |
Commit message
Description of the change
A number of changes to make Axiom a bit more present-day Python packaging compatible :)
setup.py now works without relying on non-stdlib projects. This makes it easier to pip install Axiom.
Also, tox has been configured to automagically make virtualenvs to run the tests in. This will hopefully make test runs more reproducible, instead of relying. It has the added benefit that our dependency specifications (previously DEPS.txt, now requirements.txt, for consistency with current packaging standards) are actually tested. As a free bonus, tox does coverage testing using coverage.py, too.
Laurens Van Houtven (lvh) wrote : | # |
Laurens Van Houtven (lvh) wrote : | # |
(Also, this patch doesn't actually make Axiom pip installable yet on a clean machine, as you can tell from tox.ini. To do that, I'm going to have to give Epsilon similar treatment.)
- 2728. By Laurens Van Houtven
-
Don't use setuptools
Jean-Paul Calderone (exarkun) wrote : | # |
Thanks.
1) The way setup.py and axiom/_version.py interact to convey version information seems more complex than necessary. This is of particular interest since there is no test coverage of setup.py's idea of the project version, I think. Since assembling strings is easier than parsing them, perhaps the version information should be available as a string literal in _version.py - whatever form is the absolute simplest for setup.py to get at - and it can be parsed into the Version object in _version.py (by unit tested code).
Oh, apparently that's my only comment. Please address, verify the result is sufficiently successful on continuous integration, and then merge.
Thanks again!
Laurens Van Houtven (lvh) wrote : | # |
I'm a bit at a loss of how to make this better. A version number tuple (i.e. (1, 2, 3)) makes the regex essentially the same. An explicit version string would require parsing the string again (granted, *map(int, v.split(".") isn't the hardest parse in the world).
Tristan Seligmann (mithrandi) wrote : | # |
+1 on this branch, aside from the issue exarkun raised above, but I'd like to suggest something else: dropping support for Python 2.4 and Python 2.5. This is probably a little out of scope for this branch, but since you're adding a requirements-
We don't actually seem to have an explict statement of Python version requirement anywhere now that DEPS.txt is gone; I guess the way to indicate this is with the appropriate classifiers?
- 2729. By Laurens Van Houtven
-
Address JP's version issues
- 2730. By Laurens Van Houtven
-
Remove Python 2.4 requirements file
- 2731. By Laurens Van Houtven
-
Update existing requirements file
- 2732. By Laurens Van Houtven
-
Test against Twisted trunk
- 2733. By Laurens Van Houtven
-
Add trove classifiers for supported Python versions
Laurens Van Houtven (lvh) wrote : | # |
I've added the trove classifiers.
The tox.ini file now tests against py26 and py27, both for Twisted's latest release and Twisted trunk.
Tristan Seligmann (mithrandi) wrote : | # |
I've noticed another issue with switching away from epsilon.
Tristan Seligmann (mithrandi) wrote : | # |
To summarize: the new setup.py doesn't regenerate the Twisted plugin cache post-install the way epsilon.setuphelper does. This doesn't matter for distro packaging or user installs, but represents a regression for system-wide installs as the administrator will need to regenerate the plugin cache manually.
(Also, I don't know of a better way of doing this than the hack present in epsilon.
Jean-Paul Calderone (exarkun) wrote : | # |
A better implementation than epsilon.setuphelper is probably to customize the `install` command. http://
Laurens Van Houtven (lvh) wrote : | # |
I'm trying to do this, but this section of distutils isn't really documented[1]. For one, epsilon.
Either way, that thing seems pretty general, and I think it can all be boiled down to:
list(plugin.
maybe wrapped in a try except if modules have been removed. I'm not sure what happens if pip is dragging in Twisted as a dependency when installing Axiom.
[1]: http://
Laurens Van Houtven (lvh) wrote : | # |
I am saddened:
https:/
I'm not entirely sure what the hell is going on there, but it appears that by default, setup.py install is using some *setuptools* stuff; that's the only way I can explain that that flag works, since it's something distutils doesn't know about.
Laurens Van Houtven (lvh) wrote : | # |
Realized why. tox installs axiom into the virtualenv using pip, which uses setuptools. I guess when I said earlier that I could do this with distutils, that wasn't really true. Sorry.
- 2734. By Laurens Van Houtven
-
Explicitly use setuptools
- 2735. By Laurens Van Houtven
-
Post-install cache regeneration
- 2736. By Laurens Van Houtven
-
Merge trunk
- 2737. By Laurens Van Houtven
-
Merge new trunk (with removed performance tests that were causing failures on py27 + new sqlites)
Laurens Van Houtven (lvh) wrote : | # |
I've fixed this by customizing the equivalent setuptools command.
This regenerates the cache using the command Tristan suggested. The only downside is that it now requires setuptools. On the plus side running the tests using tox now no longer relies on pip's deep distutils-masking magic :)
Please review.
Laurens Van Houtven (lvh) wrote : | # |
Also, my new branch: https:/
- 2738. By Laurens Van Houtven
-
Use Launchpad page as URL
Tristan Seligmann (mithrandi) wrote : | # |
> list(plugin.
I haven't actually tried running this code yet, but I'm pretty sure it raises an exception. The second parameter to getPlugins() is an actual python module object, not a string. In other words, this code should be something like:
import axiom.plugins
list(plugin.
list(plugin.
(Note the two calls to getPlugins; we want to regenerate the cache for twisted.plugins as well as for axiom.plugins)
Alas, I suspect this approach may work fine when running 'setup.py install' as the old setup.py did, but fail during a pip installation (or during the building of a Debian/etc. package) as Axiom is not being installed into a location that is on the sys.path of the running Python interpreter.
- 2739. By Laurens Van Houtven
-
Fix cache regeneration logic
- 2740. By Laurens Van Houtven
-
Actually use the install class. Oops.
Laurens Van Houtven (lvh) wrote : | # |
My bad. I've fixed it in the current version.
pip installs into new virtualenvs appear to work fine, now. I'm 100% sure the _regenerateCache function is being called (I know because I put a raise statement in there).
I'm trying now, rebuilding *all* the virtualenvs to make sure it's not a spuriour success due to a stale install of Axiom somewhere.
Laurens Van Houtven (lvh) wrote : | # |
(tox -r succeeded too.)
- 2741. By Laurens Van Houtven
-
setup.py doesn't actually rely on the strip or triple-quoting anymore
- 2742. By Laurens Van Houtven
-
Add PyOpenSSL to install_requires
- 2743. By Laurens Van Houtven
-
Add note to eventually remove PyOpenSSL from install_requires
Preview Diff
1 | === added file 'Axiom/.coveragerc' |
2 | --- Axiom/.coveragerc 1970-01-01 00:00:00 +0000 |
3 | +++ Axiom/.coveragerc 2013-10-14 15:41:13 +0000 |
4 | @@ -0,0 +1,8 @@ |
5 | +[run] |
6 | +branch = True |
7 | +source = |
8 | + axiom |
9 | + |
10 | +[report] |
11 | +exclude_lines = |
12 | + pragma: no cover |
13 | |
14 | === modified file 'Axiom/axiom/__init__.py' |
15 | --- Axiom/axiom/__init__.py 2008-03-09 21:03:23 +0000 |
16 | +++ Axiom/axiom/__init__.py 2013-10-14 15:41:13 +0000 |
17 | @@ -1,5 +1,8 @@ |
18 | # -*- test-case-name: axiom.test -*- |
19 | - |
20 | -from axiom._version import version |
21 | -version # tell pyflakes we're exporting it. |
22 | - |
23 | +from twisted.python import versions |
24 | +from axiom._version import __version__ |
25 | + |
26 | +def _asTwistedVersion(packageName, versionString): |
27 | + return versions.Version(packageName, *map(int, versionString.split("."))) |
28 | + |
29 | +version = _asTwistedVersion("axiom", __version__) |
30 | |
31 | === modified file 'Axiom/axiom/_version.py' |
32 | --- Axiom/axiom/_version.py 2009-11-30 01:08:55 +0000 |
33 | +++ Axiom/axiom/_version.py 2013-10-14 15:41:13 +0000 |
34 | @@ -1,3 +1,1 @@ |
35 | -# This is an auto-generated file. Use Epsilon/bin/release-divmod to update. |
36 | -from twisted.python import versions |
37 | -version = versions.Version(__name__[:__name__.rfind('.')], 0, 6, 0) |
38 | +__version__ = "0.6.0" |
39 | |
40 | === added file 'Axiom/requirements-testing.txt' |
41 | --- Axiom/requirements-testing.txt 1970-01-01 00:00:00 +0000 |
42 | +++ Axiom/requirements-testing.txt 2013-10-14 15:41:13 +0000 |
43 | @@ -0,0 +1,2 @@ |
44 | +# Requirements for running the test suite using tox |
45 | +coverage |
46 | |
47 | === renamed file 'Axiom/DEPS.txt' => 'Axiom/requirements.txt' |
48 | --- Axiom/DEPS.txt 2006-06-14 11:54:41 +0000 |
49 | +++ Axiom/requirements.txt 2013-10-14 15:41:13 +0000 |
50 | @@ -1,7 +1,5 @@ |
51 | -Python 2.4 |
52 | -SQLite 3.2.1 |
53 | -Twisted 2.4.0 |
54 | -PySQLite 2.0 |
55 | -NPTL 2.3.5 or later (LinuxThreads not supported: see |
56 | - <http://twistedmatrix.com/bugs/issue1251>) |
57 | -Epsilon 0.5.0 |
58 | +Twisted>=13.1.0 |
59 | +Epsilon>=0.6.0 |
60 | +PyOpenSSL>=0.13 # epsilon.juice depends on this |
61 | +# You may also optionally install pysqlite2. If you don't, the stdlib |
62 | +# sqlite module will be used. |
63 | |
64 | === modified file 'Axiom/setup.py' |
65 | --- Axiom/setup.py 2009-11-30 01:08:55 +0000 |
66 | +++ Axiom/setup.py 2013-10-14 15:41:13 +0000 |
67 | @@ -1,23 +1,59 @@ |
68 | -from epsilon.setuphelper import autosetup |
69 | - |
70 | -import axiom |
71 | - |
72 | -distobj = autosetup( |
73 | +from setuptools import setup, find_packages |
74 | +from setuptools.command.install import install as Install |
75 | +import re |
76 | + |
77 | +versionPattern = re.compile(r"""^__version__ = ['"](.*?)['"]$""", re.M) |
78 | +with open("axiom/_version.py", "rt") as f: |
79 | + version = versionPattern.search(f.read()).group(1) |
80 | + |
81 | + |
82 | + |
83 | +class InstallAndRegenerate(Install): |
84 | + def run(self): |
85 | + """ |
86 | + Runs the usual install logic, then regenerates the plugin cache. |
87 | + """ |
88 | + Install.run(self) |
89 | + _regenerateCache() |
90 | + |
91 | + |
92 | + |
93 | +def _regenerateCache(): |
94 | + from twisted import plugin |
95 | + from axiom import plugins |
96 | + list(plugin.getPlugins(plugin.IPlugin)) # Twisted |
97 | + list(plugin.getPlugins(plugin.IPlugin, plugins)) # Axiom |
98 | + |
99 | + |
100 | +setup( |
101 | name="Axiom", |
102 | - version=axiom.version.short(), |
103 | + version=version, |
104 | + description="An in-process object-relational database", |
105 | + url="https://launchpad.net/divmod.org", |
106 | + |
107 | maintainer="Divmod, Inc.", |
108 | maintainer_email="support@divmod.org", |
109 | - url="http://divmod.org/trac/wiki/DivmodAxiom", |
110 | + |
111 | + install_requires=["twisted", "epsilon", "PyOpenSSL"], |
112 | + # XXX: Remove PyOpenSSL install_requires as soon as epsilon |
113 | + # specifies this dependency |
114 | + packages=find_packages() + ['twisted.plugins'], |
115 | + scripts=['bin/axiomatic'], |
116 | + cmdclass={ |
117 | + "install": InstallAndRegenerate, |
118 | + }, |
119 | + |
120 | license="MIT", |
121 | platforms=["any"], |
122 | - description="An in-process object-relational database", |
123 | + |
124 | classifiers=[ |
125 | "Development Status :: 5 - Production/Stable", |
126 | "Framework :: Twisted", |
127 | "Intended Audience :: Developers", |
128 | "License :: OSI Approved :: MIT License", |
129 | "Programming Language :: Python", |
130 | - "Topic :: Database"], |
131 | - |
132 | - scripts=['bin/axiomatic']) |
133 | - |
134 | + "Programming Language :: Python :: 2", |
135 | + "Programming Language :: Python :: 2.6", |
136 | + "Programming Language :: Python :: 2.7", |
137 | + "Programming Language :: Python :: 2 :: Only", |
138 | + "Topic :: Database"]) |
139 | |
140 | === added file 'Axiom/tox.ini' |
141 | --- Axiom/tox.ini 1970-01-01 00:00:00 +0000 |
142 | +++ Axiom/tox.ini 2013-10-14 15:41:13 +0000 |
143 | @@ -0,0 +1,24 @@ |
144 | +[tox] |
145 | +envlist = py26,py27,py26-trunkdeps,py27-trunkdeps |
146 | + |
147 | +[testenv] |
148 | +deps = |
149 | + Twisted |
150 | +commands = |
151 | + pip install \ |
152 | + -r {toxinidir}/requirements.txt \ |
153 | + -r {toxinidir}/requirements-testing.txt |
154 | + coverage run {envdir}/bin/trial \ |
155 | + --temp-directory={envdir}/_trial {posargs:axiom} |
156 | + coverage report --show-missing |
157 | + coverage html --directory {envdir}/_coverage |
158 | + |
159 | +[testenv:py26-trunkdeps] |
160 | +basepython = python2.6 |
161 | +deps = |
162 | + --editable=svn+svn://svn.twistedmatrix.com/svn/Twisted/trunk |
163 | + |
164 | +[testenv:py27-trunkdeps] |
165 | +basepython = python2.7 |
166 | +deps = |
167 | + --editable=svn+svn://svn.twistedmatrix.com/svn/Twisted/trunk |
Also, Axiom's version is now also available as __version__. This appears to be the more common place to specify the version. axiom.version still works, so this is not a backwards incompatible change. I still need to write a test to check that the two are identical, but I'm not sure where to put it: test_listversions seems the closest one, but not exactly a match :)