Merge lp:~leonardr/launchpadlib/avoid-beta-beta into lp:launchpadlib

Proposed by Leonard Richardson
Status: Merged
Merged at revision: not available
Proposed branch: lp:~leonardr/launchpadlib/avoid-beta-beta
Merge into: lp:launchpadlib
Diff against target: 89 lines (+58/-0)
3 files modified
src/launchpadlib/NEWS.txt (+5/-0)
src/launchpadlib/launchpad.py (+9/-0)
src/launchpadlib/tests/test_launchpad.py (+44/-0)
To merge this branch: bzr merge lp:~leonardr/launchpadlib/avoid-beta-beta
Reviewer Review Type Date Requested Status
Paul Hummer (community) code Approve
Review via email: mp+20689@code.launchpad.net

Description of the change

Old versions of launchpadlib took a service root URI argument, and the service URI included "/beta/" at the end. Then we introduced multi-version code, and there was a separate argument for the version, which gets stuck on to the end of the service URI.

Third-party code that used the constants in launchpadlib.uris are safe. But some code didn't use those constants: it hard-coded the URI service root in a string. That code is now going to be making HTTP requests to http://api.launchpad.net/beta/beta/, and getting an unhelpful 404 error.

This branch adds a check to the Launchpad constructor that will catch code like this and complain with a helpful exception. I originally thought I could silently fix this, but the fix would only work so long as the default web service version was 'beta', which won't be much longer. Better to get the problem fixed now.

I'm uncertain about the best way to write a unit test for the message contained in an exception. I think the way I did it is a little hacky. Let me know if there's a better way.

To post a comment you must log in.
Revision history for this message
Paul Hummer (rockstar) wrote :

Ah! Looks like I've got some code to change... :)

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/launchpadlib/NEWS.txt'
2--- src/launchpadlib/NEWS.txt 2010-03-04 15:39:21 +0000
3+++ src/launchpadlib/NEWS.txt 2010-03-04 19:37:14 +0000
4@@ -8,6 +8,11 @@
5 - Fixed a minor bug when using login_with() to access a version of the
6 Launchpad web service other than the default.
7
8+- Added a check to catch old client code that would cause newer
9+ versions of launchpadlib to make nonsensical requests to
10+ https://api.launchpad.dev/beta/beta/, and raise a helpful exception
11+ telling the developer how to fix it.
12+
13 1.5.5
14 =====
15
16
17=== modified file 'src/launchpadlib/launchpad.py'
18--- src/launchpadlib/launchpad.py 2010-03-04 15:08:07 +0000
19+++ src/launchpadlib/launchpad.py 2010-03-04 19:37:14 +0000
20@@ -96,6 +96,15 @@
21 :type service_root: string
22 """
23 service_root = uris.lookup_service_root(service_root)
24+ if (service_root.endswith(version)
25+ or service_root.endswith(version + '/')):
26+ error = ("It looks like you're using a service root that "
27+ "incorporates the name of the web service version "
28+ '("%s"). Please use one of the constants from '
29+ "launchpadlib.uris instead, or at least remove "
30+ "the version name from the root URI." % version)
31+ raise ValueError(error)
32+
33 super(Launchpad, self).__init__(
34 credentials, service_root, cache, timeout, proxy_info, version)
35
36
37=== modified file 'src/launchpadlib/tests/test_launchpad.py'
38--- src/launchpadlib/tests/test_launchpad.py 2010-03-04 15:39:21 +0000
39+++ src/launchpadlib/tests/test_launchpad.py 2010-03-04 19:37:14 +0000
40@@ -92,6 +92,50 @@
41 self.assertRaises(ValueError, uris.lookup_service_root, not_a_url)
42 self.assertRaises(ValueError, uris.lookup_web_root, not_a_url)
43
44+
45+class TestServiceNameWithEmbeddedVersion(unittest.TestCase):
46+ """Reject service roots that include the version at the end of the URL.
47+
48+ If the service root is "http://api.launchpad.net/beta/" and the
49+ version is "beta", the launchpadlib constructor will raise an
50+ exception.
51+
52+ This happens with scripts that were written against old versions
53+ of launchpadlib. The alternative is to try to silently fix it (the
54+ fix will eventually break as new versions of the web service are
55+ released) or to go ahead and make a request to
56+ http://api.launchpad.net/beta/beta/, and cause an unhelpful 404
57+ error.
58+ """
59+
60+ def test_service_name_with_embedded_version(self):
61+ # Basic test. If there were no exception raised here,
62+ # launchpadlib would make a request to
63+ # /version-foo/version-foo.
64+ version = "version-foo"
65+ root = uris.service_roots['staging'] + version
66+ try:
67+ Launchpad(None, root, version=version)
68+ except ValueError, e:
69+ self.assertTrue(str(e).startswith(
70+ "It looks like you're using a service root that incorporates "
71+ 'the name of the web service version ("version-foo")'))
72+ else:
73+ raise AssertionError(
74+ "Expected a ValueError that was not thrown!")
75+
76+ # Make sure the problematic URL is caught even if it has a
77+ # slash on the end.
78+ root += '/'
79+ self.assertRaises(ValueError, Launchpad, None, root, version=version)
80+
81+ # Test that the default version has the same problem
82+ # when no explicit version is specified
83+ default_version = NoNetworkLaunchpad.DEFAULT_VERSION
84+ root = uris.service_roots['staging'] + default_version + '/'
85+ self.assertRaises(ValueError, Launchpad, None, root)
86+
87+
88 class TestLaunchpadLoginWith(unittest.TestCase):
89 """Tests for Launchpad.login_with()."""
90

Subscribers

People subscribed via source and target branches