Merge lp:~cjwatson/launchpadlib/py38-access-token into lp:launchpadlib

Proposed by Colin Watson on 2020-02-04
Status: Merged
Merged at revision: 176
Proposed branch: lp:~cjwatson/launchpadlib/py38-access-token
Merge into: lp:launchpadlib
Diff against target: 86 lines (+27/-2)
4 files modified
NEWS.rst (+4/-0)
setup.py (+1/-0)
src/launchpadlib/credentials.py (+3/-2)
src/launchpadlib/tests/test_credential_store.py (+19/-0)
To merge this branch: bzr merge lp:~cjwatson/launchpadlib/py38-access-token
Reviewer Review Type Date Requested Status
Tom Wardill 2020-02-04 Approve on 2020-02-04
Review via email: mp+378523@code.launchpad.net

Commit message

Fix AccessToken.from_string crash on Python 3.8.

To post a comment you must log in.
Tom Wardill (twom) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS.rst'
2--- NEWS.rst 2019-11-28 00:07:07 +0000
3+++ NEWS.rst 2020-02-04 14:29:20 +0000
4@@ -2,6 +2,10 @@
5 NEWS for launchpadlib
6 =====================
7
8+1.10.10
9+=======
10+- Fix AccessToken.from_string crash on Python 3.8. [bug=1861873]
11+
12 1.10.9 (2019-11-28)
13 ===================
14 - Explicitly install version.txt; launchpadlib requires it.
15
16=== modified file 'setup.py'
17--- setup.py 2019-11-27 19:40:17 +0000
18+++ setup.py 2020-02-04 14:29:20 +0000
19@@ -47,6 +47,7 @@
20 'lazr.restfulclient>=0.9.19',
21 'lazr.uri',
22 'setuptools',
23+ 'six',
24 'testresources',
25 'wadllib',
26 ]
27
28=== modified file 'src/launchpadlib/credentials.py'
29--- src/launchpadlib/credentials.py 2018-03-07 10:42:12 +0000
30+++ src/launchpadlib/credentials.py 2020-02-04 14:29:20 +0000
31@@ -29,7 +29,6 @@
32 'Credentials',
33 ]
34
35-import cgi
36 try:
37 from cStringIO import StringIO
38 except ImportError:
39@@ -60,6 +59,8 @@
40 except ImportError:
41 import simplejson as json
42
43+from six.moves.urllib.parse import parse_qs
44+
45 if bytes is str:
46 # Python 2
47 unicode_type = unicode
48@@ -248,7 +249,7 @@
49 """Create and return a new `AccessToken` from the given string."""
50 if not isinstance(query_string, unicode_type):
51 query_string = query_string.decode('utf-8')
52- params = cgi.parse_qs(query_string, keep_blank_values=False)
53+ params = parse_qs(query_string, keep_blank_values=False)
54 key = params['oauth_token']
55 assert len(key) == 1, (
56 "Query string must have exactly one oauth_token.")
57
58=== modified file 'src/launchpadlib/tests/test_credential_store.py'
59--- src/launchpadlib/tests/test_credential_store.py 2014-07-14 20:29:51 +0000
60+++ src/launchpadlib/tests/test_credential_store.py 2020-02-04 14:29:20 +0000
61@@ -41,6 +41,25 @@
62 )
63
64
65+class TestAccessToken(unittest.TestCase):
66+ """Tests for the AccessToken class."""
67+
68+ def test_from_string(self):
69+ access_token = AccessToken.from_string(
70+ "oauth_token_secret=secret%3Dpassword&oauth_token=lock%26key")
71+ self.assertEqual("lock&key", access_token.key)
72+ self.assertEqual("secret=password", access_token.secret)
73+ self.assertIsNone(access_token.context)
74+
75+ def test_from_string_with_context(self):
76+ access_token = AccessToken.from_string(
77+ "oauth_token_secret=secret%3Dpassword&oauth_token=lock%26key&"
78+ "lp.context=firefox")
79+ self.assertEqual("lock&key", access_token.key)
80+ self.assertEqual("secret=password", access_token.secret)
81+ self.assertEqual("firefox", access_token.context)
82+
83+
84 class CredentialStoreTestCase(unittest.TestCase):
85
86 def make_credential(self, consumer_key):

Subscribers

People subscribed via source and target branches