From 6df986ed1e36232fd2d7a31a15dd8c6b04d33b0e Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 11 Jun 2011 09:49:40 +0100 Subject: [PATCH 001/110] Added commit properties tests. --- tests/test_commits.py | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/tests/test_commits.py b/tests/test_commits.py index 38b2055..90a4cde 100644 --- a/tests/test_commits.py +++ b/tests/test_commits.py @@ -1,16 +1,39 @@ import _setup +from datetime import datetime + from nose.tools import assert_equals import utils -class Commit(utils.HttpMockTestCase): +class CommitProperties(utils.HttpMockTestCase): + """Test commit property handling""" + commit_id = '1c83cde9b5a7c396a01af1007fb7b88765b9ae45' + def test_commit(self): + commit = self.client.commits.show('ask/python-github2', self.commit_id) + assert_equals(commit.message, + 'Added cache support to manage_collaborators.') + assert_equals(commit.parents, + [{"id": '7d1c855d2f44a55e4b90b40017be697cf70cb4a0'}]) + assert_equals(commit.url, + '/ask/python-github2/commit/%s' % self.commit_id) + assert_equals(commit.author['login'], 'JNRowe') + assert_equals(commit.id, self.commit_id) + assert_equals(commit.committed_date, + datetime(2011, 6, 6, 16, 13, 50)) + assert_equals(commit.authored_date, datetime(2011, 6, 6, 16, 13, 50)) + assert_equals(commit.tree, 'f48fcc1a0b8ea97f3147dc42cf7cdb6683493e94') + assert_equals(commit.committer['login'], 'JNRowe') + assert_equals(commit.added, None) + assert_equals(commit.removed, None) + assert_equals(commit.modified[0]['filename'], 'github2/bin/manage_collaborators.py') + + def test_repr(self): - commit_id = '1c83cde9b5a7c396a01af1007fb7b88765b9ae45' - commit = self.client.commits.show('ask/python-github2', commit_id) + commit = self.client.commits.show('ask/python-github2', self.commit_id) assert_equals(repr(commit), - '' % commit_id[:8]) + '' % self.commit_id[:8]) class CommitsQueries(utils.HttpMockTestCase): From 0a3c36fdcdc3323603b84c979d47602cd8da3c03 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 11 Jun 2011 09:59:47 +0100 Subject: [PATCH 002/110] Added issue/comment properties tests. --- tests/test_issues.py | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/tests/test_issues.py b/tests/test_issues.py index 72988f3..377412e 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -1,16 +1,49 @@ import _setup +from datetime import datetime + from nose.tools import assert_equals import utils -class ReprTests(utils.HttpMockTestCase): +class Issue(utils.HttpMockTestCase): + def test_properties(self): + issue = self.client.issues.show('ask/python-github2', 24) + assert_equals(issue.position, 24.0) + assert_equals(issue.number, 24) + assert_equals(issue.votes, 0) + assert_equals(len(issue.body), 164) + assert_equals(issue.title, 'Pagination support for commits.') + assert_equals(issue.user, 'svetlyak40wt') + assert_equals(issue.state, 'open') + assert_equals(issue.labels, []) + assert_equals(issue.created_at, datetime(2010, 12, 8, 23, 50, 26)) + assert_equals(issue.closed_at, None) + assert_equals(issue.updated_at, datetime(2011, 1, 4, 16, 26, 7)) + assert_equals(issue.diff_url, + 'https://github.com/ask/python-github2/pull/24.diff') + assert_equals(issue.patch_url, + 'https://github.com/ask/python-github2/pull/24.patch') + assert_equals(issue.pull_request_url, + 'https://github.com/ask/python-github2/pull/24') + def test_issue_repr(self): issue = self.client.issues.show('ask/python-github2', 24) assert_equals(repr(issue), '') - + + +class Comment(utils.HttpMockTestCase): + def test_properties(self): + comments = self.client.issues.comments('ask/python-github2', 24) + comment = comments[0] + assert_equals(comment.created_at, datetime(2010, 12, 9, 22, 37, 26)) + assert_equals(comment.updated_at, datetime(2010, 12, 9, 22, 37, 26)) + assert_equals(len(comment.body), 267) + assert_equals(comment.id, 601871) + assert_equals(comment.user, 'nvie') + def test_comment_repr(self): comments = self.client.issues.comments('ask/python-github2', 24) assert_equals(repr(comments[1]), From bca4787cbbfd3cdc9695e32e5d67768b1fc52af3 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 11 Jun 2011 10:56:42 +0100 Subject: [PATCH 003/110] Added test for list_by_label Issues method. --- ...ay,label,bug,79a89664a2d4783ee9089d29f99b660e | 16 ++++++++++++++++ tests/test_issues.py | 5 +++++ 2 files changed, 21 insertions(+) create mode 100644 tests/data/github.com,api,v2,json,issues,list,JNRowe,misc-overlay,label,bug,79a89664a2d4783ee9089d29f99b660e diff --git a/tests/data/github.com,api,v2,json,issues,list,JNRowe,misc-overlay,label,bug,79a89664a2d4783ee9089d29f99b660e b/tests/data/github.com,api,v2,json,issues,list,JNRowe,misc-overlay,label,bug,79a89664a2d4783ee9089d29f99b660e new file mode 100644 index 0000000..e865e18 --- /dev/null +++ b/tests/data/github.com,api,v2,json,issues,list,JNRowe,misc-overlay,label,bug,79a89664a2d4783ee9089d29f99b660e @@ -0,0 +1,16 @@ +status: 200 +x-ratelimit-remaining: 59 +content-location: https://github.com/api/v2/json/issues/list/JNRowe/misc-overlay/label/bug +connection: keep-alive +x-next: https://github.com/api/v2/json/issues/list/JNRowe/misc-overlay/label/bug?page=2 +content-length: 15566 +server: nginx/0.7.67 +date: Wed, 08 Jun 2011 13:42:00 GMT +x-runtime: 138ms +x-ratelimit-limit: 60 +etag: "f625ba2e14adae8f3b8960c00d60e9eb" +cache-control: private, max-age=0, must-revalidate +x-last: https://github.com/api/v2/json/issues/list/JNRowe/misc-overlay/label/bug?page=2 +content-type: application/json; charset=utf-8 + +{"issues":[{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":1.0,"number":3,"votes":0,"created_at":"2010/09/14 17:51:13 -0700","comments":1,"body":"\n---\n`ditz-id`: `05d00a48cdce80119a2b26f7c6f0e25894ff8537`\n\n`ditz-event-time`: `2010-03-04T19:21:01.799951Z`","title":"app-text/gist file locations have changed in git repo.","updated_at":"2010/09/14 17:51:17 -0700","closed_at":"2010/09/14 17:51:17 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/3","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":4.0,"number":9,"votes":0,"created_at":"2010/09/14 17:52:17 -0700","comments":1,"body":"\n---\n`ditz-id`: `0fdb57d80db65f2370811df882adbc8e958e5d8a`\n\n`ditz-event-time`: `2009-12-21T17:53:02.947952Z`","title":"fossil uses internal copy of sqlite.","updated_at":"2010/09/14 17:52:21 -0700","closed_at":"2010/09/14 17:52:21 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/9","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":6.0,"number":11,"votes":0,"created_at":"2010/09/14 17:52:40 -0700","comments":1,"body":"\n---\n`ditz-id`: `137ec0032fe83918fd0570e125dc1f2991a37676`\n\n`ditz-event-time`: `2010-03-04T19:37:23.671948Z`","title":"dev-python/pycukes fails with recent distutills.eclass changes.","updated_at":"2010/09/14 17:52:44 -0700","closed_at":"2010/09/14 17:52:44 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/11","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":19.0,"number":24,"votes":0,"created_at":"2010/09/14 17:54:52 -0700","comments":1,"body":"\n---\n`ditz-id`: `2ca7641993a1f7a1a8cb7ab01d5cde6b874e118a`\n\n`ditz-event-time`: `2009-12-14T10:32:37.855964Z`","title":"app-text/apvlv-0.0.8.1 has automagic djvu dependency.","updated_at":"2010/09/14 17:54:57 -0700","closed_at":"2010/09/14 17:54:57 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/24","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":24.0,"number":29,"votes":0,"created_at":"2010/09/14 17:55:30 -0700","comments":2,"body":"Reported by Dennis Bruce.\n\n---\n`ditz-id`: `32197e2725b7a973e0a66f3ecaf0efbbfb966c1e`\n\n`ditz-event-time`: `2010-03-04T17:43:17.471958Z`","title":"dev-util/ccontrol fails in src_test.","updated_at":"2010/09/14 17:55:35 -0700","closed_at":"2010/09/14 17:55:35 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/29","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":25.0,"number":30,"votes":0,"created_at":"2010/09/14 17:55:37 -0700","comments":1,"body":"\n---\n`ditz-id`: `337caa2e1f972335878906cc1fbfd6091a96d633`\n\n`ditz-event-time`: `2010-03-05T21:27:08.459986Z`","title":"python.eclass changes emit warnings with jnrowe-pypi:module_script_wrapper().","updated_at":"2010/09/14 17:55:46 -0700","closed_at":"2010/09/14 17:55:46 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/30","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":28.0,"number":33,"votes":0,"created_at":"2010/09/14 17:55:59 -0700","comments":1,"body":"\n---\n`ditz-id`: `35cca70ded236159c5a3a18bf816c2af345bc811`\n\n`ditz-event-time`: `2010-07-05T17:16:15.503883Z`","title":"dev-libs/ctpl cupage check blocked by robots.txt.","updated_at":"2010/09/14 17:56:03 -0700","closed_at":"2010/09/14 17:56:03 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/33","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":29.0,"number":34,"votes":0,"created_at":"2010/09/14 17:56:06 -0700","comments":1,"body":"\n---\n`ditz-id`: `362778bbc4dd3a91ab4149f33868039c75ccc7d6`\n\n`ditz-event-time`: `2010-02-14T07:36:28.091756Z`","title":"dev-python/html doesn't work with Python 2.4.","updated_at":"2010/09/14 17:56:10 -0700","closed_at":"2010/09/14 17:56:10 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/34","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":33.0,"number":38,"votes":0,"created_at":"2010/09/14 17:56:28 -0700","comments":1,"body":"\n---\n`ditz-id`: `3a12af55a7e27b7a87cf0432c7285e4e32ace4fe`\n\n`ditz-event-time`: `2009-12-06T06:21:55.723974Z`","title":"Invalid man page install path in apvlv.","updated_at":"2010/09/14 17:56:38 -0700","closed_at":"2010/09/14 17:56:38 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/38","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":34.0,"number":39,"votes":0,"created_at":"2010/09/14 17:56:44 -0700","comments":1,"body":"\n---\n`ditz-id`: `3a3471c3a9218713445122c21458c5d7f1b72e30`\n\n`ditz-event-time`: `2010-03-04T17:44:37.431956Z`","title":"dev-util/gitserve fails with recent distutills.eclass changes.","updated_at":"2010/09/14 17:56:49 -0700","closed_at":"2010/09/14 17:56:49 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/39","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":35.0,"number":40,"votes":0,"created_at":"2010/09/14 17:56:51 -0700","comments":1,"body":"The download page has changed layout.\n\n---\n`ditz-id`: `408d842ddd5caef873f5bedcaf4e71cee992d058`\n\n`ditz-event-time`: `2009-12-31T03:25:36.464053Z`","title":"matwm2 cupage entry broken.","updated_at":"2010/09/14 17:56:56 -0700","closed_at":"2010/09/14 17:56:56 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/40","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":40.0,"number":45,"votes":0,"created_at":"2010/09/14 17:57:35 -0700","comments":1,"body":"- /usr/share/doc/apvlv-0.0.7.4/reg.png - /usr/share/doc/apvlv-0.0.7.4/dir.png - /usr/share/doc/apvlv-0.0.7.4/pdf.png\n\n---\n`ditz-id`: `48578b8bac650dad93271d2880de33140768b4f0`\n\n`ditz-event-time`: `2009-11-14T06:53:02.847996Z`","title":"apvlv stores datafiles in docdir.","updated_at":"2010/09/14 17:57:39 -0700","closed_at":"2010/09/14 17:57:39 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/45","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":49.0,"number":54,"votes":0,"created_at":"2010/09/14 17:59:00 -0700","comments":1,"body":"Some of the plugins reference the build system's default document path, which is overridden at install time. This isn't just cosmetic, it breaks help functionality in the interface.\n\n---\n`ditz-id`: `54418badf2a50f642b919f458dd561e559083e7b`\n\n`ditz-event-time`: `2010-06-20T12:35:08.378462Z`","title":"Invalid doc path used in geany-plugins-0.19.","updated_at":"2010/09/14 17:59:10 -0700","closed_at":"2010/09/14 17:59:10 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/54","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":81.0,"number":86,"votes":0,"created_at":"2010/09/14 18:08:09 -0700","comments":1,"body":"ebuild and cupage entry need updating.\n\n---\n`ditz-id`: `81ea1ed5020396c7114643281ad2bf554133f9d6`\n\n`ditz-event-time`: `2009-11-16T05:25:05.255933Z`","title":"x11-wm/parti has moved to Google's code hosting.","updated_at":"2010/09/14 18:08:13 -0700","closed_at":"2010/09/14 18:08:13 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/86","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":97.0,"number":102,"votes":0,"created_at":"2010/09/14 18:11:24 -0700","comments":6,"body":"\n---\n`ditz-id`: `971e2fc2ad70b118b79adfe1a3745e5c551932bf`\n\n`ditz-event-time`: `2009-11-12T04:40:21.007927Z`","title":"Packages missing cupage config entries.","updated_at":"2010/09/14 18:11:37 -0700","closed_at":"2010/09/14 18:11:37 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/102","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":113.0,"number":118,"votes":0,"created_at":"2010/09/14 18:13:58 -0700","comments":1,"body":"\n---\n`ditz-id`: `a7598bb237c7bb2c402c4ff4c6a4e59d543e998f`\n\n`ditz-event-time`: `2010-03-04T19:17:31.451916Z`","title":"dev-python/restview fails with recent distutills.eclass changes.","updated_at":"2010/09/14 18:14:02 -0700","closed_at":"2010/09/14 18:14:02 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/118","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":117.0,"number":122,"votes":0,"created_at":"2010/09/14 18:14:23 -0700","comments":1,"body":"\n---\n`ditz-id`: `afa05d6a5f6ccdebcdaebec759d408d61888e729`\n\n`ditz-event-time`: `2010-07-05T17:21:11.219887Z`","title":"www-client/opera-remote cupage check blocked by robots.txt.","updated_at":"2010/09/14 18:14:28 -0700","closed_at":"2010/09/14 18:14:28 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/122","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":122.0,"number":127,"votes":0,"created_at":"2010/09/14 18:15:29 -0700","comments":1,"body":"\n---\n`ditz-id`: `b48295c6d581976a0c95f26c2190865c493fc081`\n\n`ditz-event-time`: `2010-07-05T17:17:40.083880Z`","title":"dev-libs/luaposix cupage check blocked by robots.txt.","updated_at":"2010/09/14 18:15:39 -0700","closed_at":"2010/09/14 18:15:39 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/127","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":0.0,"number":141,"votes":0,"created_at":"2010/09/14 18:17:45 -0700","comments":3,"body":"\n---\n`ditz-id`: `c8d8078898af58f80139f986306433a4c4efd397`\n\n`ditz-event-time`: `2010-07-05T17:23:22.063887Z`","title":"media-gfx/psplash cupage check raises 403.","updated_at":"2011/02/25 22:13:20 -0800","closed_at":"2011/02/25 22:13:20 -0800","html_url":"https://github.com/JNRowe/misc-overlay/issues/141","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":150.0,"number":155,"votes":0,"created_at":"2010/09/14 18:20:01 -0700","comments":1,"body":"Uses incorrect path.\n\n---\n`ditz-id`: `d3ba89ca556458709fe431eb3ad43989722cf274`\n\n`ditz-event-time`: `2010-06-22T18:17:54.823885Z`","title":"net-misc/bleeter-0.5.0 manpage generation broken.","updated_at":"2010/09/14 18:20:12 -0700","closed_at":"2010/09/14 18:20:12 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/155","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":166.0,"number":171,"votes":0,"created_at":"2010/09/14 18:22:48 -0700","comments":1,"body":"\n---\n`ditz-id`: `f86c46636c26fd30d5d812fc207a8ea9107c7bdc`\n\n`ditz-event-time`: `2009-12-13T11:35:43.211823Z`","title":"taskwarrior overrides user CFLAGS settings.","updated_at":"2010/09/14 18:22:53 -0700","closed_at":"2010/09/14 18:22:53 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/171","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":11.0,"number":199,"votes":0,"created_at":"2010/10/07 18:17:27 -0700","comments":2,"body":"This pypi entry seems to have been deleted. Leave this bug open for a few weeks to see if it is re-added, if not look for alternatives.","title":"dev-python/termstyle cupage check raises 404.","updated_at":"2010/11/05 05:53:12 -0700","closed_at":"2010/11/05 05:53:12 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/199","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":177.0,"number":200,"votes":0,"created_at":"2010/10/08 04:06:56 -0700","comments":1,"body":"Thanks to Daniel Brew for reporting.","title":"media-gfx/sng won't build with libpng-1.4.","updated_at":"2010/10/08 04:33:06 -0700","closed_at":"2010/10/08 04:33:06 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/200","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":18.0,"number":258,"votes":0,"created_at":"2011/01/09 22:53:39 -0800","comments":2,"body":"Recent sourceforge changes have broken matcher.","title":"sci-geosciences/gpsfeed cupage check fails.","updated_at":"2011/01/10 23:47:24 -0800","closed_at":"2011/01/10 23:47:24 -0800","html_url":"https://github.com/JNRowe/misc-overlay/issues/258","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":19.0,"number":259,"votes":0,"created_at":"2011/01/09 23:02:37 -0800","comments":2,"body":"Recent sourceforge changes have broken matcher.","title":"media-gfx/sng cupage check fails.","updated_at":"2011/01/10 22:04:52 -0800","closed_at":"2011/01/10 22:04:52 -0800","html_url":"https://github.com/JNRowe/misc-overlay/issues/259","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":20.0,"number":261,"votes":0,"created_at":"2011/01/09 23:04:31 -0800","comments":2,"body":"Recent sourceforge changes have broken matcher.","title":"dev-tcltk/tcludp cupage check fails.","updated_at":"2011/01/10 22:04:52 -0800","closed_at":"2011/01/10 22:04:52 -0800","html_url":"https://github.com/JNRowe/misc-overlay/issues/261","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":6.0,"number":262,"votes":0,"created_at":"2011/01/09 23:44:53 -0800","comments":2,"body":"If `USE=!examples` the links in the documentation will be broken.\r\n\r\nThis obviously also applies to `mail-filter/maildirproc-python2`.","title":"mail-filter/maildirproc documentation should link to upstream for examples","updated_at":"2011/01/10 23:47:24 -0800","closed_at":"2011/01/10 23:47:24 -0800","html_url":"https://github.com/JNRowe/misc-overlay/issues/262","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":0.0,"number":284,"votes":0,"created_at":"2011/02/14 03:00:42 -0800","comments":2,"body":"Upstream appears to have redesigned their site, so the cupage check needs updating.","title":"dev-python/texttable cupage check raises 404.","updated_at":"2011/02/15 05:54:47 -0800","closed_at":"2011/02/15 05:54:47 -0800","html_url":"https://github.com/JNRowe/misc-overlay/issues/284","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":9.0,"number":327,"votes":0,"created_at":"2011/04/04 21:42:38 -0700","comments":1,"body":"Appears to have switched to PyPI for listings.","title":"dev-python/feedcache cupage entry broken.","updated_at":"2011/04/05 03:59:24 -0700","closed_at":"2011/04/05 03:59:24 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/327","user":"JNRowe","labels":["bug"],"state":"closed"},{"gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","position":10.0,"number":328,"votes":0,"created_at":"2011/04/04 21:44:12 -0700","comments":1,"body":"Files have been repackaged and renamed.","title":"app-misc/libeatmydata cupage entry broken.","updated_at":"2011/04/05 03:59:24 -0700","closed_at":"2011/04/05 03:59:24 -0700","html_url":"https://github.com/JNRowe/misc-overlay/issues/328","user":"JNRowe","labels":["bug"],"state":"closed"}]} \ No newline at end of file diff --git a/tests/test_issues.py b/tests/test_issues.py index 72988f3..166e592 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -38,3 +38,8 @@ def test_issue_labels(self): labels = self.client.issues.list_labels('JNRowe/misc-overlay') assert_equals(len(labels), 3) assert_equals(labels[0], 'feature') + + def test_list_by_label(self): + issues = self.client.issues.list_by_label('JNRowe/misc-overlay', 'bug') + assert_equals(len(issues), 30) + assert_equals(issues[-1].number, 328) From cfa7a543bcee2ab63619fea99bd40ffa8084eb3e Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 11 Jun 2011 10:58:09 +0100 Subject: [PATCH 004/110] Added more repository querying tests. --- ...languages,941f2fae40c32a86b82f8e51a623cacd | 14 +++++++++++ ...,branches,2be8c8f036124b61fbddeecbbdf28e9c | 14 +++++++++++ ...aborators,855cea60d613a363106762311e6f53ea | 14 +++++++++++ ...hub2,tags,e7b38a20b45dffd2a22d34b5b51f41da | 14 +++++++++++ ...,watchers,8f4f641783ac93b3f5d7507bc65cf925 | 14 +++++++++++ tests/test_repositories.py | 25 +++++++++++++++++++ 6 files changed, 95 insertions(+) create mode 100644 tests/data/github.com,api,v2,json,repos,show,JNRowe,misc-overlay,languages,941f2fae40c32a86b82f8e51a623cacd create mode 100644 tests/data/github.com,api,v2,json,repos,show,ask,python-github2,branches,2be8c8f036124b61fbddeecbbdf28e9c create mode 100644 tests/data/github.com,api,v2,json,repos,show,ask,python-github2,collaborators,855cea60d613a363106762311e6f53ea create mode 100644 tests/data/github.com,api,v2,json,repos,show,ask,python-github2,tags,e7b38a20b45dffd2a22d34b5b51f41da create mode 100644 tests/data/github.com,api,v2,json,repos,show,ask,python-github2,watchers,8f4f641783ac93b3f5d7507bc65cf925 diff --git a/tests/data/github.com,api,v2,json,repos,show,JNRowe,misc-overlay,languages,941f2fae40c32a86b82f8e51a623cacd b/tests/data/github.com,api,v2,json,repos,show,JNRowe,misc-overlay,languages,941f2fae40c32a86b82f8e51a623cacd new file mode 100644 index 0000000..15bd799 --- /dev/null +++ b/tests/data/github.com,api,v2,json,repos,show,JNRowe,misc-overlay,languages,941f2fae40c32a86b82f8e51a623cacd @@ -0,0 +1,14 @@ +status: 200 +x-ratelimit-remaining: 59 +content-location: https://github.com/api/v2/json/repos/show/JNRowe/misc-overlay/languages +x-runtime: 93ms +content-length: 40 +server: nginx/0.7.67 +connection: keep-alive +x-ratelimit-limit: 60 +etag: "584c4c914a780c9338d00d146803076b" +cache-control: private, max-age=0, must-revalidate +date: Wed, 08 Jun 2011 13:38:58 GMT +content-type: application/json; charset=utf-8 + +{"languages":{"VimL":82,"Python":11194}} \ No newline at end of file diff --git a/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,branches,2be8c8f036124b61fbddeecbbdf28e9c b/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,branches,2be8c8f036124b61fbddeecbbdf28e9c new file mode 100644 index 0000000..ab694a6 --- /dev/null +++ b/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,branches,2be8c8f036124b61fbddeecbbdf28e9c @@ -0,0 +1,14 @@ +status: 200 +x-ratelimit-remaining: 57 +content-location: https://github.com/api/v2/json/repos/show/ask/python-github2/branches +x-runtime: 8ms +content-length: 66 +server: nginx/0.7.67 +connection: keep-alive +x-ratelimit-limit: 60 +etag: "9f005bc97eb5ab622f01f1810790a947" +cache-control: private, max-age=0, must-revalidate +date: Wed, 08 Jun 2011 13:39:24 GMT +content-type: application/json; charset=utf-8 + +{"branches":{"master":"1c83cde9b5a7c396a01af1007fb7b88765b9ae45"}} \ No newline at end of file diff --git a/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,collaborators,855cea60d613a363106762311e6f53ea b/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,collaborators,855cea60d613a363106762311e6f53ea new file mode 100644 index 0000000..26c614b --- /dev/null +++ b/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,collaborators,855cea60d613a363106762311e6f53ea @@ -0,0 +1,14 @@ +status: 200 +x-ratelimit-remaining: 57 +content-location: https://github.com/api/v2/json/repos/show/ask/python-github2/collaborators?access_token=xxx +x-runtime: 15ms +content-length: 50 +server: nginx/0.7.67 +connection: keep-alive +x-ratelimit-limit: 60 +etag: "03a973e8cc6d6cc0a8f05f2ef767a175" +cache-control: private, max-age=0, must-revalidate +date: Wed, 08 Jun 2011 13:38:17 GMT +content-type: application/json; charset=utf-8 + +{"collaborators":["ask","jdunck","JNRowe","nvie"]} \ No newline at end of file diff --git a/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,tags,e7b38a20b45dffd2a22d34b5b51f41da b/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,tags,e7b38a20b45dffd2a22d34b5b51f41da new file mode 100644 index 0000000..617036e --- /dev/null +++ b/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,tags,e7b38a20b45dffd2a22d34b5b51f41da @@ -0,0 +1,14 @@ +status: 200 +x-ratelimit-remaining: 58 +content-location: https://github.com/api/v2/json/repos/show/ask/python-github2/tags +x-runtime: 7ms +content-length: 372 +server: nginx/0.7.67 +connection: keep-alive +x-ratelimit-limit: 60 +etag: "25b6801155cc07a688ae97ce708404aa" +cache-control: private, max-age=0, must-revalidate +date: Wed, 08 Jun 2011 13:39:16 GMT +content-type: application/json; charset=utf-8 + +{"tags":{"0.4.0":"6337009b8cefecaff3d5b73883d3da541cc25432","v0.2.0":"9c573faef38b14603c8bdca39c0b7a0140502da9","v0.3.0":"573da9892ddbe85272b7367bf2936d1a3d5d3868","v0.1.2":"03afc58f59b0023a0a9c880387b0487b9010ca98","0.4.1":"96b0a41dd249c521323700bc11a0a721a7c9e642","v0.3.1":"f4c0a1f94770dd087fe636ed98f3443db317ab8c","v0.1.3":"210b2ac7f9368e372d17b7c932e3ad08c23530d4"}} \ No newline at end of file diff --git a/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,watchers,8f4f641783ac93b3f5d7507bc65cf925 b/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,watchers,8f4f641783ac93b3f5d7507bc65cf925 new file mode 100644 index 0000000..cd08980 --- /dev/null +++ b/tests/data/github.com,api,v2,json,repos,show,ask,python-github2,watchers,8f4f641783ac93b3f5d7507bc65cf925 @@ -0,0 +1,14 @@ +status: 200 +x-ratelimit-remaining: 56 +content-location: https://github.com/api/v2/json/repos/show/ask/python-github2/watchers +x-runtime: 54ms +content-length: 1625 +server: nginx/0.7.67 +connection: keep-alive +x-ratelimit-limit: 60 +etag: "b358d3db0f531bd5a4942821a7b2c207" +cache-control: private, max-age=0, must-revalidate +date: Wed, 08 Jun 2011 13:39:31 GMT +content-type: application/json; charset=utf-8 + +{"watchers":["ask","bartTC","gregnewman","sneeu","playpauseandstop","bradjasper","tav","joestump","montylounge","justquick","annoma","mrevilme","matagus","stefanfoulis","paulproteus","mattdennewitz","mrolafsson","mlaprise","notesandvolts","idangazit","defunkt","ericholscher","travisjeffery","mnaberez","mikexstudios","robertpfeiffer","diox","mmalone","rconradharris","codysoyland","fperez","koenbollen","mager","eokyere","leegao","nvie","storborg","thoas","Taomio","junckritter","eklitzke","claudiob","yyliuliang","hemanth","dinoboff","hoffmann","Kuze","sixthgear","wasabi1809","CMB","dcolish","tomdyson","miyamuko","stevejalim","grauwoelfchen","pydanny","mgrouchy","kennethreitz","mrtazz","durden","tkaemming","rnelson","jbochi","cloudartisan","jdunck","mattoufoutu","MtvnGames","salsakran","jrabbit","ojii","shabda","JNRowe","zsiciarz","rnagle","imp","rdegges","travlr","johl","gregory80","markuso","meantheory","idorosen","svetlyak40wt","adamv","dforsyth","bleepbloop","ChristopherMacGown","dreynolds","TaurusOlson","rstrobl","johndagostino","droot","pierre-roux","sanjayprabhu","pquerna","iki","mt3","RaiMan","pinoystartup","adamdoupe","RafeKettler","glensc","wermut","switchyard","sammyt","patrys","blackspiraldev","fkling","rokstrnisa","myusuf3","xen-git","bassdread","pmuilu","pombredanne","sigurdga","surajram","loganlinn","k7d","throughnothing","Amper","nikescar","deeGraYve","broderboy","aculich","AntonioMeireles","pikhovkin","atkinson","sc68cal","ralphbean","goosemo","ergelo","gazoombo","zikey","hub-cap","jamesadney","EnTeQuAk","albertz","ryansb","misfire","lxneng","jean-philippe","deniszgonjanin","Irazmus"]} \ No newline at end of file diff --git a/tests/test_repositories.py b/tests/test_repositories.py index 497a5c2..a30179b 100644 --- a/tests/test_repositories.py +++ b/tests/test_repositories.py @@ -69,6 +69,31 @@ def test_contributors(self): assert_equals(len(contributors), 27) assert_equals(contributors[1].name, 'Ask Solem Hoel') + def test_list_collaborators(self): + collaborators = self.client.repos.list_collaborators('ask/python-github2') + assert_equals(len(collaborators), 4) + assert_equals(collaborators[2], 'JNRowe') + + def test_languages(self): + languages = self.client.repos.languages('JNRowe/misc-overlay') + assert_equals(len(languages), 2) + assert_equals(languages['Python'], 11194) + + def test_tags(self): + tags = self.client.repos.tags('ask/python-github2') + assert_equals(len(tags), 7) + assert_equals(tags['0.4.1'], '96b0a41dd249c521323700bc11a0a721a7c9e642') + + def test_branches(self): + branches = self.client.repos.branches('ask/python-github2') + assert_equals(len(branches), 1) + assert_equals(branches['master'], '1c83cde9b5a7c396a01af1007fb7b88765b9ae45') + + def test_watchers(self): + watchers = self.client.repos.watchers('ask/python-github2') + assert_equals(len(watchers), 143) + assert_equals(watchers[0], 'ask') + class AuthenticatedRepoQueries(utils.HttpMockAuthenticatedTestCase): def test_pushable(self): From 09ff9ff5a61f0a074b978df03df99a5239aa160c Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sun, 12 Jun 2011 12:24:56 +0100 Subject: [PATCH 005/110] Added organisation properties tests. --- tests/test_organizations.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/test_organizations.py b/tests/test_organizations.py index 120c9c0..0842dcc 100644 --- a/tests/test_organizations.py +++ b/tests/test_organizations.py @@ -1,11 +1,33 @@ import _setup +from datetime import datetime + from nose.tools import (assert_equals, assert_true) import utils class OrganizationProperties(utils.HttpMockTestCase): + def test_properties(self): + organization = self.client.organizations.show('github') + assert_equals(organization.id, 9919) + assert_equals(organization.name, 'GitHub') + assert_equals(organization.blog, 'https://github.com/about') + assert_equals(organization.location, 'San Francisco, CA') + assert_equals(organization.gravatar_id, + '61024896f291303615bcd4f7a0dcfb74') + assert_equals(organization.login, 'github') + assert_equals(organization.email, 'support@github.com') + assert_equals(organization.company, None) + assert_equals(organization.created_at, + datetime(2008, 5, 10, 21, 37, 31)) + assert_equals(organization.following_count, 0) + assert_equals(organization.followers_count, 571) + assert_equals(organization.public_gist_count, 0) + assert_equals(organization.public_repo_count, 26) + assert_equals(organization.permission, None) + assert_equals(organization.plan, None) + def test_is_authenticated(self): organization = self.client.organizations.show('github') assert_true(organization.is_authenticated() is False) From 79d4d03a070f1bc0ae3e4a4cdd5ac71a7c6ec083 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sun, 12 Jun 2011 12:26:16 +0100 Subject: [PATCH 006/110] Added pull request properties tests. --- tests/test_pull_requests.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/test_pull_requests.py b/tests/test_pull_requests.py index 522b799..8138b14 100644 --- a/tests/test_pull_requests.py +++ b/tests/test_pull_requests.py @@ -1,11 +1,47 @@ import _setup +from datetime import datetime + from nose.tools import assert_equals import utils class PullRequest(utils.HttpMockTestCase): + def test_properties(self): + pull_request = self.client.pull_requests.show('ask/python-github2', 39) + assert_equals(pull_request.state, 'open') + assert_equals(pull_request.base['sha'], + '6a79f43f174acd3953ced69263c06d311a6bda56') + assert_equals(pull_request.head['sha'], + 'a31cfb70343d3ac9d6330e6328008c0bc690a5a1') + assert_equals(pull_request.issue_user['login'], 'JNRowe') + assert_equals(pull_request.user['login'], 'JNRowe') + assert_equals(pull_request.title, 'Datetime timezone handling.') + assert_equals(len(pull_request.body), 1442) + assert_equals(pull_request.position, 39.0) + assert_equals(pull_request.number, 39.0) + assert_equals(pull_request.votes, 0) + assert_equals(pull_request.comments, 3) + assert_equals(pull_request.diff_url, + 'https://github.com/ask/python-github2/pull/39.diff') + assert_equals(pull_request.patch_url, + 'https://github.com/ask/python-github2/pull/39.patch') + assert_equals(pull_request.labels, []) + assert_equals(pull_request.html_url, + 'https://github.com/ask/python-github2/pull/39') + assert_equals(pull_request.issue_created_at, + datetime(2011, 4, 18, 15, 25, 47)) + assert_equals(pull_request.issue_updated_at, + datetime(2011, 5, 29, 15, 37, 8)) + assert_equals(pull_request.created_at, + datetime(2011, 4, 30, 12, 37, 40)) + assert_equals(pull_request.updated_at, + datetime(2011, 6, 7, 13, 56, 50)) + assert_equals(pull_request.closed_at, None) + assert_equals(len(pull_request.discussion), 13) + assert_equals(pull_request.mergeable, False) + def test_repr(self): pull_request = self.client.pull_requests.show('ask/python-github2', 39) assert_equals(repr(pull_request), From d13d7691d23828bb100254e84e6ae183da859331 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 13:52:01 +0000 Subject: [PATCH 007/110] Silly little PEP-8 fixes. --- github2/core.py | 14 ++++++++------ github2/issues.py | 4 ++-- github2/repositories.py | 6 +++--- github2/request.py | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/github2/core.py b/github2/core.py index 4e11ec7..fe0a122 100644 --- a/github2/core.py +++ b/github2/core.py @@ -100,8 +100,8 @@ def requires_auth(f): :param func f: Function to wrap :raises AuthError: If function called without an authenticated session """ - # When Python 2.4 support is dropped move straight to functools.wraps, don't - # pass go and don't collect $200. + # When Python 2.4 support is dropped move straight to functools.wraps, + # don't pass go and don't collect $200. def wrapper(self, *args, **kwargs): if not self.request.access_token and not self.request.api_token: raise AuthError("%r requires an authenticated session" @@ -161,7 +161,8 @@ def get_value(self, *args, **kwargs): # unicode keys are not accepted as kwargs by python, see: #http://mail-archives.apache.org/mod_mbox/qpid-dev/200609.mbox/%3C1159389941.4505.10.camel@localhost.localdomain%3E # So we make a local dict with the same keys but as strings: - return datatype(**dict((str(k), v) for (k, v) in value.iteritems())) + return datatype(**dict((str(k), v) + for (k, v) in value.iteritems())) return value def get_values(self, *args, **kwargs): @@ -170,7 +171,8 @@ def get_values(self, *args, **kwargs): if datatype: # Same as above, unicode keys will blow up in **args, so we need to # create a new 'values' dict with string keys - return [datatype(**dict((str(k), v) for (k, v) in value.iteritems())) + return [datatype(**dict((str(k), v) + for (k, v) in value.iteritems())) for value in values] else: return values @@ -273,7 +275,7 @@ def __getitem__(self, key): responses to ``BaseData`` derived objects. """ warn("Subscript access on %r is deprecated, use object attributes" - % self.__class__.__name__, DeprecationWarning) + % self.__class__.__name__, DeprecationWarning) if not key in self._meta.keys(): raise KeyError(key) return getattr(self, key) @@ -284,7 +286,7 @@ def __setitem__(self, key, value): :see: ``BaseData.__getitem__`` """ warn("Subscript access on %r is deprecated, use object attributes" - % self.__class__.__name__, DeprecationWarning) + % self.__class__.__name__, DeprecationWarning) if not key in self._meta.keys(): raise KeyError(key) setattr(self, key, value) diff --git a/github2/issues.py b/github2/issues.py index 43111b0..0983b29 100644 --- a/github2/issues.py +++ b/github2/issues.py @@ -68,8 +68,8 @@ def list_by_label(self, project, label): :param str project: GitHub project :param str label: a string representing a label (e.g., ``bug``). """ - return self.get_values("list", project, "label", label, filter="issues", - datatype=Issue) + return self.get_values("list", project, "label", label, + filter="issues", datatype=Issue) def list_labels(self, project): """Get all labels for project. diff --git a/github2/repositories.py b/github2/repositories.py index 2724627..cbd9ad4 100644 --- a/github2/repositories.py +++ b/github2/repositories.py @@ -14,7 +14,7 @@ class Repository(BaseData): fork = Attribute("If True, this is a fork of another repository.") owner = Attribute("Username of the user owning this repository.") homepage = Attribute("Homepage for this project.") - master_branch = Attribute("Default branch, if set.") + master_branch = Attribute("Default branch, if set.") integration_branch = Attribute("Integration branch, if set.") open_issues = Attribute("List of open issues for this repository.") created_at = DateAttribute("Datetime the repository was created.") @@ -64,7 +64,6 @@ def pushable(self): return self.get_values("pushable", filter="repositories", datatype=Repository) - def list(self, user=None, page=1): """Return a list of all repositories for a user. @@ -189,7 +188,8 @@ def languages(self, project): :param str project: Github project """ - return self.get_values("show", project, "languages", filter="languages") + return self.get_values("show", project, "languages", + filter="languages") def tags(self, project): """Get tags for project diff --git a/github2/request.py b/github2/request.py index d350d55..aea7405 100644 --- a/github2/request.py +++ b/github2/request.py @@ -90,7 +90,7 @@ def __init__(self, username=None, api_token=None, url_prefix=None, "api_version": self.api_version, "api_format": self.api_format, } - digicert_ha_cert = path.join(path.dirname(path.abspath(__file__ )), + digicert_ha_cert = path.join(path.dirname(path.abspath(__file__)), "DigiCert_High_Assurance_EV_Root_CA.crt") if proxy_host is None: self._http = httplib2.Http(cache=cache, ca_certs=digicert_ha_cert) From 162d8eade2ebc7acf0ba67accf4bfd2d9fab4487 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 13:52:45 +0000 Subject: [PATCH 008/110] Remove invalid cookies from test data. --- ...st,JNRowe,jnrowe-misc,master,a252487bd992cdfc8247b3c41d0cb9fa | 1 - ...JNRowe,misc-overlay,gh-pages,d0ce7ae70e44f7f396a93485a24b3423 | 1 - ...ges,packages,dev-python.html,8622bc5e052f03439528cc9b7bf3fea2 | 1 - ...misc-overlay,master,Makefile,75d9a1e41e76c3b924420d48b56dc756 | 1 - ...t,JNRowe,misc-overlay,master,bfb4f990e48c87dab73d988a81318d69 | 1 - ...c396a01af1007fb7b88765b9ae45,a4f58221c8131c4e0975cd806f13d76c | 1 - 6 files changed, 6 deletions(-) diff --git a/tests/data/github.com,api,v2,json,commits,list,JNRowe,jnrowe-misc,master,a252487bd992cdfc8247b3c41d0cb9fa b/tests/data/github.com,api,v2,json,commits,list,JNRowe,jnrowe-misc,master,a252487bd992cdfc8247b3c41d0cb9fa index 7128271..b88099b 100644 --- a/tests/data/github.com,api,v2,json,commits,list,JNRowe,jnrowe-misc,master,a252487bd992cdfc8247b3c41d0cb9fa +++ b/tests/data/github.com,api,v2,json,commits,list,JNRowe,jnrowe-misc,master,a252487bd992cdfc8247b3c41d0cb9fa @@ -2,7 +2,6 @@ status: 200 x-ratelimit-remaining: 59 content-location: https://github.com/api/v2/json/commits/list/JNRowe/jnrowe-misc/master?page=2 -content-encoding: gzip -set-cookie: _gh_sess=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%3D%3D--ed7eadd474fd37850b68bd3c08a5c55ad0c3c833; path=/; expires=Fri, 01 Jan 2021 00:00:00 GMT; secure; HttpOnly connection: keep-alive content-length: 22608 diff --git a/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,gh-pages,d0ce7ae70e44f7f396a93485a24b3423 b/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,gh-pages,d0ce7ae70e44f7f396a93485a24b3423 index 56b04cb..b15f434 100644 --- a/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,gh-pages,d0ce7ae70e44f7f396a93485a24b3423 +++ b/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,gh-pages,d0ce7ae70e44f7f396a93485a24b3423 @@ -2,7 +2,6 @@ status: 200 x-ratelimit-remaining: 59 content-location: https://github.com/api/v2/json/commits/list/JNRowe/misc-overlay/gh-pages -content-encoding: gzip -set-cookie: _gh_sess=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%3D%3D--ed7eadd474fd37850b68bd3c08a5c55ad0c3c833; path=/; expires=Fri, 01 Jan 2021 00:00:00 GMT; secure; HttpOnly connection: keep-alive content-length: 19508 diff --git a/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,gh-pages,packages,dev-python.html,8622bc5e052f03439528cc9b7bf3fea2 b/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,gh-pages,packages,dev-python.html,8622bc5e052f03439528cc9b7bf3fea2 index 3493ec2..a55f85d 100644 --- a/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,gh-pages,packages,dev-python.html,8622bc5e052f03439528cc9b7bf3fea2 +++ b/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,gh-pages,packages,dev-python.html,8622bc5e052f03439528cc9b7bf3fea2 @@ -2,7 +2,6 @@ status: 200 x-ratelimit-remaining: 58 content-location: https://github.com/api/v2/json/commits/list/JNRowe/misc-overlay/gh-pages/packages/dev-python.html -content-encoding: gzip -set-cookie: _gh_sess=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%3D%3D--ed7eadd474fd37850b68bd3c08a5c55ad0c3c833; path=/; expires=Fri, 01 Jan 2021 00:00:00 GMT; secure; HttpOnly connection: keep-alive content-length: 19508 diff --git a/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,master,Makefile,75d9a1e41e76c3b924420d48b56dc756 b/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,master,Makefile,75d9a1e41e76c3b924420d48b56dc756 index eb2d090..d420f44 100644 --- a/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,master,Makefile,75d9a1e41e76c3b924420d48b56dc756 +++ b/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,master,Makefile,75d9a1e41e76c3b924420d48b56dc756 @@ -2,7 +2,6 @@ status: 200 x-ratelimit-remaining: 59 content-location: https://github.com/api/v2/json/commits/list/JNRowe/misc-overlay/master/Makefile -content-encoding: gzip -set-cookie: _gh_sess=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%3D%3D--ed7eadd474fd37850b68bd3c08a5c55ad0c3c833; path=/; expires=Fri, 01 Jan 2021 00:00:00 GMT; secure; HttpOnly connection: keep-alive content-length: 19364 diff --git a/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,master,bfb4f990e48c87dab73d988a81318d69 b/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,master,bfb4f990e48c87dab73d988a81318d69 index 33b6332..e6d80d7 100644 --- a/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,master,bfb4f990e48c87dab73d988a81318d69 +++ b/tests/data/github.com,api,v2,json,commits,list,JNRowe,misc-overlay,master,bfb4f990e48c87dab73d988a81318d69 @@ -2,7 +2,6 @@ status: 200 x-ratelimit-remaining: 59 content-location: https://github.com/api/v2/json/commits/list/JNRowe/misc-overlay/master -content-encoding: gzip -set-cookie: _gh_sess=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%3D%3D--ed7eadd474fd37850b68bd3c08a5c55ad0c3c833; path=/; expires=Fri, 01 Jan 2021 00:00:00 GMT; secure; HttpOnly connection: keep-alive content-length: 23425 diff --git a/tests/data/github.com,api,v2,json,commits,show,ask,python-github2,1c83cde9b5a7c396a01af1007fb7b88765b9ae45,a4f58221c8131c4e0975cd806f13d76c b/tests/data/github.com,api,v2,json,commits,show,ask,python-github2,1c83cde9b5a7c396a01af1007fb7b88765b9ae45,a4f58221c8131c4e0975cd806f13d76c index 6340de4..e7cf6dc 100644 --- a/tests/data/github.com,api,v2,json,commits,show,ask,python-github2,1c83cde9b5a7c396a01af1007fb7b88765b9ae45,a4f58221c8131c4e0975cd806f13d76c +++ b/tests/data/github.com,api,v2,json,commits,show,ask,python-github2,1c83cde9b5a7c396a01af1007fb7b88765b9ae45,a4f58221c8131c4e0975cd806f13d76c @@ -2,7 +2,6 @@ status: 200 x-ratelimit-remaining: 59 content-location: https://github.com/api/v2/json/commits/show/ask/python-github2/1c83cde9b5a7c396a01af1007fb7b88765b9ae45 -content-encoding: gzip -set-cookie: _gh_sess=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%3D%3D--ed7eadd474fd37850b68bd3c08a5c55ad0c3c833; path=/; expires=Fri, 01 Jan 2021 00:00:00 GMT; secure; HttpOnly connection: keep-alive content-length: 1578 From f5c447d35000c46e5daeadaf2052d7c6c1d4c5ee Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 13:53:09 +0000 Subject: [PATCH 009/110] Use UTF-8 encoding for test_unit. --- tests/test_unit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_unit.py b/tests/test_unit.py index 9d6650b..ccadb36 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -1,4 +1,4 @@ -# -*- coding: latin-1 -*- +# -*- coding: utf-8 -*- import _setup From f72a255efed7a3cf5fb21dfc5ba07e6371c785ad Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 14:00:12 +0000 Subject: [PATCH 010/110] Added github-plots to 'in the wild' document. --- doc/wild.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/wild.rst b/doc/wild.rst index 6ee7751..0603a94 100644 --- a/doc/wild.rst +++ b/doc/wild.rst @@ -40,6 +40,13 @@ listed on this page. :PyPI page: :pypi:`ghmiles` +``github-plots`` +'''''''''''''''' + + Alternative plots from GitHub stats. + +:PyPI page: :pypi:`github-plots` + ``hubugs`` '''''''''' From c2e043c4d6026b76a524e144a8dc0aecd6b52b0f Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 14:26:04 +0000 Subject: [PATCH 011/110] Added github-issues to 'in the wild' document. --- doc/wild.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/wild.rst b/doc/wild.rst index 0603a94..5e20f7f 100644 --- a/doc/wild.rst +++ b/doc/wild.rst @@ -40,6 +40,14 @@ listed on this page. :PyPI page: :pypi:`ghmiles` +``github-issues`` +''''''''''''''''' + + github-issues allows you to create, close, show, list, and comment on + issues on your github project - that's it. + +:Git repository: https://github.com/kashifrazzaqui/github-issues + ``github-plots`` '''''''''''''''' From edb064d577763f4973e933c826b3c45a9addc477 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 13:43:30 +0000 Subject: [PATCH 012/110] Attempt to import using Python 3 stdlib names first. --- github2/issues.py | 10 ++++++---- github2/request.py | 17 ++++++++++++----- github2/users.py | 10 +++++++--- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/github2/issues.py b/github2/issues.py index 43111b0..c5adb90 100644 --- a/github2/issues.py +++ b/github2/issues.py @@ -1,4 +1,7 @@ -import urllib +try: + from urllib.parse import quote_plus # For Python 3 +except ImportError: + from urllib import quote_plus from github2.core import (GithubCommand, BaseData, Attribute, DateAttribute, repr_string, requires_auth) @@ -47,9 +50,8 @@ def search(self, project, term, state="open"): :param str term: term to search issues for :param str state: can be either ``open`` or ``closed``. """ - return self.get_values("search", project, state, - urllib.quote_plus(term), filter="issues", - datatype=Issue) + return self.get_values("search", project, state, quote_plus(term), + filter="issues", datatype=Issue) def list(self, project, state="open"): """Get all issues for project with given state. diff --git a/github2/request.py b/github2/request.py index d350d55..d7d2769 100644 --- a/github2/request.py +++ b/github2/request.py @@ -3,18 +3,25 @@ import re import time import httplib2 -from httplib import responses +try: + from http.client import responses # For Python 3 +except ImportError: + from httplib import responses try: import json as simplejson # For Python 2.6 except ImportError: import simplejson from os import path -from urlparse import (urlsplit, urlunsplit) try: - from urlparse import parse_qs + # For Python 3 + from urllib.parse import (parse_qs, quote, urlencode, urlsplit, urlunsplit) except ImportError: - from cgi import parse_qs -from urllib import urlencode, quote + from urlparse import (urlsplit, urlunsplit) + try: + from urlparse import parse_qs + except ImportError: + from cgi import parse_qs + from urllib import urlencode, quote #: Hostname for API access diff --git a/github2/users.py b/github2/users.py index 3a40a8f..7dba3e6 100644 --- a/github2/users.py +++ b/github2/users.py @@ -1,6 +1,10 @@ +try: + from urllib.parse import quote_plus # For Python 3 +except ImportError: + from urllib import quote_plus + from github2.core import (BaseData, GithubCommand, DateAttribute, Attribute, enhanced_by_auth, requires_auth) -import urllib class User(BaseData): @@ -48,8 +52,8 @@ def search(self, query): :param str query: term to search for """ - return self.get_values("search", urllib.quote_plus(query), - filter="users", datatype=User) + return self.get_values("search", quote_plus(query), filter="users", + datatype=User) def search_by_email(self, query): """Search for users by email address From 9ea7e4ca60652b9db8d41eacee129d003a28d8dc Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 13:44:25 +0000 Subject: [PATCH 013/110] Use Python 2 & 3 compatible syntax for metaclass usage. --- github2/core.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/github2/core.py b/github2/core.py index 4e11ec7..a1137c0 100644 --- a/github2/core.py +++ b/github2/core.py @@ -263,9 +263,9 @@ def iterate(self): return result_cls -class BaseData(object): - __metaclass__ = BaseDataType - +# Ugly base class definition for Python 2 and 3 compatibility, where metaclass +# syntax is incompatible +class BaseData(BaseDataType('BaseData', (object, ), {})): def __getitem__(self, key): """Access objects's attribute using subscript notation From 32fe44d25fce6211f665568cfd318cef71d24899 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 13:45:25 +0000 Subject: [PATCH 014/110] =?UTF-8?q?No=20need=20for=20unicode=E2=86=92str?= =?UTF-8?q?=20kwargs=20hack=20in=20Python=203.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- github2/core.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/github2/core.py b/github2/core.py index a1137c0..36558a0 100644 --- a/github2/core.py +++ b/github2/core.py @@ -158,20 +158,26 @@ def get_value(self, *args, **kwargs): datatype = kwargs.pop("datatype", None) value = self.make_request(*args, **kwargs) if datatype: - # unicode keys are not accepted as kwargs by python, see: - #http://mail-archives.apache.org/mod_mbox/qpid-dev/200609.mbox/%3C1159389941.4505.10.camel@localhost.localdomain%3E - # So we make a local dict with the same keys but as strings: - return datatype(**dict((str(k), v) for (k, v) in value.iteritems())) + if not PY3K: + # unicode keys are not accepted as kwargs by python, see: + #http://mail-archives.apache.org/mod_mbox/qpid-dev/200609.mbox/%3C1159389941.4505.10.camel@localhost.localdomain%3E + # So we make a local dict with the same keys but as strings: + return datatype(**dict((str(k), v) for (k, v) in value.items())) + else: + return datatype(**value) return value def get_values(self, *args, **kwargs): datatype = kwargs.pop("datatype", None) values = self.make_request(*args, **kwargs) if datatype: - # Same as above, unicode keys will blow up in **args, so we need to - # create a new 'values' dict with string keys - return [datatype(**dict((str(k), v) for (k, v) in value.iteritems())) - for value in values] + if not PY3K: + # Same as above, unicode keys will blow up in **args, so we need to + # create a new 'values' dict with string keys + return [datatype(**dict((str(k), v) for (k, v) in value.items())) + for value in values] + else: + return [datatype(**value) for value in values] else: return values From dd588f8d28ef1eb931dbe55cdf752a1757499b7e Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 13:47:11 +0000 Subject: [PATCH 015/110] Removed now unused build path hack in tests. --- tests/_setup.py | 6 ------ tests/test_charset_header.py | 2 -- tests/test_commits.py | 2 -- tests/test_date_handling.py | 2 -- tests/test_issues.py | 2 -- tests/test_organizations.py | 2 -- tests/test_pull_requests.py | 2 -- tests/test_regression.py | 2 -- tests/test_repositories.py | 2 -- tests/test_request.py | 2 -- tests/test_tz_aware_date_handling.py | 2 -- tests/test_unit.py | 2 -- tests/test_user.py | 2 -- tests/utils.py | 2 -- 14 files changed, 32 deletions(-) delete mode 100644 tests/_setup.py diff --git a/tests/_setup.py b/tests/_setup.py deleted file mode 100644 index c410274..0000000 --- a/tests/_setup.py +++ /dev/null @@ -1,6 +0,0 @@ -import sys - -# Forcibly insert path for `setup.py build` output, so that we import from the -# ``2to3`` converted sources. This is an ugly hack, but it saves an enormous -# amount of grief in handling Python 2 and 3. -sys.path.insert(0, 'build/lib') diff --git a/tests/test_charset_header.py b/tests/test_charset_header.py index 073e10c..b495bfc 100644 --- a/tests/test_charset_header.py +++ b/tests/test_charset_header.py @@ -1,5 +1,3 @@ -import _setup - from nose.tools import assert_equals from github2.request import charset_from_headers diff --git a/tests/test_commits.py b/tests/test_commits.py index 06f3b1c..b4eab13 100644 --- a/tests/test_commits.py +++ b/tests/test_commits.py @@ -1,5 +1,3 @@ -import _setup - from nose.tools import assert_equals import utils diff --git a/tests/test_date_handling.py b/tests/test_date_handling.py index 591bb2c..dcfea34 100644 --- a/tests/test_date_handling.py +++ b/tests/test_date_handling.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -import _setup - from datetime import datetime as dt from nose.tools import assert_equals diff --git a/tests/test_issues.py b/tests/test_issues.py index 83e2822..245b6b9 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -1,5 +1,3 @@ -import _setup - from nose.tools import assert_equals import utils diff --git a/tests/test_organizations.py b/tests/test_organizations.py index 1425a07..f97b905 100644 --- a/tests/test_organizations.py +++ b/tests/test_organizations.py @@ -1,5 +1,3 @@ -import _setup - from nose.tools import (assert_equals, assert_true) import utils diff --git a/tests/test_pull_requests.py b/tests/test_pull_requests.py index 80cc540..2a453b0 100644 --- a/tests/test_pull_requests.py +++ b/tests/test_pull_requests.py @@ -1,5 +1,3 @@ -import _setup - from nose.tools import assert_equals import utils diff --git a/tests/test_regression.py b/tests/test_regression.py index 5438888..a2b235c 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -1,5 +1,3 @@ -import _setup - import httplib2 from nose.tools import assert_equals diff --git a/tests/test_repositories.py b/tests/test_repositories.py index d7f9c07..103045f 100644 --- a/tests/test_repositories.py +++ b/tests/test_repositories.py @@ -1,5 +1,3 @@ -import _setup - import datetime from nose.tools import assert_equals diff --git a/tests/test_request.py b/tests/test_request.py index a36086f..90849dc 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -1,5 +1,3 @@ -import _setup - import unittest from nose.tools import (assert_equals, assert_true) diff --git a/tests/test_tz_aware_date_handling.py b/tests/test_tz_aware_date_handling.py index c2e07c6..4e4f6eb 100644 --- a/tests/test_tz_aware_date_handling.py +++ b/tests/test_tz_aware_date_handling.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -import _setup - from datetime import datetime as dt from dateutil.tz import tzutc diff --git a/tests/test_unit.py b/tests/test_unit.py index 9d6650b..f4b3452 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -1,7 +1,5 @@ # -*- coding: latin-1 -*- -import _setup - import datetime import unittest diff --git a/tests/test_user.py b/tests/test_user.py index 5fe4c5b..3b0f8c3 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -1,5 +1,3 @@ -import _setup - import datetime from nose.tools import (assert_equals, assert_false, assert_true) diff --git a/tests/utils.py b/tests/utils.py index d05e258..0657cfa 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,5 +1,3 @@ -import _setup - import os import sys import unittest From 355c17255ced730d5644beab4bf4fd4b81023c80 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 13:54:14 +0000 Subject: [PATCH 016/110] Remove library rebuild hack in tox config. --- tox.ini | 2 -- 1 file changed, 2 deletions(-) diff --git a/tox.ini b/tox.ini index 7a01449..531bac9 100644 --- a/tox.ini +++ b/tox.ini @@ -7,8 +7,6 @@ deps = nose coverage commands = - rm -rf build - {envpython} setup.py build nosetests {posargs:-vv} tests [testenv:rst] deps = From e221921a8e90ffda59c74349b4fc39df3922eafd Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 15:52:06 +0000 Subject: [PATCH 017/110] httplib.responses fix for Python 2.4 compatibility. Thanks to James Elkin for reporting. --- github2/request.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/github2/request.py b/github2/request.py index aea7405..a773f48 100644 --- a/github2/request.py +++ b/github2/request.py @@ -3,7 +3,12 @@ import re import time import httplib2 -from httplib import responses +try: + from httplib import responses +except ImportError: # For Python 2.4 + from BaseHTTPServer import BaseHTTPRequestHandler + responses = dict([(k, v[0]) + for k, v in BaseHTTPRequestHandler.responses.items()]) try: import json as simplejson # For Python 2.6 except ImportError: @@ -55,7 +60,7 @@ def __init__(self, message, content, code): self.message = message self.content = content self.code = code - if code: + if code and responses: self.code_reason = responses[code] else: self.code_reason = "" From d85343f8cc5d374b79191c27274a78b067f4ea19 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 14:11:42 +0000 Subject: [PATCH 018/110] Wrap print statement/function in scripts for compatibility. --- github2/bin/manage_collaborators.py | 23 ++++++++++++++++++++--- github2/bin/search_repos.py | 22 ++++++++++++++++++---- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/github2/bin/manage_collaborators.py b/github2/bin/manage_collaborators.py index ca59df5..821e89d 100755 --- a/github2/bin/manage_collaborators.py +++ b/github2/bin/manage_collaborators.py @@ -12,10 +12,27 @@ # BSD licensed import logging +import sys + from optparse import OptionParser + import github2.client +#: Running under Python 3 +PY3K = sys.version_info[0] == 3 and True or False + + +def print_(text): + """Python 2 & 3 compatible print function + + We support <2.6, so can't use __future__.print_function""" + if PY3K: + print(text) + else: + sys.stdout.write(text + '\n') + + def parse_commandline(): """Parse the comandline and return parsed options.""" @@ -72,7 +89,7 @@ def main(): if len(args) == 1: for repos in github.repos.list(options.account): fullreposname = github.project_for_user_repo(options.account, repos.name) - print "%s: %s" % (repos.name, ' '.join(github.repos.list_collaborators(fullreposname))) + print_("%s: %s" % (repos.name, ' '.join(github.repos.list_collaborators(fullreposname)))) elif len(args) == 2: command, collaborator = args for repos in github.repos.list(options.account): @@ -80,11 +97,11 @@ def main(): if collaborator in github.repos.list_collaborators(fullreposname): if command == 'remove': github.repos.remove_collaborator(repos.name, collaborator) - print "removed %r from %r" % (collaborator, repos.name) + print_("removed %r from %r" % (collaborator, repos.name)) else: if command == 'add': github.repos.add_collaborator(repos.name, collaborator) - print "added %r to %r" % (collaborator, repos.name) + print_("added %r to %r" % (collaborator, repos.name)) logging.shutdown() diff --git a/github2/bin/search_repos.py b/github2/bin/search_repos.py index 75b295c..c52be46 100755 --- a/github2/bin/search_repos.py +++ b/github2/bin/search_repos.py @@ -12,6 +12,20 @@ import github2.client +#: Running under Python 3 +PY3K = sys.version_info[0] == 3 and True or False + + +def print_(text): + """Python 2 & 3 compatible print function + + We support <2.6, so can't use __future__.print_function""" + if PY3K: + print(text) + else: + sys.stdout.write(text + '\n') + + def parse_commandline(): """Parse the comandline and return parsed options.""" @@ -47,14 +61,14 @@ def main(): repos = github.repos.search(term) if not repos: - print 'No repos found!' + print_('No repos found!') return_value = 255 else: for repo in repos: - print repo.project + print(repo.project) if repo.description: - print '\n'.join(wrap(repo.description, initial_indent=' ', - subsequent_indent=' ')) + print_('\n'.join(wrap(repo.description, initial_indent=' ', + subsequent_indent=' '))) logging.shutdown() return return_value From d9ba6658a4f6ecc10bf5cb5c73857dfe5914083b Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 14:31:24 +0000 Subject: [PATCH 019/110] =?UTF-8?q?Unicode=E2=86=92str=20kwargs=20hack=20o?= =?UTF-8?q?nly=20needed=20for=20Python=20<2.7.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- github2/core.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/github2/core.py b/github2/core.py index 36558a0..7b47d12 100644 --- a/github2/core.py +++ b/github2/core.py @@ -9,6 +9,9 @@ #: Running under Python 3 PY3K = sys.version_info[0] == 3 and True or False +#: Running under Python 2.7, or newer +PY27 = sys.version_info[:2] == 3 and True or False + GITHUB_DATE_FORMAT = "%Y/%m/%d %H:%M:%S %z" # We need to manually mangle the timezone for commit date formatting because it # uses -xx:xx format @@ -158,9 +161,9 @@ def get_value(self, *args, **kwargs): datatype = kwargs.pop("datatype", None) value = self.make_request(*args, **kwargs) if datatype: - if not PY3K: - # unicode keys are not accepted as kwargs by python, see: - #http://mail-archives.apache.org/mod_mbox/qpid-dev/200609.mbox/%3C1159389941.4505.10.camel@localhost.localdomain%3E + if not PY27: + # unicode keys are not accepted as kwargs by python, until 2.7: + # http://bugs.python.org/issue2646 # So we make a local dict with the same keys but as strings: return datatype(**dict((str(k), v) for (k, v) in value.items())) else: @@ -171,7 +174,7 @@ def get_values(self, *args, **kwargs): datatype = kwargs.pop("datatype", None) values = self.make_request(*args, **kwargs) if datatype: - if not PY3K: + if not PY27: # Same as above, unicode keys will blow up in **args, so we need to # create a new 'values' dict with string keys return [datatype(**dict((str(k), v) for (k, v) in value.items())) From 6d5f350585e8f340fa4cbc6de4769fbe3d7d7aa5 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 14:37:00 +0000 Subject: [PATCH 020/110] Use __name__ instead of func_name for compatibility with Python 3. --- github2/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github2/core.py b/github2/core.py index 7b47d12..61b6899 100644 --- a/github2/core.py +++ b/github2/core.py @@ -250,7 +250,7 @@ def __new__(cls, name, bases, attrs): for attr_name in attributes])) def _contribute_method(name, func): - func.func_name = name + func.__name__ = name attrs[name] = func def constructor(self, **kwargs): From c6afe2977483dfc598d11a322c9ba27bf5ad4e18 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 13 Dec 2011 20:04:38 +0000 Subject: [PATCH 021/110] No longer need to call 2to3 during build. --- setup.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/setup.py b/setup.py index 0abb26b..8613f1f 100755 --- a/setup.py +++ b/setup.py @@ -13,10 +13,8 @@ if sys.version_info[:2] < (2, 6): install_requires.append('simplejson >= 2.0.9') -extra = {} if sys.version_info >= (3,): install_requires.append('python-dateutil >= 2.0') - extra['use_2to3'] = True else: install_requires.append('python-dateutil < 2.0') @@ -64,5 +62,4 @@ "Topic :: Software Development", "Topic :: Software Development :: Libraries", ], - **extra ) From ab46a17eb0e4c6b49fe41aa60b232bd95c869e03 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 15 Dec 2011 20:39:02 +0000 Subject: [PATCH 022/110] Activat the Sphinx coverage extension. --- doc/conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index 2f2b3bf..e54a0cc 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -28,7 +28,8 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ["sphinx.ext.%s" % ext - for ext in ["autodoc", "todo", "intersphinx", "viewcode"]] + \ + for ext in ["autodoc", "todo", "intersphinx", "viewcode", + "coverage"]] + \ ["sphinxcontrib.%s" % ext for ext in ["cheeseshop", ]] # Add any paths that contain templates here, relative to this directory. From 057e02b886cc3700d7e76ea1a88d0b73797deac4 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 15 Dec 2011 20:59:24 +0000 Subject: [PATCH 023/110] Added bugwarrior to 'in the wild' document. --- doc/wild.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/wild.rst b/doc/wild.rst index 5e20f7f..968358f 100644 --- a/doc/wild.rst +++ b/doc/wild.rst @@ -24,6 +24,14 @@ listed on this page. :PyPI page: :pypi:`bitbucket2github` +``bugwarrior`` +'''''''''''''' + + Pull tickets from github, bitbucket, and trac into `taskwarrior + `__ + +:PyPI page: :pypi:`bugwarrior` + ``forkfeed`` '''''''''''' From 3f476e6fa9f01d827afdb774c45f532c5aeea476 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 20 Dec 2011 02:39:01 +0000 Subject: [PATCH 024/110] Fixed rate limiting example in problems doc. --- doc/problems.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/problems.rst b/doc/problems.rst index 90021af..5fabddf 100644 --- a/doc/problems.rst +++ b/doc/problems.rst @@ -35,14 +35,14 @@ response from GitHub, here the user data of ``JNRowe``. Rate limiting ''''''''''''' -If rate limiting is enabled, with the ``requests_per_second`` when creating a -:class:`~github2.client.Github` object, then you'll see a ``WARNING`` level -message when a request has been delayed. +If rate limiting is enabled, with the ``requests_per_second`` parameter when +creating a :class:`~github2.client.Github` object, then you'll see a ``WARNING`` +level message when a request has been delayed. - >>> github = Github(requests_per_second=0.2, debug=True) + >>> github = Github(requests_per_second=0.2) >>> user = github.users.show("JNRowe") >>> user = github.users.show("JNRowe") - delaying API call 4.99773 + WARNING:github2.request:delaying API call 4.997032 second(s) Here we have defined a rate limit of one call every five seconds, and doing so has imposed an almost 5 second delay before completing the second request. From 62d95cca4eacfbd089796aaca23397903b14fc73 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 20 Dec 2011 02:39:43 +0000 Subject: [PATCH 025/110] Simplify testing of Python version. Also fixes an unnoticed stupid copy/paste bug. --- github2/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github2/core.py b/github2/core.py index 3308044..e2860cb 100644 --- a/github2/core.py +++ b/github2/core.py @@ -7,10 +7,10 @@ #: Running under Python 3 -PY3K = sys.version_info[0] == 3 and True or False +PY3K = sys.version_info[0] == 3 #: Running under Python 2.7, or newer -PY27 = sys.version_info[:2] == 3 and True or False +PY27 = sys.version_info[:2] >= (2, 7) GITHUB_DATE_FORMAT = "%Y/%m/%d %H:%M:%S %z" # We need to manually mangle the timezone for commit date formatting because it From 4b5edf4e349d7123d246c478d301023b1f38c9e6 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 20 Dec 2011 02:40:17 +0000 Subject: [PATCH 026/110] Don't repeatably call str.upper() when testing method name. --- github2/core.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github2/core.py b/github2/core.py index e2860cb..cb75f9b 100644 --- a/github2/core.py +++ b/github2/core.py @@ -141,14 +141,14 @@ def make_request(self, command, *args, **kwargs): page = kwargs.pop("page", 1) if page and not page == 1: post_data["page"] = page - method = kwargs.get("method", "GET") - if method.upper() == "POST" or method.upper() == "GET" and post_data: + method = kwargs.get("method", "GET").upper() + if method == "POST" or method == "GET" and post_data: response = self.request.post(self.domain, command, *args, **post_data) - elif method.upper() == "PUT": + elif method == "PUT": response = self.request.put(self.domain, command, *args, **post_data) - elif method.upper() == "DELETE": + elif method == "DELETE": response = self.request.delete(self.domain, command, *args, **post_data) else: From 08480073f3e80655a7b97a6367b25389095aea14 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 20 Dec 2011 02:41:18 +0000 Subject: [PATCH 027/110] Correct docstring for teams.repositories. --- github2/teams.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github2/teams.py b/github2/teams.py index 859a40e..bd8c783 100644 --- a/github2/teams.py +++ b/github2/teams.py @@ -33,7 +33,7 @@ def members(self, team_id): datatype=User) def repositories(self, team_id): - """Get list of all team members + """Get list of all team repositories :param int team_id: team to get information for """ From 99a34823a34b63c55ece2ae95daf30145bdf4d54 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 20 Dec 2011 02:42:33 +0000 Subject: [PATCH 028/110] Added requires_auth decorator to team modifying methods. --- github2/teams.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/github2/teams.py b/github2/teams.py index bd8c783..1c5feda 100644 --- a/github2/teams.py +++ b/github2/teams.py @@ -1,4 +1,4 @@ -from github2.core import BaseData, GithubCommand, Attribute +from github2.core import BaseData, GithubCommand, Attribute, requires_auth from github2.repositories import Repository from github2.users import User @@ -40,6 +40,7 @@ def repositories(self, team_id): return self.get_values(str(team_id), "repositories", filter="repositories", datatype=Repository) + @requires_auth def add_project(self, team_id, project): """Add a project to a team @@ -52,6 +53,7 @@ def add_project(self, team_id, project): post_data={'name': project}, filter="repositories", datatype=Repository) + @requires_auth def remove_project(self, team_id, project): """Remove a project to a team From 5a6ff55d7675cbb3e9df6f18875caf848b65fbf7 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 20 Dec 2011 02:44:09 +0000 Subject: [PATCH 029/110] Very minor simplification of encode_authentication_data. --- github2/request.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/github2/request.py b/github2/request.py index d062a97..1b473fe 100644 --- a/github2/request.py +++ b/github2/request.py @@ -113,13 +113,12 @@ def __init__(self, username=None, api_token=None, url_prefix=None, ca_certs=digicert_ha_cert) def encode_authentication_data(self, extra_post_data): + post_data = {} if self.access_token: - post_data = {"access_token": self.access_token} + post_data["access_token"] = self.access_token elif self.username and self.api_token: - post_data = {"login": self.username, - "token": self.api_token} - else: - post_data = {} + post_data["login"] = self.username + post_data["token"] = self.api_token post_data.update(extra_post_data) return urlencode(post_data) From b0c12a731b59155c682aff644c9b3f64f36b3ab1 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 20 Dec 2011 04:41:13 +0000 Subject: [PATCH 030/110] Support the use of repeated keys in query strings. --- github2/request.py | 16 +++++--- tests/test_request.py | 85 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 80 insertions(+), 21 deletions(-) diff --git a/github2/request.py b/github2/request.py index d062a97..628aff5 100644 --- a/github2/request.py +++ b/github2/request.py @@ -113,14 +113,18 @@ def __init__(self, username=None, api_token=None, url_prefix=None, ca_certs=digicert_ha_cert) def encode_authentication_data(self, extra_post_data): + post_data = [] if self.access_token: - post_data = {"access_token": self.access_token} + post_data.append(("access_token", self.access_token)) elif self.username and self.api_token: - post_data = {"login": self.username, - "token": self.api_token} - else: - post_data = {} - post_data.update(extra_post_data) + post_data.append(("login", self.username)) + post_data.append(("token", self.api_token)) + for key, value in extra_post_data.items(): + if isinstance(value, list): + for elem in value: + post_data.append((key, elem)) + else: + post_data.append((key, value)) return urlencode(post_data) def get(self, *path_components): diff --git a/tests/test_request.py b/tests/test_request.py index 90849dc..031bc4f 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -1,31 +1,86 @@ import unittest -from nose.tools import (assert_equals, assert_true) +try: + from urllib.parse import parse_qs # For Python 3 +except ImportError: + try: + from urlparse import parse_qs + except ImportError: # For Python <2.6 + from cgi import parse_qs + +try: + from nose.tools import (assert_dict_contains_subset, assert_dict_equal) +except ImportError: # for Python <2.7 + import unittest2 + + _binding = unittest2.TestCase('run') + assert_dict_contains_subset = _binding.assertDictContainsSubset + assert_dict_equal = _binding.assertDictEqual + from github2 import request +def assert_params(first, second): + assert_dict_equal(first, parse_qs(second)) + + +def assert_params_contain(first, second): + assert_dict_contains_subset(first, parse_qs(second)) + + class TestAuthEncode(unittest.TestCase): """Test processing of authentication data""" def setUp(self): self.r = request.GithubRequest() def test_unauthenticated(self): - assert_equals('', self.r.encode_authentication_data({})) + assert_params({}, self.r.encode_authentication_data({})) def test_access_token(self): - self.r.access_token = 'hex string' - assert_equals('access_token=hex+string', - self.r.encode_authentication_data({})) - assert_true('access_token=hex+string' in - self.r.encode_authentication_data({'key': 'value'})) - self.r.access_token = None + try: + self.r.access_token = 'hex string' + assert_params({'access_token': ['hex string', ]}, + self.r.encode_authentication_data({})) + finally: + self.r.access_token = None def test_user_token(self): - self.r.username = 'user' - self.r.api_token = 'hex string' - assert_equals('login=user&token=hex+string', - self.r.encode_authentication_data({})) - assert_true('login=user&token=hex+string' in - self.r.encode_authentication_data({'key': 'value'})) - self.r.username = self.r.api_token = None + try: + self.r.username = 'user' + self.r.api_token = 'hex string' + token_params = {'login': ['user', ], 'token': ['hex string', ]} + assert_params(token_params, self.r.encode_authentication_data({})) + finally: + self.r.username = self.r.api_token = None + + +class TestParameterEncoding(unittest.TestCase): + def setUp(self): + self.r = request.GithubRequest() + self.params = { + 'key1': 'value1', + 'key2': 'value2', + } + + def test_no_parameters(self): + assert_params({}, self.r.encode_authentication_data({})) + + def test_parameters(self): + assert_params({'key1': ['value1', ], 'key2': ['value2', ]}, + self.r.encode_authentication_data(self.params)) + + def test_parameters_with_auth(self): + try: + self.r.username = 'user' + self.r.api_token = 'hex string' + assert_params({'key2': ['value2', ], 'login': ['user', ], + 'token': ['hex string', ], 'key1': ['value1', ]}, + self.r.encode_authentication_data(self.params)) + finally: + self.r.username = '' + self.r.api_token = '' + + def test_multivalue_parameters(self): + multivals = {'key': ['value1', 'value2']} + assert_params(multivals, self.r.encode_authentication_data(multivals)) From 05f4e79c8a48584b33883368a648dc40d67a126d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 19 Dec 2011 20:54:11 +0000 Subject: [PATCH 031/110] Added method to add a new team. Thanks to Clint Savage, refs #69. --- github2/organizations.py | 18 +++++++++++++++++- ...-org,teams,6869b96ae6fbaa7511d92aa73803898b | 14 ++++++++++++++ ..._token=xxx,00192d3a6cc4fc297b5a9cb0742c3663 | 14 ++++++++++++++ tests/test_organizations.py | 17 +++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 tests/data/github.com,api,v2,json,organizations,JNRowe-test-org,teams,6869b96ae6fbaa7511d92aa73803898b create mode 100644 tests/data/github.com,api,v2,json,teams,121678,repositories,access_token=xxx,00192d3a6cc4fc297b5a9cb0742c3663 diff --git a/github2/organizations.py b/github2/organizations.py index 25df990..0c8aa00 100644 --- a/github2/organizations.py +++ b/github2/organizations.py @@ -1,4 +1,5 @@ -from github2.core import BaseData, GithubCommand, Attribute, DateAttribute +from github2.core import (BaseData, GithubCommand, Attribute, DateAttribute, + requires_auth) from github2.repositories import Repository from github2.teams import Team from github2.users import User @@ -81,3 +82,18 @@ def teams(self, organization): """ return self.get_values(organization, 'teams', filter="teams", datatype=Team) + + @requires_auth + def add_team(self, organization, name, permission='pull', projects=None): + """Add a team to an organization + + :param str organization: organization to add team to + :param str team: name of team to add + :param str permission: permissions for team(push, pull or admin) + :param list projects: optional GitHub projects for this team + """ + team_data = {'team[name]': name, 'team[permission]': permission} + if projects: + team_data['team[repo_names][]'] = projects + return self.get_value(organization, 'teams', post_data=team_data, + method='POST', filter='team', datatype=Team) diff --git a/tests/data/github.com,api,v2,json,organizations,JNRowe-test-org,teams,6869b96ae6fbaa7511d92aa73803898b b/tests/data/github.com,api,v2,json,organizations,JNRowe-test-org,teams,6869b96ae6fbaa7511d92aa73803898b new file mode 100644 index 0000000..969ee88 --- /dev/null +++ b/tests/data/github.com,api,v2,json,organizations,JNRowe-test-org,teams,6869b96ae6fbaa7511d92aa73803898b @@ -0,0 +1,14 @@ +status: 200 +x-ratelimit-remaining: 60 +content-location: https://github.com/api/v2/json/organizations/JNRowe-test-org/teams +x-runtime: 20ms +content-length: 61 +server: nginx/1.0.4 +connection: keep-alive +x-ratelimit-limit: 58 +etag: "0ea8a446a00b4d7894676a34bd8d501f" +cache-control: private, max-age=0, must-revalidate +date: Mon, 19 Dec 2011 20:50:41 GMT +content-type: application/json; charset=utf-8 + +{"team":{"name":"team_pull","id":121678,"permission":"pull"}} diff --git a/tests/data/github.com,api,v2,json,teams,121678,repositories,access_token=xxx,00192d3a6cc4fc297b5a9cb0742c3663 b/tests/data/github.com,api,v2,json,teams,121678,repositories,access_token=xxx,00192d3a6cc4fc297b5a9cb0742c3663 new file mode 100644 index 0000000..c83a9c7 --- /dev/null +++ b/tests/data/github.com,api,v2,json,teams,121678,repositories,access_token=xxx,00192d3a6cc4fc297b5a9cb0742c3663 @@ -0,0 +1,14 @@ +status: 200 +x-ratelimit-remaining: 60 +content-location: https://github.com/api/v2/json/organizations/JNRowe-test-org/teams +x-runtime: 20ms +content-length: 676 +server: nginx/1.0.4 +connection: keep-alive +x-ratelimit-limit: 58 +etag: "397a2fcea970a6391b74eabcb62ed265" +cache-control: private, max-age=0, must-revalidate +date: Thu, 19 Dec 2011 20:50:41 GMT +content-type: application/json; charset=utf-8 + +{"repositories":[{"open_issues":0,"description":"","watchers":1,"forks":1,"has_issues":true,"has_downloads":true,"fork":false,"created_at":"2011/12/18 17:36:08 -0800","homepage":"","size":0,"private":false,"name":"test1","owner":"JNRowe-test-org","has_wiki":true,"url":"https://github.com/JNRowe-test-org/test1","organization":"JNRowe-test-org"},{"open_issues":0,"description":"","watchers":1,"forks":1,"has_issues":true,"has_downloads":true,"fork":false,"created_at":"2011/12/18 17:36:24 -0800","homepage":"","size":0,"private":false,"name":"test2","owner":"JNRowe-test-org","has_wiki":true,"url":"https://github.com/JNRowe-test-org/test2","organization":"JNRowe-test-org"}]} diff --git a/tests/test_organizations.py b/tests/test_organizations.py index f97b905..2f8d43f 100644 --- a/tests/test_organizations.py +++ b/tests/test_organizations.py @@ -29,3 +29,20 @@ def test_public_members(self): members = self.client.organizations.public_members('github') assert_equals(len(members), 35) assert_equals(members[2].name, 'Ben Burkert') + + +class OrganizationsEdits(utils.HttpMockAuthenticatedTestCase): + def test_add_team(self): + team = self.client.organizations.add_team('JNRowe-test-org', + 'test_pull', 'pull') + assert_equals(team.name, 'team_pull') + assert_equals(team.permission, 'pull') + + def test_add_team_with_repos(self): + projects = ['JNRowe-test-org/test1', 'JNRowe-test-org/test2'] + team = self.client.organizations.add_team('JNRowe-test-org', + 'test_push', 'push', projects) + + team_repos = self.client.teams.repositories(team.id) + assert_equals(['/'.join([x.organization, x.name]) for x in team_repos], + projects) From b77e3c91bf73b9dec9d69b43d8643f1490dd11b5 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 19 Dec 2011 20:55:58 +0000 Subject: [PATCH 032/110] Added method to add a new team member. Thanks to Clint Savage, refs #69. --- github2/teams.py | 13 ++++++++++++- ...121990,members,ef66ad4c5f8c1b21dc9bc8c54c9ec91e | 14 ++++++++++++++ tests/test_teams.py | 9 +++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 tests/data/github.com,api,v2,json,teams,121990,members,ef66ad4c5f8c1b21dc9bc8c54c9ec91e create mode 100644 tests/test_teams.py diff --git a/github2/teams.py b/github2/teams.py index 859a40e..175f1f6 100644 --- a/github2/teams.py +++ b/github2/teams.py @@ -1,4 +1,4 @@ -from github2.core import BaseData, GithubCommand, Attribute +from github2.core import BaseData, GithubCommand, Attribute, requires_auth from github2.repositories import Repository from github2.users import User @@ -32,6 +32,17 @@ def members(self, team_id): return self.get_values(str(team_id), "members", filter="users", datatype=User) + @requires_auth + def add_member(self, team_id, username): + """Add a new member to a team + + :param int team_id: team to add new member to + :param str username: GitHub username to add to team + """ + return self.get_values(str(team_id), 'members', method='POST', + post_data={'name': username}, filter='users', + datatype=User) + def repositories(self, team_id): """Get list of all team members diff --git a/tests/data/github.com,api,v2,json,teams,121990,members,ef66ad4c5f8c1b21dc9bc8c54c9ec91e b/tests/data/github.com,api,v2,json,teams,121990,members,ef66ad4c5f8c1b21dc9bc8c54c9ec91e new file mode 100644 index 0000000..10bd256 --- /dev/null +++ b/tests/data/github.com,api,v2,json,teams,121990,members,ef66ad4c5f8c1b21dc9bc8c54c9ec91e @@ -0,0 +1,14 @@ +status: 200 +x-ratelimit-remaining: 60 +content-location: https://github.com/api/v2/json/teams/121990/members +x-runtime: 20ms +content-length: 202 +server: nginx/1.0.4 +connection: keep-alive +x-ratelimit-limit: 58 +etag: "397a2fcea970a6391b74eabcb62ed265" +cache-control: private, max-age=0, must-revalidate +date: Thu, 19 Dec 2011 20:55:34 GMT +content-type: application/json; charset=utf-8 + +{"users":[{"name":"James Rowe","gravatar_id":"e40de1eb6e8a74cb96b3f07f3994f155","location":"Cambridge, UK","blog":"http://jnrowe.github.com/","type":"User","login":"JNRowe","email":"jnrowe@gmail.com"}]} diff --git a/tests/test_teams.py b/tests/test_teams.py new file mode 100644 index 0000000..85689aa --- /dev/null +++ b/tests/test_teams.py @@ -0,0 +1,9 @@ +from nose.tools import assert_equals + +import utils + + +class TeamEdits(utils.HttpMockAuthenticatedTestCase): + def test_add_member(self): + users = self.client.teams.add_member(121990, 'JNRowe') + assert_equals(users[0].login, 'JNRowe') From de1f059f7ff5b5a1f202c68441d748dd9e39baab Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 20 Dec 2011 05:51:50 +0000 Subject: [PATCH 033/110] Use system certificates database, if possible. Closes #68. --- doc/api/request.rst | 2 ++ github2/request.py | 28 ++++++++++++++++++++++++---- tests/utils.py | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/doc/api/request.rst b/doc/api/request.rst index 395f39f..f58fd0a 100644 --- a/doc/api/request.rst +++ b/doc/api/request.rst @@ -10,6 +10,8 @@ Requests .. autodata:: GITHUB_URL +.. autodata:: SYSTEM_CERTS + .. autoexception:: GithubError .. autoclass:: GithubRequest diff --git a/github2/request.py b/github2/request.py index 1b473fe..abe3a11 100644 --- a/github2/request.py +++ b/github2/request.py @@ -1,8 +1,9 @@ import datetime import logging import re +import sys import time -import httplib2 + try: # For Python 3 from http.client import responses @@ -28,6 +29,8 @@ from cgi import parse_qs from urllib import urlencode, quote +import httplib2 + #: Hostname for API access GITHUB_URL = "https://github.com" @@ -35,6 +38,24 @@ #: Logger for requests module LOGGER = logging.getLogger('github2.request') +#: Whether github2 is using the system's certificates for SSL connections +SYSTEM_CERTS = not httplib2.CA_CERTS.startswith(path.dirname(httplib2.__file__)) +if not SYSTEM_CERTS and sys.platform.startswith('linux'): + for cert_file in ['/etc/ssl/certs/ca-certificates.crt', + '/etc/pki/tls/certs/ca-bundle.crt']: + if path.exists(cert_file): + httplib2.CA_CERTS = cert_file + SYSTEM_CERTS = True + break +elif not SYSTEM_CERTS and sys.platform.startswith('freebsd'): + if path.exists('/usr/local/share/certs/ca-root-nss.crt'): + httplib2.CA_CERTS = '/usr/local/share/certs/ca-root-nss.crt' + SYSTEM_CERTS = True +if SYSTEM_CERTS: + LOGGER.info('Using system certificates in %r', httplib2.CA_CERTS) +else: + LOGGER.warning('Using bundled certificates for HTTPS connections') + def charset_from_headers(headers): """Parse charset from headers @@ -105,12 +126,11 @@ def __init__(self, username=None, api_token=None, url_prefix=None, digicert_ha_cert = path.join(path.dirname(path.abspath(__file__)), "DigiCert_High_Assurance_EV_Root_CA.crt") if proxy_host is None: - self._http = httplib2.Http(cache=cache, ca_certs=digicert_ha_cert) + self._http = httplib2.Http(cache=cache) else: proxy_info = httplib2.ProxyInfo(httplib2.socks.PROXY_TYPE_HTTP, proxy_host, proxy_port) - self._http = httplib2.Http(proxy_info=proxy_info, cache=cache, - ca_certs=digicert_ha_cert) + self._http = httplib2.Http(proxy_info=proxy_info, cache=cache) def encode_authentication_data(self, extra_post_data): post_data = {} diff --git a/tests/utils.py b/tests/utils.py index 0657cfa..a1c32b4 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -25,7 +25,7 @@ class HttpMock(object): Implementation tests should never span network boundaries """ - def __init__(self, cache=None, timeout=None, proxy_info=None, ca_certs=None): + def __init__(self, cache=None, timeout=None, proxy_info=None): """Create a mock httplib.Http object .. attribute: called_with From d32273af8b67a671bab242c9808a309f07398108 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 20 Dec 2011 20:36:26 +0000 Subject: [PATCH 034/110] Fix for users unable to use system certificates. Regression that snuck in de1f059f7ff5b5a1f202c68441d748dd9e39baab. --- github2/request.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/github2/request.py b/github2/request.py index 3650265..21d73f0 100644 --- a/github2/request.py +++ b/github2/request.py @@ -123,14 +123,15 @@ def __init__(self, username=None, api_token=None, url_prefix=None, "api_version": self.api_version, "api_format": self.api_format, } - digicert_ha_cert = path.join(path.dirname(path.abspath(__file__)), - "DigiCert_High_Assurance_EV_Root_CA.crt") if proxy_host is None: self._http = httplib2.Http(cache=cache) else: proxy_info = httplib2.ProxyInfo(httplib2.socks.PROXY_TYPE_HTTP, proxy_host, proxy_port) self._http = httplib2.Http(proxy_info=proxy_info, cache=cache) + if not SYSTEM_CERTS: + self._http.ca_certs = path.join(path.dirname(path.abspath(__file__)), + "DigiCert_High_Assurance_EV_Root_CA.crt") def encode_authentication_data(self, extra_post_data): post_data = [] From ec5412d5ef15f841888f71676aeea2e1cb7cc206 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 21 Dec 2011 08:03:01 +0000 Subject: [PATCH 035/110] Added a link for finding the full history to NEWS. --- NEWS.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index cebb8ac..2d98764 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -1,6 +1,11 @@ User-visible changes ==================== +This file lists only the most important changes that may be visible to users, +look at the `git repository`_ for the full project history. + +.. _git repository: https://github.com/ask/python-github2/ + .. contents:: 0.5.2 - 2011-09-02 From 98a96475f060b0a66fb5aa06258b1c8ce4d3c959 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 21 Dec 2011 08:09:26 +0000 Subject: [PATCH 036/110] Bumped version to 0.6.0. --- NEWS.rst | 6 ++++++ README.rst | 2 +- github2/__init__.py | 7 +++++-- github2/_version.py | 9 +++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 github2/_version.py diff --git a/NEWS.rst b/NEWS.rst index 2d98764..54c693b 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -8,6 +8,12 @@ look at the `git repository`_ for the full project history. .. contents:: +0.6.0 - 2011-12-21 +------------------ + +* Now uses system certificates for SSL validation where possible +* Python 3 is supported directly, without a separate ``2to3`` build step + 0.5.2 - 2011-09-02 ------------------ diff --git a/README.rst b/README.rst index 0746644..804dc81 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ github2 - Github API v2 library for Python. :Authors: Ask Solem (askh@opera.com) -:Version: 0.5.2 +:Version: 0.6.0 This is a Python library implementing all of the features available in version 2 of the `Github API`_. diff --git a/github2/__init__.py b/github2/__init__.py index ce95e04..30d323e 100644 --- a/github2/__init__.py +++ b/github2/__init__.py @@ -1,7 +1,10 @@ "Github API v2 library for Python" -VERSION = (0, 5, 2) + +from github2 import _version + +VERSION = _version.tuple __author__ = "Ask Solem" __contact__ = "askh@opera.com" __homepage__ = "http://github.com/ask/python-github2" -__version__ = ".".join(map(str, VERSION)) +__version__ = _version.dotted diff --git a/github2/_version.py b/github2/_version.py new file mode 100644 index 0000000..bf9f4df --- /dev/null +++ b/github2/_version.py @@ -0,0 +1,9 @@ +# This is github2 version 0.6.0 (2011-12-21) +# pylint: disable=C0103, C0111, C0121, W0622 + +dotted = "0.6.0" +libtool = "6:20" +hex = 0x000600 +date = "2011-12-21" +tuple = (0, 6, 0) +web = "github/0.6.0" From 57450e7473303f28d9030e8897ed61f778977883 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 21 Dec 2011 11:56:48 +0000 Subject: [PATCH 037/110] Minor rewording in bugs doc. --- doc/bugs.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/bugs.rst b/doc/bugs.rst index 2226397..6105987 100644 --- a/doc/bugs.rst +++ b/doc/bugs.rst @@ -24,7 +24,7 @@ or a deficiency in the API. You can check which URLs your code is requesting by enabling :data:`~logging.DEBUG` level output in your logger, see the -:mod:`python:logging` for more information. +:mod:`python:logging` documentation for details. If the bug you've found is outside the reach of this project an issue should be opened in GitHub's `API support forum`_. It doesn't hurt to `report an issue`_ @@ -45,10 +45,10 @@ A good bug report will have the following: * A minimal test-case to reproduce the error * A list of solutions you've already tried -Simon Tatham has an excellent essay titled `How to Report Bugs Effectively`_, +Simon Tatham wrote aa fantastic essay titled `How to Report Bugs Effectively`_, with some excellent tips on filing good bug reports. -.. [#] The content of :data:`github2.__version__` if you're using an official +.. [#] The value of :data:`github2.__version__` if you're using an official release, or the output of :command:`git describe` if you're using the git repository directly. From baa6a04ac6d5d1c207796a8f9eaa0b8c4fbe9332 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 21 Dec 2011 11:57:17 +0000 Subject: [PATCH 038/110] Fixed broken Python 2.4 handling in github2.requests. --- github2/request.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/github2/request.py b/github2/request.py index 21d73f0..d3c25a2 100644 --- a/github2/request.py +++ b/github2/request.py @@ -8,11 +8,12 @@ # For Python 3 from http.client import responses except ImportError: # For Python 2.5-2.7 - from httplib import responses -except ImportError: # For Python 2.4 - from BaseHTTPServer import BaseHTTPRequestHandler - responses = dict([(k, v[0]) - for k, v in BaseHTTPRequestHandler.responses.items()]) + try: + from httplib import responses + except ImportError: # For Python 2.4 + from BaseHTTPServer import BaseHTTPRequestHandler + responses = dict([(k, v[0]) + for k, v in BaseHTTPRequestHandler.responses.items()]) try: import json as simplejson # For Python 2.6+ except ImportError: From 4c2b325f387794be21a6fb30113fcb89b9ddd413 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 14 Jan 2012 12:19:30 +0000 Subject: [PATCH 039/110] Skip unrecognised HTTP status lookups in HttpError. Closes #71, thanks to Ben Olive for the report. --- github2/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github2/request.py b/github2/request.py index d3c25a2..297a4f1 100644 --- a/github2/request.py +++ b/github2/request.py @@ -89,7 +89,7 @@ def __init__(self, message, content, code): self.message = message self.content = content self.code = code - if code and responses: + if code in responses: self.code_reason = responses[code] else: self.code_reason = "" From dcd608886996528f6b75a0f80324b9807f08847d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 14 Jan 2012 12:20:06 +0000 Subject: [PATCH 040/110] Converted remaining warnings users to logging. --- github2/core.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/github2/core.py b/github2/core.py index cb75f9b..b15161f 100644 --- a/github2/core.py +++ b/github2/core.py @@ -1,11 +1,13 @@ +import logging import sys -from warnings import warn - from datetime import datetime from dateutil import (parser, tz) +#: Logger for core module +LOGGER = logging.getLogger('github2.core') + #: Running under Python 3 PY3K = sys.version_info[0] == 3 @@ -281,8 +283,9 @@ def __getitem__(self, key): This is here purely to maintain compatibility when switching ``dict`` responses to ``BaseData`` derived objects. """ - warn("Subscript access on %r is deprecated, use object attributes" - % self.__class__.__name__, DeprecationWarning) + LOGGER.warning("Subscript access on %r is deprecated, use object " + "attributes" % self.__class__.__name__, + DeprecationWarning) if not key in self._meta.keys(): raise KeyError(key) return getattr(self, key) @@ -292,8 +295,9 @@ def __setitem__(self, key, value): :see: ``BaseData.__getitem__`` """ - warn("Subscript access on %r is deprecated, use object attributes" - % self.__class__.__name__, DeprecationWarning) + LOGGER.warning("Subscript access on %r is deprecated, use object " + "attributes" % self.__class__.__name__, + DeprecationWarning) if not key in self._meta.keys(): raise KeyError(key) setattr(self, key, value) From e3a239a025e992932a2a5d21122f7159ae95e2e0 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 14 Jan 2012 12:26:00 +0000 Subject: [PATCH 041/110] Fixed silly DST straddling delay bug. Incredibly unlikely to occur, but annoying as hell if it did ;) --- github2/request.py | 4 ++-- tests/test_unit.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/github2/request.py b/github2/request.py index 297a4f1..3b6ba47 100644 --- a/github2/request.py +++ b/github2/request.py @@ -170,7 +170,7 @@ def delete(self, *path_components, **extra_post_data): def make_request(self, path, extra_post_data=None, method="GET"): if self.delay: - since_last = (datetime.datetime.now() - self.last_request) + since_last = (datetime.datetime.utcnow() - self.last_request) since_last_in_seconds = (since_last.days * 24 * 60 * 60) + since_last.seconds + (since_last.microseconds/1000000.0) if since_last_in_seconds < self.delay: duration = self.delay - since_last_in_seconds @@ -182,7 +182,7 @@ def make_request(self, path, extra_post_data=None, method="GET"): result = self.raw_request(url, extra_post_data, method=method) if self.delay: - self.last_request = datetime.datetime.now() + self.last_request = datetime.datetime.utcnow() return result def raw_request(self, url, extra_post_data, method="GET"): diff --git a/tests/test_unit.py b/tests/test_unit.py index b90a0bc..c72f3ef 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -28,9 +28,9 @@ def test_delays(self): """Test call delay is at least one second""" client = Github(requests_per_second=.5) client.users.show('defunkt') - start = datetime.datetime.now() + start = datetime.datetime.utcnow() client.users.show('mojombo') - end = datetime.datetime.now() + end = datetime.datetime.utcnow() delta = end - start delta_seconds = delta.days * 24 * 60 * 60 + delta.seconds From 61b572e516b2079f1eac12c9732b47bd71b0fc5c Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 14 Jan 2012 12:32:34 +0000 Subject: [PATCH 042/110] Scrubbed unused imports in tests. --- tests/test_repositories.py | 1 - tests/test_user.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/tests/test_repositories.py b/tests/test_repositories.py index 001fe61..b55f4d5 100644 --- a/tests/test_repositories.py +++ b/tests/test_repositories.py @@ -2,7 +2,6 @@ from nose.tools import assert_equals -from github2.client import Github import utils diff --git a/tests/test_user.py b/tests/test_user.py index 3b0f8c3..d61794b 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -2,8 +2,6 @@ from nose.tools import (assert_equals, assert_false, assert_true) -from github2.client import Github - import utils From 6a4380053566e56d1dfd352a1f6de72f13ba17e5 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 14 Jan 2012 12:35:58 +0000 Subject: [PATCH 043/110] Bump copyright years. --- doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index e54a0cc..1fb7895 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -46,7 +46,7 @@ # General information about the project. project = u'github2' -copyright = u'2011, Ask Solem' +copyright = u'2009-2012, Ask Solem' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From 405dbed3397a856ada37840148f6eee25d757a01 Mon Sep 17 00:00:00 2001 From: modocache Date: Thu, 19 Jan 2012 00:19:56 +0900 Subject: [PATCH 044/110] Added support for Github Enterprise hosts. Allows users to pass a parameter specifying the host to send requests to. Closes #72. --- AUTHORS | 1 + doc/api/client.rst | 8 ++++++++ github2/client.py | 5 +++-- github2/request.py | 10 +++++++--- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index 66d4ec9..99f5070 100644 --- a/AUTHORS +++ b/AUTHORS @@ -28,3 +28,4 @@ Christopher MacGown Rok Garbas Ionuț Arțăriși Stéphane Angel +modocache diff --git a/doc/api/client.rst b/doc/api/client.rst index 4edc07b..4954148 100644 --- a/doc/api/client.rst +++ b/doc/api/client.rst @@ -50,4 +50,12 @@ given, is 8080:: >>> github = Github(username="ask", api_token=".......", ... proxy_host="my.proxy.com", proxy_port=9000) +You may specify a GitHub Enterprise URL by passing in the ``github_url`` +setting. If you do not specify ``github_url``, requests will be made to +https://github.com/. + + >>> from github2.client import Github + >>> github = Github(username="modocache", api_token=".......", + ... github_url="http://git.gree-dev.net/") + .. _OAuth service: http://develop.github.com/p/oauth.html diff --git a/github2/client.py b/github2/client.py index a26210d..f761b62 100644 --- a/github2/client.py +++ b/github2/client.py @@ -12,7 +12,7 @@ class Github(object): def __init__(self, username=None, api_token=None, requests_per_second=None, access_token=None, cache=None, proxy_host=None, - proxy_port=8080): + proxy_port=8080, github_url=None): """ An interface to GitHub's API: http://develop.github.com/ @@ -44,7 +44,8 @@ def __init__(self, username=None, api_token=None, requests_per_second=None, requests_per_second=requests_per_second, access_token=access_token, cache=cache, proxy_host=proxy_host, - proxy_port=proxy_port) + proxy_port=proxy_port, + github_url=github_url) self.issues = Issues(self.request) self.users = Users(self.request) self.repos = Repositories(self.request) diff --git a/github2/request.py b/github2/request.py index 3b6ba47..d3d2103 100644 --- a/github2/request.py +++ b/github2/request.py @@ -34,7 +34,7 @@ #: Hostname for API access -GITHUB_URL = "https://github.com" +DEFAULT_GITHUB_URL = "https://github.com" #: Logger for requests module LOGGER = logging.getLogger('github2.request') @@ -96,7 +96,6 @@ def __init__(self, message, content, code): class GithubRequest(object): - github_url = GITHUB_URL url_format = "%(github_url)s/api/%(api_version)s/%(api_format)s" api_version = "v2" api_format = "json" @@ -104,7 +103,8 @@ class GithubRequest(object): def __init__(self, username=None, api_token=None, url_prefix=None, requests_per_second=None, access_token=None, - cache=None, proxy_host=None, proxy_port=None): + cache=None, proxy_host=None, proxy_port=None, + github_url=None): """Make an API request. :see: :class:`github2.client.Github` @@ -113,6 +113,10 @@ def __init__(self, username=None, api_token=None, url_prefix=None, self.api_token = api_token self.access_token = access_token self.url_prefix = url_prefix + if github_url is None: + self.github_url = DEFAULT_GITHUB_URL + else: + self.github_url = github_url if requests_per_second is None: self.delay = 0 else: From 4bb1f50ce0bf7bd16966d0babce67e62194e31fa Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 18 Jan 2012 17:58:59 +0000 Subject: [PATCH 045/110] More silly little PEP-8 fixes. This is what pre-commit hooks supposed to be used for ;) --- github2/bin/manage_collaborators.py | 18 ++++++++++++------ github2/core.py | 10 ++++++---- tests/test_charset_header.py | 1 + tests/test_commits.py | 6 ++++-- tests/test_date_handling.py | 1 + tests/test_organizations.py | 3 ++- tests/test_pull_requests.py | 3 ++- tests/test_repositories.py | 6 ++++-- tests/test_tz_aware_date_handling.py | 2 +- 9 files changed, 33 insertions(+), 17 deletions(-) diff --git a/github2/bin/manage_collaborators.py b/github2/bin/manage_collaborators.py index 821e89d..3efafee 100755 --- a/github2/bin/manage_collaborators.py +++ b/github2/bin/manage_collaborators.py @@ -58,11 +58,14 @@ def parse_commandline(): if len(args) not in [1, 2]: parser.error('wrong number of arguments') if (len(args) == 1 and args[0] in ['add', 'remove']): - parser.error('%r needs a collaborator name as second parameter\n' % args[0]) + parser.error('%r needs a collaborator name as second parameter\n' + % args[0]) elif (len(args) == 1 and args[0] != 'list'): - parser.error('unknown command %r. Try "list", "add" or "remove"\n' % args[0]) + parser.error('unknown command %r. Try "list", "add" or "remove"\n' + % args[0]) if (len(args) == 2 and args[0] not in ['add', 'remove']): - parser.error('unknown command %r. Try "list", "add" or "remove"\n' % args[0]) + parser.error('unknown command %r. Try "list", "add" or "remove"\n' + % args[0]) if not options.login: parser.error('you must provide --login information\n') @@ -88,12 +91,15 @@ def main(): datefmt="%Y-%m-%dT%H:%M:%S") if len(args) == 1: for repos in github.repos.list(options.account): - fullreposname = github.project_for_user_repo(options.account, repos.name) - print_("%s: %s" % (repos.name, ' '.join(github.repos.list_collaborators(fullreposname)))) + fullreposname = github.project_for_user_repo(options.account, + repos.name) + collabs = github.repos.list_collaborators(fullreposname) + print_("%s: %s" % (repos.name, ' '.join(collabs))) elif len(args) == 2: command, collaborator = args for repos in github.repos.list(options.account): - fullreposname = github.project_for_user_repo(options.account, repos.name) + fullreposname = github.project_for_user_repo(options.account, + repos.name) if collaborator in github.repos.list_collaborators(fullreposname): if command == 'remove': github.repos.remove_collaborator(repos.name, collaborator) diff --git a/github2/core.py b/github2/core.py index b15161f..60da833 100644 --- a/github2/core.py +++ b/github2/core.py @@ -167,7 +167,8 @@ def get_value(self, *args, **kwargs): # unicode keys are not accepted as kwargs by python, until 2.7: # http://bugs.python.org/issue2646 # So we make a local dict with the same keys but as strings: - return datatype(**dict((str(k), v) for (k, v) in value.items())) + return datatype(**dict((str(k), v) + for (k, v) in value.items())) else: return datatype(**value) return value @@ -177,9 +178,10 @@ def get_values(self, *args, **kwargs): values = self.make_request(*args, **kwargs) if datatype: if not PY27: - # Same as above, unicode keys will blow up in **args, so we need to - # create a new 'values' dict with string keys - return [datatype(**dict((str(k), v) for (k, v) in value.items())) + # Same as above, unicode keys will blow up in **args, so we + # need to create a new 'values' dict with string keys + return [datatype(**dict((str(k), v) + for (k, v) in value.items())) for value in values] else: return [datatype(**value) for value in values] diff --git a/tests/test_charset_header.py b/tests/test_charset_header.py index b495bfc..40aff70 100644 --- a/tests/test_charset_header.py +++ b/tests/test_charset_header.py @@ -7,6 +7,7 @@ def no_match_test(): d = {} assert_equals("ascii", charset_from_headers(d)) + def utf_test(): d = {'content-type': 'application/json; charset=utf-8'} assert_equals("utf-8", charset_from_headers(d)) diff --git a/tests/test_commits.py b/tests/test_commits.py index 337bffb..5d4ee8e 100644 --- a/tests/test_commits.py +++ b/tests/test_commits.py @@ -8,6 +8,7 @@ class CommitProperties(utils.HttpMockTestCase): """Test commit property handling""" commit_id = '1c83cde9b5a7c396a01af1007fb7b88765b9ae45' + def test_commit(self): commit = self.client.commits.show('ask/python-github2', self.commit_id) assert_equals(commit.message, @@ -25,8 +26,8 @@ def test_commit(self): assert_equals(commit.committer['login'], 'JNRowe') assert_equals(commit.added, None) assert_equals(commit.removed, None) - assert_equals(commit.modified[0]['filename'], 'github2/bin/manage_collaborators.py') - + assert_equals(commit.modified[0]['filename'], + 'github2/bin/manage_collaborators.py') def test_repr(self): commit = self.client.commits.show('ask/python-github2', self.commit_id) @@ -36,6 +37,7 @@ def test_repr(self): class CommitsQueries(utils.HttpMockTestCase): """Test commit querying""" + def test_list(self): commits = self.client.commits.list('JNRowe/misc-overlay') assert_equals(len(commits), 35) diff --git a/tests/test_date_handling.py b/tests/test_date_handling.py index dcfea34..fabc8d5 100644 --- a/tests/test_date_handling.py +++ b/tests/test_date_handling.py @@ -114,6 +114,7 @@ def test_datetime_to_commitdate(): assert_equals(datetime_to_commitdate(dt(2011, 4, 9, 9, 53, 0)), '2011-04-09T09:53:00-07:00') + def test_isodate_to_datetime(): assert_equals(string_to_datetime('2011-05-22T00:24:15Z'), dt(2011, 5, 22, 0, 24, 15)) diff --git a/tests/test_organizations.py b/tests/test_organizations.py index dee751e..9f4e56b 100644 --- a/tests/test_organizations.py +++ b/tests/test_organizations.py @@ -63,7 +63,8 @@ def test_add_team(self): def test_add_team_with_repos(self): projects = ['JNRowe-test-org/test1', 'JNRowe-test-org/test2'] team = self.client.organizations.add_team('JNRowe-test-org', - 'test_push', 'push', projects) + 'test_push', 'push', + projects) team_repos = self.client.teams.repositories(team.id) assert_equals(['/'.join([x.organization, x.name]) for x in team_repos], diff --git a/tests/test_pull_requests.py b/tests/test_pull_requests.py index 129e502..50197ce 100644 --- a/tests/test_pull_requests.py +++ b/tests/test_pull_requests.py @@ -52,7 +52,8 @@ class PullRequestQueries(utils.HttpMockTestCase): def test_list(self): pull_requests = self.client.pull_requests.list('ask/python-github2') assert_equals(len(pull_requests), 1) - assert_equals(pull_requests[0].title, 'Pagination support for commits.') + assert_equals(pull_requests[0].title, + 'Pagination support for commits.') def test_list_with_page(self): pull_requests = self.client.pull_requests.list('robbyrussell/oh-my-zsh', diff --git a/tests/test_repositories.py b/tests/test_repositories.py index b55f4d5..fc5f6f4 100644 --- a/tests/test_repositories.py +++ b/tests/test_repositories.py @@ -95,12 +95,14 @@ def test_languages(self): def test_tags(self): tags = self.client.repos.tags('ask/python-github2') assert_equals(len(tags), 7) - assert_equals(tags['0.4.1'], '96b0a41dd249c521323700bc11a0a721a7c9e642') + assert_equals(tags['0.4.1'], + '96b0a41dd249c521323700bc11a0a721a7c9e642') def test_branches(self): branches = self.client.repos.branches('ask/python-github2') assert_equals(len(branches), 1) - assert_equals(branches['master'], '1c83cde9b5a7c396a01af1007fb7b88765b9ae45') + assert_equals(branches['master'], + '1c83cde9b5a7c396a01af1007fb7b88765b9ae45') def test_watchers(self): watchers = self.client.repos.watchers('ask/python-github2') diff --git a/tests/test_tz_aware_date_handling.py b/tests/test_tz_aware_date_handling.py index 4e4f6eb..ccc224f 100644 --- a/tests/test_tz_aware_date_handling.py +++ b/tests/test_tz_aware_date_handling.py @@ -16,7 +16,7 @@ def setup_module(): def teardown_module(): - """Disable timezone-aware datetime handling when finished with this module""" + """Disable timezone-aware datetime handling when tests have completed""" core.NAIVE = True From f6c908faa49bb013e529da2305674846e2bc440d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 18 Jan 2012 18:00:09 +0000 Subject: [PATCH 046/110] Simplify delay time calculation. Would still be far easier timedelta.total_seconds(), but Python <2.7 compatibility denies us that luxury. --- github2/request.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/github2/request.py b/github2/request.py index d3d2103..2d4b584 100644 --- a/github2/request.py +++ b/github2/request.py @@ -175,10 +175,9 @@ def delete(self, *path_components, **extra_post_data): def make_request(self, path, extra_post_data=None, method="GET"): if self.delay: since_last = (datetime.datetime.utcnow() - self.last_request) - since_last_in_seconds = (since_last.days * 24 * 60 * 60) + since_last.seconds + (since_last.microseconds/1000000.0) - if since_last_in_seconds < self.delay: - duration = self.delay - since_last_in_seconds - LOGGER.warning("delaying API call %s second(s)", duration) + if since_last.days == 0 and since_last.seconds < self.delay: + duration = self.delay - since_last.seconds + LOGGER.warning("delaying API call %g second(s)", duration) time.sleep(duration) extra_post_data = extra_post_data or {} From 95af393c7ad04a5ef33d2aee29e8c0f504e187c9 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 18 Jan 2012 18:01:21 +0000 Subject: [PATCH 047/110] Added test for host URL propagation. --- tests/test_unit.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_unit.py b/tests/test_unit.py index c72f3ef..76c637a 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -22,6 +22,16 @@ def test_issue(self): assert_equals(str, type(repr(i))) +class HostSetting(unittest.TestCase): + def test_default_host(self): + client = Github() + assert_equals(client.request.github_url, 'https://github.com') + + def test_non_standard_host(self): + client = Github(github_url="http://git.gree-dev.net/") + assert_equals(client.request.github_url, 'http://git.gree-dev.net/') + + class RateLimits(utils.HttpMockTestCase): """Test API rate-limitting""" def test_delays(self): From 478e2a38ef13956c7902374c77d44c77adbb7168 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 18 Jan 2012 18:54:47 +0000 Subject: [PATCH 048/110] Don't override httplib2 certificates at module level. This creates problems when other parts of a runtime are using httplib2 with custom bundles. --- github2/request.py | 11 ++++++----- tests/utils.py | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/github2/request.py b/github2/request.py index 2d4b584..0019623 100644 --- a/github2/request.py +++ b/github2/request.py @@ -45,17 +45,19 @@ for cert_file in ['/etc/ssl/certs/ca-certificates.crt', '/etc/pki/tls/certs/ca-bundle.crt']: if path.exists(cert_file): - httplib2.CA_CERTS = cert_file + CA_CERTS = cert_file SYSTEM_CERTS = True break elif not SYSTEM_CERTS and sys.platform.startswith('freebsd'): if path.exists('/usr/local/share/certs/ca-root-nss.crt'): - httplib2.CA_CERTS = '/usr/local/share/certs/ca-root-nss.crt' + CA_CERTS = '/usr/local/share/certs/ca-root-nss.crt' SYSTEM_CERTS = True if SYSTEM_CERTS: LOGGER.info('Using system certificates in %r', httplib2.CA_CERTS) else: LOGGER.warning('Using bundled certificates for HTTPS connections') + CA_CERTS = path.join(path.dirname(path.abspath(__file__)), + "DigiCert_High_Assurance_EV_Root_CA.crt") def charset_from_headers(headers): @@ -134,9 +136,8 @@ def __init__(self, username=None, api_token=None, url_prefix=None, proxy_info = httplib2.ProxyInfo(httplib2.socks.PROXY_TYPE_HTTP, proxy_host, proxy_port) self._http = httplib2.Http(proxy_info=proxy_info, cache=cache) - if not SYSTEM_CERTS: - self._http.ca_certs = path.join(path.dirname(path.abspath(__file__)), - "DigiCert_High_Assurance_EV_Root_CA.crt") + self._http.ca_certs = CA_CERTS + def encode_authentication_data(self, extra_post_data): post_data = [] diff --git a/tests/utils.py b/tests/utils.py index a1c32b4..cbd41cc 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -25,7 +25,8 @@ class HttpMock(object): Implementation tests should never span network boundaries """ - def __init__(self, cache=None, timeout=None, proxy_info=None): + def __init__(self, cache=None, timeout=None, proxy_info=None, + ca_certs=None): """Create a mock httplib.Http object .. attribute: called_with From a7e495f306fdf69ce81109b92e41f0014e104119 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 18 Jan 2012 18:56:25 +0000 Subject: [PATCH 049/110] Append 422 status to HTTP responses dict. --- github2/request.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/github2/request.py b/github2/request.py index 0019623..3066702 100644 --- a/github2/request.py +++ b/github2/request.py @@ -60,6 +60,11 @@ "DigiCert_High_Assurance_EV_Root_CA.crt") +# Common missing entries from the HTTP status code dict, basically anything +# GitHub reports that isn't basic HTTP/1.1. +responses[422] = 'Unprocessable Entity' + + def charset_from_headers(headers): """Parse charset from headers From 3bd621cddefc55acb34cf8d55ba58d5061b332ed Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 18 Jan 2012 19:05:34 +0000 Subject: [PATCH 050/110] Warn about bundled certs on creation not import. --- github2/request.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github2/request.py b/github2/request.py index 3066702..5c9f555 100644 --- a/github2/request.py +++ b/github2/request.py @@ -52,10 +52,7 @@ if path.exists('/usr/local/share/certs/ca-root-nss.crt'): CA_CERTS = '/usr/local/share/certs/ca-root-nss.crt' SYSTEM_CERTS = True -if SYSTEM_CERTS: - LOGGER.info('Using system certificates in %r', httplib2.CA_CERTS) else: - LOGGER.warning('Using bundled certificates for HTTPS connections') CA_CERTS = path.join(path.dirname(path.abspath(__file__)), "DigiCert_High_Assurance_EV_Root_CA.crt") @@ -142,7 +139,10 @@ def __init__(self, username=None, api_token=None, url_prefix=None, proxy_host, proxy_port) self._http = httplib2.Http(proxy_info=proxy_info, cache=cache) self._http.ca_certs = CA_CERTS - + if SYSTEM_CERTS: + LOGGER.info('Using system certificates in %r', CA_CERTS) + else: + LOGGER.warning('Using bundled certificate for HTTPS connections') def encode_authentication_data(self, extra_post_data): post_data = [] From b08b9b78664bfbf462ca722f5b5dedca7e441631 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 18 Jan 2012 19:06:30 +0000 Subject: [PATCH 051/110] Added warning for unknown HTTP status. --- github2/request.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/github2/request.py b/github2/request.py index 5c9f555..d6190e2 100644 --- a/github2/request.py +++ b/github2/request.py @@ -96,7 +96,8 @@ def __init__(self, message, content, code): if code in responses: self.code_reason = responses[code] else: - self.code_reason = "" + self.code_reason = "" + LOGGER.warning('Unknown HTTP status %r, please file an issue', code) class GithubRequest(object): From 6f8131301bcb36f624f13b09f1b588c4c7cf4b14 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 9 Feb 2012 11:01:20 +0000 Subject: [PATCH 052/110] Ignore .pyo files. Test runner is completing a run with -O too now. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index de35dbe..ea2d6d3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ .noseids .ropeproject/ .tox/ -*.pyc +*.py[co] *~ *.sqlite *.sqlite-journal From c22e2be078aefefba8113fc343e371b3d8e30ed4 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 9 Feb 2012 11:06:13 +0000 Subject: [PATCH 053/110] Added Repository source attribute. --- github2/repositories.py | 1 + tests/test_repositories.py | 1 + 2 files changed, 2 insertions(+) diff --git a/github2/repositories.py b/github2/repositories.py index cbd9ad4..89f8e57 100644 --- a/github2/repositories.py +++ b/github2/repositories.py @@ -24,6 +24,7 @@ class Repository(BaseData): has_issues = Attribute("If True, this repository has an issue tracker.") language = Attribute("Primary language for the repository.") parent = Attribute("The parent project of this fork.") + source = Attribute("The root project of this fork") def _project(self): return self.owner + "/" + self.name diff --git a/tests/test_repositories.py b/tests/test_repositories.py index fc5f6f4..63f39c0 100644 --- a/tests/test_repositories.py +++ b/tests/test_repositories.py @@ -48,6 +48,7 @@ def test_fork_properties(self): assert_equals(repo.forks, 0) assert_equals(repo.fork, True) assert_equals(repo.parent, 'ask/python-github2') + assert_equals(repo.source, 'ask/python-github2') class RepoQueries(utils.HttpMockTestCase): From 95cc0d93cc0b5ff6ba55ce9b1e9a6e647433611e Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 9 Feb 2012 11:07:39 +0000 Subject: [PATCH 054/110] [QA] Silly typo. --- github2/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github2/request.py b/github2/request.py index d6190e2..b8588de 100644 --- a/github2/request.py +++ b/github2/request.py @@ -77,7 +77,7 @@ def charset_from_headers(headers): class GithubError(Exception): - """An error occured when making a request to the Github API.""" + """An error occurred when making a request to the Github API.""" class HttpError(RuntimeError): From 0f672e72a1e3e18ba5d843723d77cd2c39d980ff Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 10 Feb 2012 14:18:54 +0000 Subject: [PATCH 055/110] Added support for mangling SSH keys. Refs #73. --- doc/api/users.rst | 2 ++ github2/users.py | 35 +++++++++++++++++++ ...token=xxx,f95947b79ef9d668b2ebac9a591a2a36 | 16 +++++++++ tests/test_user.py | 4 +++ 4 files changed, 57 insertions(+) create mode 100644 tests/data/github.com,api,v2,json,user,keys,access_token=xxx,f95947b79ef9d668b2ebac9a591a2a36 diff --git a/doc/api/users.rst b/doc/api/users.rst index 36f086d..052092a 100644 --- a/doc/api/users.rst +++ b/doc/api/users.rst @@ -13,6 +13,8 @@ Users .. autoclass:: Users(type) +.. autoclass:: Key(type) + Examples -------- diff --git a/github2/users.py b/github2/users.py index 7dba3e6..f2282b2 100644 --- a/github2/users.py +++ b/github2/users.py @@ -7,6 +7,15 @@ enhanced_by_auth, requires_auth) +class Key(BaseData): + id = Attribute('The key id') + key = Attribute('The SSH key data') + title = Attribute('The title for the SSH key') + + def __repr__(self): + return "" % self.id + + class User(BaseData): id = Attribute("The user id") login = Attribute("The login username") @@ -102,3 +111,29 @@ def unfollow(self, other_user): :param str other_user: Github user name """ return self.get_values("unfollow", other_user, method="POST") + + @requires_auth + def list_keys(self): + """Get list of SSH keys for the authenticated user""" + return self.get_values('keys', filter='public_keys', datatype=Key) + + @requires_auth + def add_key(self, key, title=''): + """Add a SSH key for the authenticated user + + :param str key: SSH key identifier + :param str title: Optional title for the SSH key + """ + return self.get_values("key/add", + post_data={'key': key, 'title': title}, + method="POST", filter='public_keys', + datatype=Key) + + @requires_auth + def remove_key(self, key_id): + """Remove a SSH key for the authenticated user + + :param int key_id: SSH key's GitHub identifier + """ + return self.get_values('key/remove', post_data={'id': str(key_id)}, + filter='public_keys', datatype=Key) diff --git a/tests/data/github.com,api,v2,json,user,keys,access_token=xxx,f95947b79ef9d668b2ebac9a591a2a36 b/tests/data/github.com,api,v2,json,user,keys,access_token=xxx,f95947b79ef9d668b2ebac9a591a2a36 new file mode 100644 index 0000000..ef84a1d --- /dev/null +++ b/tests/data/github.com,api,v2,json,user,keys,access_token=xxx,f95947b79ef9d668b2ebac9a591a2a36 @@ -0,0 +1,16 @@ +status: 200 +x-ratelimit-remaining: 60 +content-location: https://github.com/api/v2/json/user/keys?access_token=xxx +-content-encoding: gzip +connection: keep-alive +content-length: 94 +server: nginx/1.0.4 +x-runtime: 7 +x-ratelimit-limit: 60 +etag: "1df3e8616495dcf01a4fb79fa450c544" +cache-control: private, max-age=0, must-revalidate +date: Fri, 10 Feb 2012 13:53:29 GMT +x-frame-options: deny +content-type: application/json; charset=utf-8 + +{"public_keys":[{"title":"My sekret key","id":1337,"key":"ssh-rsa DoYouSee key@example.com"}]} diff --git a/tests/test_user.py b/tests/test_user.py index d61794b..aff6ad5 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -62,6 +62,10 @@ def test_is_authenticated(self): user = self.client.users.show('') assert_true(user.is_authenticated() is True) + def test_list_keys(self): + keys = self.client.users.list_keys() + assert_equals(keys[0].id, 1337) + class AuthenticatedUserProperties(utils.HttpMockAuthenticatedTestCase): def test_private_data(self): From f2a0671d15a3de611f7df03c20b20bafb83fd0a4 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 10 Feb 2012 14:19:56 +0000 Subject: [PATCH 056/110] Fixed GITHUB_URL doc reference. Should have been fixed along with 405dbed3397a856ada37840148f6eee25d757a01, whoops. --- doc/api/request.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/request.rst b/doc/api/request.rst index f58fd0a..eb126ec 100644 --- a/doc/api/request.rst +++ b/doc/api/request.rst @@ -8,7 +8,7 @@ Requests of the :mod:`github2` package, but it is documented to aid contributors to the package. -.. autodata:: GITHUB_URL +.. autodata:: DEFAULT_GITHUB_URL .. autodata:: SYSTEM_CERTS From a8513b44f7db508323e7a6c6ad448646c84de9e0 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 10 Feb 2012 14:21:16 +0000 Subject: [PATCH 057/110] [QA] Fix wild spelling of 'authentication'. --- github2/users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github2/users.py b/github2/users.py index f2282b2..1cd5ac6 100644 --- a/github2/users.py +++ b/github2/users.py @@ -41,7 +41,7 @@ class User(BaseData): format="user") def is_authenticated(self): - """Test for user auththenication + """Test for user authentication :return bool: ``True`` if user is authenticated""" return self.plan is not None From 3221df99b027964d1b631204a49df67e4e48f8b7 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 10 Feb 2012 19:42:39 +0000 Subject: [PATCH 058/110] Correct decorated function signatures in Sphinx output. --- doc/conf.py | 13 +++++++++++++ github2/core.py | 1 + 2 files changed, 14 insertions(+) diff --git a/doc/conf.py b/doc/conf.py index 1fb7895..9675450 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -13,6 +13,8 @@ import sys, os +from sphinx.util import inspect + import cloud_sptheme as csp # If extensions (or modules to document with autodoc) are in another directory, @@ -229,3 +231,14 @@ intersphinx_mapping = { 'python': ('http://docs.python.org/', os.getenv('SPHINX_PYTHON_OBJECTS')) } + + +# Horrific nastiness to generate correct function signature for decorated +# objects. Close your eyes... Now! +orig_getargspec = inspect.getargspec +def getargspec(func): + if hasattr(func, '__orig_func__'): + return orig_getargspec(func.__orig_func__) + else: + return orig_getargspec(func) +inspect.getargspec = getargspec diff --git a/github2/core.py b/github2/core.py index 60da833..9898be0 100644 --- a/github2/core.py +++ b/github2/core.py @@ -113,6 +113,7 @@ def wrapper(self, *args, **kwargs): % f.__name__) return f(self, *args, **kwargs) wrapped = wrapper + wrapped.__orig_func__ = f wrapped.__name__ = f.__name__ wrapped.__doc__ = f.__doc__ + """\n.. warning:: Requires authentication""" wrapped.requires_auth = True From 7162ef26f636b2f1e34242ec619c73ef12c0c2c5 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 10 Feb 2012 19:46:04 +0000 Subject: [PATCH 059/110] [QA] Fix PEP-8 compliance in Sphinx config. --- doc/conf.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 9675450..ea950db 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -3,7 +3,8 @@ # python-github2 documentation build configuration file, created by # sphinx-quickstart on Mon Apr 11 16:16:25 2011. # -# This file is execfile()d with the current directory set to its containing dir. +# This file is execfile()d with the current directory set to its containing +# dir. # # Note that not all possible configuration values are present in this # autogenerated file. @@ -11,7 +12,8 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import os +import sys from sphinx.util import inspect @@ -22,13 +24,13 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('..')) -# -- General configuration ----------------------------------------------------- +# -- General configuration ---------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ["sphinx.ext.%s" % ext for ext in ["autodoc", "todo", "intersphinx", "viewcode", "coverage"]] + \ @@ -74,7 +76,8 @@ # directories to ignore when looking for source files. exclude_patterns = ['.build'] -# The reST default role (used for this markup: `text`) to use for all documents. +# The reST default role (used for this markup: `text`) to use for all +# documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. @@ -95,7 +98,7 @@ #modindex_common_prefix = [] -# -- Options for HTML output --------------------------------------------------- +# -- Options for HTML output -------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. @@ -177,7 +180,7 @@ htmlhelp_basename = 'github2doc' -# -- Options for LaTeX output -------------------------------------------------- +# -- Options for LaTeX output ------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' @@ -186,7 +189,8 @@ #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). +# (source start file, target name, title, author, +# documentclass [howto/manual]). latex_documents = [ ('index', 'github2.tex', u'github2 Documentation', u'Ask Solem', 'manual'), @@ -216,7 +220,7 @@ #latex_domain_indices = True -# -- Options for manual page output -------------------------------------------- +# -- Options for manual page output ------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). @@ -236,6 +240,8 @@ # Horrific nastiness to generate correct function signature for decorated # objects. Close your eyes... Now! orig_getargspec = inspect.getargspec + + def getargspec(func): if hasattr(func, '__orig_func__'): return orig_getargspec(func.__orig_func__) From 34c28268c05180059f86a4fe9d523fb2e4efd584 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 10 Feb 2012 19:46:47 +0000 Subject: [PATCH 060/110] Report correct module in funcs decorated by requires_auth. --- github2/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/github2/core.py b/github2/core.py index 9898be0..6ae08bb 100644 --- a/github2/core.py +++ b/github2/core.py @@ -116,6 +116,7 @@ def wrapper(self, *args, **kwargs): wrapped.__orig_func__ = f wrapped.__name__ = f.__name__ wrapped.__doc__ = f.__doc__ + """\n.. warning:: Requires authentication""" + wrapped.__module__ = f.__module__ wrapped.requires_auth = True return wrapped From 6992c53d2cdc0466fa320f575d3344213a96c3f0 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 10 Feb 2012 19:57:22 +0000 Subject: [PATCH 061/110] Provide a fall back to CURL_CA_BUNDLE. This is only used if we can't discover a system certs location. --- doc/api/request.rst | 1 + github2/request.py | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/api/request.rst b/doc/api/request.rst index eb126ec..0dd71f2 100644 --- a/doc/api/request.rst +++ b/doc/api/request.rst @@ -11,6 +11,7 @@ Requests .. autodata:: DEFAULT_GITHUB_URL .. autodata:: SYSTEM_CERTS +.. autodata:: CURL_CERTS .. autoexception:: GithubError diff --git a/github2/request.py b/github2/request.py index b8588de..3965415 100644 --- a/github2/request.py +++ b/github2/request.py @@ -18,7 +18,7 @@ import json as simplejson # For Python 2.6+ except ImportError: import simplejson -from os import path +from os import (getenv, path) try: # For Python 3 from urllib.parse import (parse_qs, quote, urlencode, urlsplit, urlunsplit) @@ -41,6 +41,8 @@ #: Whether github2 is using the system's certificates for SSL connections SYSTEM_CERTS = not httplib2.CA_CERTS.startswith(path.dirname(httplib2.__file__)) +#: Whether github2 is using the cert's from the file given in $CURL_CA_BUNDLE +CURL_CERTS = False if not SYSTEM_CERTS and sys.platform.startswith('linux'): for cert_file in ['/etc/ssl/certs/ca-certificates.crt', '/etc/pki/tls/certs/ca-bundle.crt']: @@ -52,6 +54,9 @@ if path.exists('/usr/local/share/certs/ca-root-nss.crt'): CA_CERTS = '/usr/local/share/certs/ca-root-nss.crt' SYSTEM_CERTS = True +elif path.exists(getenv('CURL_CA_BUNDLE', '')): + CA_CERTS = getenv('CURL_CA_BUNDLE') + CURL_CERTS = True else: CA_CERTS = path.join(path.dirname(path.abspath(__file__)), "DigiCert_High_Assurance_EV_Root_CA.crt") @@ -142,6 +147,8 @@ def __init__(self, username=None, api_token=None, url_prefix=None, self._http.ca_certs = CA_CERTS if SYSTEM_CERTS: LOGGER.info('Using system certificates in %r', CA_CERTS) + elif CURL_CERTS: + LOGGER.info("Using cURL's certificates in %r", CA_CERTS) else: LOGGER.warning('Using bundled certificate for HTTPS connections') From 2afb1a566e16195e76cd30273fbfd14235c960f4 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 15 Feb 2012 15:23:53 +0000 Subject: [PATCH 062/110] Document the Github github_url parameter. --- github2/client.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/github2/client.py b/github2/client.py index f761b62..c585f3b 100644 --- a/github2/client.py +++ b/github2/client.py @@ -23,6 +23,8 @@ def __init__(self, username=None, api_token=None, requests_per_second=None, The ``cache`` and ``access_token`` parameters .. versionadded:: 0.4.0 The ``proxy_host`` and ``proxy_port`` parameters + .. versionadded:: 0.7.0 + The ``github_url`` parameter :param str username: your own GitHub username. :param str api_token: can be found at https://github.com/account @@ -38,6 +40,8 @@ def __init__(self, username=None, api_token=None, requests_per_second=None, :param str proxy_host: the hostname for the HTTP proxy, if needed. :param str proxy_port: the hostname for the HTTP proxy, if needed (will default to 8080 if a proxy_host is set and no port is set). + :param str github_url: the hostname to connect to, for GitHub + Enterprise support """ self.request = GithubRequest(username=username, api_token=api_token, From 0e768616e38faa5f03ef0dc2decc1bf00f4c9535 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 24 Feb 2012 16:34:06 +0000 Subject: [PATCH 063/110] Added github-issues-export to 'in the wild' document. Refs #74. --- doc/wild.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/wild.rst b/doc/wild.rst index 968358f..78b2298 100644 --- a/doc/wild.rst +++ b/doc/wild.rst @@ -56,6 +56,14 @@ listed on this page. :Git repository: https://github.com/kashifrazzaqui/github-issues +``github-issues-export`` +'''''''''''''''''''''''' + + Script to liberate issues from github issues in case you would like to have + your data free. + +:Git repository: https://github.com/mcepl/github-issues-export + ``github-plots`` '''''''''''''''' From 0a75e3788cd107178d4d9764d784bd86af0c4aef Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 28 Feb 2012 20:07:35 +0000 Subject: [PATCH 064/110] Initial documentation for the binding objects. Closes #70. --- doc/api/core.rst | 8 ++++---- github2/core.py | 42 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/doc/api/core.rst b/doc/api/core.rst index bb96daf..9b9e297 100644 --- a/doc/api/core.rst +++ b/doc/api/core.rst @@ -30,10 +30,10 @@ Core .. autofunction:: repr_string -.. autoclass:: GithubCommand(type) +.. autoclass:: GithubCommand -.. autoclass:: Attribute(type) +.. autoclass:: Attribute -.. autoclass:: DateAttribute(type) +.. autoclass:: DateAttribute(help, format) -.. autoclass:: BaseDataType(type) +.. autoclass:: BaseData() diff --git a/github2/core.py b/github2/core.py index 6ae08bb..ea5afcd 100644 --- a/github2/core.py +++ b/github2/core.py @@ -137,9 +137,24 @@ def enhanced_by_auth(f): class GithubCommand(object): def __init__(self, request): + """Main API binding interface + + :param github2.request.GithubRequest request: HTTP request handler + """ self.request = request def make_request(self, command, *args, **kwargs): + """Make an API request + + Various options are supported if they exist in ``kwargs``: + + * The value of a ``method`` argument will define the HTTP method + to perform for this request, the default is ``GET`` + * The value of a ``filter`` argument will restrict the response to that + data + * The value of a ``page`` argument will be used to fetch a specific + page of results, default of 1 is assumed if not given + """ filter = kwargs.get("filter") post_data = kwargs.get("post_data") or {} page = kwargs.pop("page", 1) @@ -162,6 +177,11 @@ def make_request(self, command, *args, **kwargs): return response def get_value(self, *args, **kwargs): + """Process a single-value response from the API + + If a ``datatype`` parameter is given it defines the + :class:`BaseData`-derived class we should build from the provided data + """ datatype = kwargs.pop("datatype", None) value = self.make_request(*args, **kwargs) if datatype: @@ -176,6 +196,10 @@ def get_value(self, *args, **kwargs): return value def get_values(self, *args, **kwargs): + """Process a multi-value response from the API + + :see: :meth:`get_value` + """ datatype = kwargs.pop("datatype", None) values = self.make_request(*args, **kwargs) if datatype: @@ -208,8 +232,11 @@ def bullet(title, text): class Attribute(object): - def __init__(self, help): + """Generic object attribute for use with :class:`BaseData` + + :param str help: Attribute description + """ self.help = help def to_python(self, value): @@ -228,6 +255,11 @@ class DateAttribute(Attribute): } def __init__(self, *args, **kwargs): + """Date handling attribute for use with :class:`BaseData` + + :param str format: The date format to support, see + :data:`convertor_for_format` for supported options + """ self.format = kwargs.pop("format", self.format) super(DateAttribute, self).__init__(*args, **kwargs) @@ -281,6 +313,12 @@ def iterate(self): # Ugly base class definition for Python 2 and 3 compatibility, where metaclass # syntax is incompatible class BaseData(BaseDataType('BaseData', (object, ), {})): + """Wrapper for API responses + + .. warning:: + Supports subscript attribute access purely for backwards compatibility, + you shouldn't rely on that functionality in new code + """ def __getitem__(self, key): """Access objects's attribute using subscript notation @@ -297,7 +335,7 @@ def __getitem__(self, key): def __setitem__(self, key, value): """Update object's attribute using subscript notation - :see: ``BaseData.__getitem__`` + :see: :meth:`BaseData.__getitem__` """ LOGGER.warning("Subscript access on %r is deprecated, use object " "attributes" % self.__class__.__name__, From f5b5440d10fea1b36d9ec8f9b6b8a3c87674a43f Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 28 Feb 2012 20:08:02 +0000 Subject: [PATCH 065/110] [QA] Missing word in contributing. --- doc/contributing.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/contributing.rst b/doc/contributing.rst index ad3f31c..8c3b47a 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -71,9 +71,9 @@ Many assertions, such as :meth:`~unittest.TestCase.assertIn` and The simple workaround is to evaluate an expression to test with :meth:`~unittest.TestCase.assertTrue` -The incredibly functions for skipping tests(:func:`~unittest.skip`) and marking -expected failures(:func:`~unittest.expectedFailure`) were only added in 2.7, and -unfortunately can't be used. +The incredibly useful functions for skipping tests(:func:`~unittest.skip`) and +marking expected failures(:func:`~unittest.expectedFailure`) were only added in +2.7, and unfortunately can't be used. .. todo:: Add topic branches and pull request usage examples, but most git users are From 915165b2a33cf17b25467b7b61f0c9d07ceb7bc4 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 28 Feb 2012 20:08:46 +0000 Subject: [PATCH 066/110] Added basic release building document. If you can't guess why this is here, then I'd be very surprised indeed. --- doc/index.rst | 1 + doc/release.rst | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 doc/release.rst diff --git a/doc/index.rst b/doc/index.rst index 8656174..fffa939 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -41,6 +41,7 @@ Contents bugs contributing wild + release license Indices and tables diff --git a/doc/release.rst b/doc/release.rst new file mode 100644 index 0000000..b7baf79 --- /dev/null +++ b/doc/release.rst @@ -0,0 +1,63 @@ +Release HOWTO +============= + +.. highlight:: sh + +.. + Much of this stuff is automated locally, but I'm describing the process for + other people who will not have access to the same release tools I use. The + first thing I recommend that you do is find/write a tool that allows you to + automate all of this, or you're going to miss important steps at some point. + +Test +---- + +In the general case tests can be run via :pypi:`nose`'s :pypi:`distribute` +integration:: + + $ ./setup.py nosetests + +When preparing a release it is important to check that :mod:`github2` works with +all currently supported Python versions, and that the documentation is correct. +To that end you can use :pypi:`tox` to run the full testsuite:: + + $ tox -v + +This will test :mod:`github2` with Python 2.4 → 3.2, check that the ``reST`` +syntax is valid and also that the :pypi:`sphinx` documentation builds correctly. +You can run a subset of these options too, see the ``tox`` documentation for +more information. + +Prepare release +--------------- + +With the tests passing, perform the following steps + +* Update the version data in :file:`github2/_version.py`, and also the + reference in :file:`README.rst` +* Update :file:`NEWS.rst`, if there are any user visible changes +* Commit the release notes and version changes +* Create a signed tag for the release +* Push the changes, including the new tag, to the GitHub repository + +Update PyPI +----------- + +.. + This is the section you're especially likely to get wrong at some point if you + try to handle all of this manually ;) + +Create and upload the new release tarballs to PyPI:: + + $ ./setup.py sdist --formats=bztar,gztar register upload --sign + +You should also update the hosted documentation too:: + + $ ./setup.py build_sphinx && ./setup.py upload_docs + +Fetch the uploaded tarballs, and check for errors. + +You should also perform test installations from PyPI, to check the experience +:mod:`github2` users will have. + +.. highlight:: python From f6db79af8670d0d5535ca4dd46b9c133285f3b6d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 28 Feb 2012 20:11:32 +0000 Subject: [PATCH 067/110] [QA] Minor PEP-8 fixes. --- github2/core.py | 7 +++---- github2/organizations.py | 9 ++++++--- github2/pull_requests.py | 12 ++++++------ github2/request.py | 3 ++- tests/test_unit.py | 1 + 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/github2/core.py b/github2/core.py index 6ae08bb..fe171d1 100644 --- a/github2/core.py +++ b/github2/core.py @@ -248,12 +248,11 @@ def __new__(cls, name, bases, attrs): super_new = super(BaseDataType, cls).__new__ _meta = dict([(attr_name, attr_value) - for attr_name, attr_value in attrs.items() - if isinstance(attr_value, Attribute)]) + for attr_name, attr_value in attrs.items() + if isinstance(attr_value, Attribute)]) attrs["_meta"] = _meta attributes = _meta.keys() - attrs.update(dict([(attr_name, None) - for attr_name in attributes])) + attrs.update(dict([(attr_name, None) for attr_name in attributes])) def _contribute_method(name, func): func.__name__ = name diff --git a/github2/organizations.py b/github2/organizations.py index 0c8aa00..38eac83 100644 --- a/github2/organizations.py +++ b/github2/organizations.py @@ -17,10 +17,13 @@ class Organization(BaseData): company = Attribute("The organization's company name.") created_at = DateAttribute("The date the organization was created.", format="commit") - following_count = Attribute("Number of users the organization is following.") + following_count = Attribute("Number of users the organization is " + "following.") followers_count = Attribute("Number of users following this organization.") - public_gist_count = Attribute("Organization's number of active public gists.") - public_repo_count = Attribute("Organization's number of active repositories.") + public_gist_count = Attribute("Organization's number of active public " + "gists.") + public_repo_count = Attribute("Organization's number of active " + "repositories.") permission = Attribute("Permissions within this organization.") plan = Attribute("GitHub plan for this organization.") diff --git a/github2/pull_requests.py b/github2/pull_requests.py index 3573f75..b75d62e 100644 --- a/github2/pull_requests.py +++ b/github2/pull_requests.py @@ -22,14 +22,14 @@ class PullRequest(BaseData): patch_url = Attribute("The URL to the downloadable patch.") labels = Attribute("A list of labels attached to the pull request.") html_url = Attribute("The URL to the pull request.") - issue_created_at = DateAttribute("The date the issue for this pull request was opened.", - format='iso') - issue_updated_at = DateAttribute("The date the issue for this pull request was last updated.", - format='iso') + issue_created_at = DateAttribute("The date the issue for this pull " + "request was opened.", format='iso') + issue_updated_at = DateAttribute("The date the issue for this pull " + "request was last updated.", format='iso') created_at = DateAttribute("The date when this pull request was created.", format='iso') - updated_at = DateAttribute("The date when this pull request was last updated.", - format='iso') + updated_at = DateAttribute("The date when this pull request was last " + "updated.", format='iso') closed_at = DateAttribute("The date when this pull request was closed", format='iso') discussion = Attribute("Discussion thread for the pull request.") diff --git a/github2/request.py b/github2/request.py index 3965415..bee5846 100644 --- a/github2/request.py +++ b/github2/request.py @@ -102,7 +102,8 @@ def __init__(self, message, content, code): self.code_reason = responses[code] else: self.code_reason = "" - LOGGER.warning('Unknown HTTP status %r, please file an issue', code) + LOGGER.warning('Unknown HTTP status %r, please file an issue', + code) class GithubRequest(object): diff --git a/tests/test_unit.py b/tests/test_unit.py index 76c637a..2e985a7 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -75,6 +75,7 @@ def test_project_for_user_repo(): assert_equals(client.project_for_user_repo('JNRowe', 'misc-overlay'), 'JNRowe/misc-overlay') + def test_repr_string(): assert_equals(repr_string('test'), 'test') assert_equals(repr_string('abcdefghijklmnopqrst'), 'abcdefghijklmnopqrst') From 18eaf6163192d129ed09bd30b4e96f9c1894b4e0 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 28 Feb 2012 20:12:39 +0000 Subject: [PATCH 068/110] [QA] Added hints for flake8. --- github2/issues.py | 2 +- github2/request.py | 17 ++++++++--------- github2/users.py | 2 +- tests/test_request.py | 8 ++++---- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/github2/issues.py b/github2/issues.py index ae9723b..851f813 100644 --- a/github2/issues.py +++ b/github2/issues.py @@ -1,7 +1,7 @@ try: from urllib.parse import quote_plus # For Python 3 except ImportError: - from urllib import quote_plus + from urllib import quote_plus # NOQA from github2.core import (GithubCommand, BaseData, Attribute, DateAttribute, repr_string, requires_auth) diff --git a/github2/request.py b/github2/request.py index bee5846..c05394a 100644 --- a/github2/request.py +++ b/github2/request.py @@ -9,26 +9,25 @@ from http.client import responses except ImportError: # For Python 2.5-2.7 try: - from httplib import responses + from httplib import responses # NOQA except ImportError: # For Python 2.4 - from BaseHTTPServer import BaseHTTPRequestHandler - responses = dict([(k, v[0]) - for k, v in BaseHTTPRequestHandler.responses.items()]) + from BaseHTTPServer import BaseHTTPRequestHandler as _BHRH + responses = dict([(k, v[0]) for k, v in _BHRH.responses.items()]) # NOQA try: import json as simplejson # For Python 2.6+ except ImportError: - import simplejson + import simplejson # NOQA from os import (getenv, path) try: # For Python 3 from urllib.parse import (parse_qs, quote, urlencode, urlsplit, urlunsplit) except ImportError: - from urlparse import (urlsplit, urlunsplit) + from urlparse import (urlsplit, urlunsplit) # NOQA try: - from urlparse import parse_qs + from urlparse import parse_qs # NOQA except ImportError: - from cgi import parse_qs - from urllib import urlencode, quote + from cgi import parse_qs # NOQA + from urllib import urlencode, quote # NOQA import httplib2 diff --git a/github2/users.py b/github2/users.py index 1cd5ac6..ad40fc1 100644 --- a/github2/users.py +++ b/github2/users.py @@ -1,7 +1,7 @@ try: from urllib.parse import quote_plus # For Python 3 except ImportError: - from urllib import quote_plus + from urllib import quote_plus # NOQA from github2.core import (BaseData, GithubCommand, DateAttribute, Attribute, enhanced_by_auth, requires_auth) diff --git a/tests/test_request.py b/tests/test_request.py index 031bc4f..7c7f93b 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -4,9 +4,9 @@ from urllib.parse import parse_qs # For Python 3 except ImportError: try: - from urlparse import parse_qs + from urlparse import parse_qs # NOQA except ImportError: # For Python <2.6 - from cgi import parse_qs + from cgi import parse_qs # NOQA try: from nose.tools import (assert_dict_contains_subset, assert_dict_equal) @@ -14,8 +14,8 @@ import unittest2 _binding = unittest2.TestCase('run') - assert_dict_contains_subset = _binding.assertDictContainsSubset - assert_dict_equal = _binding.assertDictEqual + assert_dict_contains_subset = _binding.assertDictContainsSubset # NOQA + assert_dict_equal = _binding.assertDictEqual # NOQA from github2 import request From 04b24977b4a4aba96dd41a6a092cacd4641351ba Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 28 Feb 2012 20:14:48 +0000 Subject: [PATCH 069/110] Fixed Sphinx :see: uses to use domain refs. --- tests/test_tz_aware_date_handling.py | 2 +- tests/utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_tz_aware_date_handling.py b/tests/test_tz_aware_date_handling.py index ccc224f..5789593 100644 --- a/tests/test_tz_aware_date_handling.py +++ b/tests/test_tz_aware_date_handling.py @@ -23,7 +23,7 @@ def teardown_module(): def dt_utz(year, month, day, hour, minute, second): """Produce a UTC-anchored datetime object - :see: ``datetime.datetime`` + :see: :class:`datetime.datetime` """ return dt(year, month, day, hour, minute, second, tzinfo=tzutc()) diff --git a/tests/utils.py b/tests/utils.py index cbd41cc..78fb8c4 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -73,7 +73,7 @@ class HttpMockAuthenticatedTestCase(HttpMockTestCase): def setUp(self): """Prepare test fixtures - :see: ``HttpMockTestCase`` + :see: :class:`HttpMockTestCase` :attr:`client` is an authenticated :obj:`Github` object for easy use in tests. From 6724850616fcbb31b0c99b94ec4dfc1fdf470fb0 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 28 Feb 2012 20:18:09 +0000 Subject: [PATCH 070/110] Added ghsync/humble to 'in the wild' doc. --- doc/wild.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/wild.rst b/doc/wild.rst index 78b2298..af21eed 100644 --- a/doc/wild.rst +++ b/doc/wild.rst @@ -48,6 +48,13 @@ listed on this page. :PyPI page: :pypi:`ghmiles` +``ghsync`` +'''''''''' + + GitHub Syncer. Clones or Pulls all GitHub repos. + +:PyPI page: :pypi:`ghsync` + ``github-issues`` ''''''''''''''''' @@ -81,6 +88,13 @@ listed on this page. .. _GitHub's issue tracker: http://github.com/blog/411-github-issue-tracker +``humble`` +'''''''''' + + Shows stats on a given GitHub user. + +:PyPI page: :pypi:`humble` + ``Repos.io`` '''''''''''' From d7b0cccbd67ba99e1f90aeb835014ee564ec6542 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 28 Feb 2012 20:27:09 +0000 Subject: [PATCH 071/110] Bumped version to 0.6.1. --- NEWS.rst | 11 +++++++++++ README.rst | 2 +- github2/_version.py | 14 +++++++------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index 54c693b..1f94908 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -8,6 +8,17 @@ look at the `git repository`_ for the full project history. .. contents:: +0.6.1 - 2012-02-28 +------------------ + +* Support for `GitHub:Enterprise`_ using the ``github_url`` parameter when + creating a client +* Adds SSH key management +* Support reading SSL certificates from the location set in ``CURL_CA_BUNDLE``, + if all else fails + +.. _GitHub:Enterprise: https://enterprise.github.com/ + 0.6.0 - 2011-12-21 ------------------ diff --git a/README.rst b/README.rst index 804dc81..67867b9 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ github2 - Github API v2 library for Python. :Authors: Ask Solem (askh@opera.com) -:Version: 0.6.0 +:Version: 0.6.1 This is a Python library implementing all of the features available in version 2 of the `Github API`_. diff --git a/github2/_version.py b/github2/_version.py index bf9f4df..0269a27 100644 --- a/github2/_version.py +++ b/github2/_version.py @@ -1,9 +1,9 @@ -# This is github2 version 0.6.0 (2011-12-21) +# This is github2 version 0.6.1 (2012-02-28) # pylint: disable=C0103, C0111, C0121, W0622 -dotted = "0.6.0" -libtool = "6:20" -hex = 0x000600 -date = "2011-12-21" -tuple = (0, 6, 0) -web = "github/0.6.0" +dotted = "0.6.1" +libtool = "6:21" +hex = 0x000601 +date = "2012-02-28" +tuple = (0, 6, 1) +web = "github2/0.6.1" From ddeb4bc60b89311c8e068f31b3e0df77bc27164c Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 6 Apr 2012 07:50:51 +0100 Subject: [PATCH 072/110] [QA] Removed contents directive from NEWS file. --- NEWS.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index 1f94908..e7092fe 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -6,8 +6,6 @@ look at the `git repository`_ for the full project history. .. _git repository: https://github.com/ask/python-github2/ -.. contents:: - 0.6.1 - 2012-02-28 ------------------ From 3414c22d25a54624e554be5bdb8a6fb327ff27d7 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 6 Apr 2012 07:48:36 +0100 Subject: [PATCH 073/110] Added a warning to the intro docs for pending API switch-off. Wondering whether this needs an explicit "don't file bug reports" clause ;) --- README.rst | 12 ++++++++++++ doc/index.rst | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/README.rst b/README.rst index 67867b9..3e6ab34 100644 --- a/README.rst +++ b/README.rst @@ -6,12 +6,24 @@ github2 - Github API v2 library for Python. Ask Solem (askh@opera.com) :Version: 0.6.1 +.. warning:: + + GitHub are planning to `switch off API v2`_ on 2012-05-01, you should + be looking to replace ``github2`` as soon as possible. + + Both remoteobjects_ and micromodels_ provide easy-to-use functionality for + creating bindings to remote APIs, and should significantly reduce the amount + of work needed in moving away from GitHub's API v2. + This is a Python library implementing all of the features available in version 2 of the `Github API`_. See the ``doc/`` directory for installation instructions and usage information. If you prefer you can also read the `documentation online`_. +.. _switch off API v2: https://github.com/blog/1090-github-api-moving-on +.. _remoteobjects: https://github.com/saymedia/remoteobjects +.. _micromodels: https://github.com/j4mie/micromodels .. _Github API: http://develop.github.com/ .. _documentation online: http://packages.python.org/github2 diff --git a/doc/index.rst b/doc/index.rst index fffa939..55814bf 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -13,6 +13,19 @@ ``github2`` - Github API v2 library for Python ============================================== +.. warning:: + + GitHub are planning to `switch off API v2`_ on 2012-05-01, you should + be looking to replace ``github2`` as soon as possible. + + Both remoteobjects_ and micromodels_ provide easy-to-use functionality for + creating bindings to remote APIs, and should significantly reduce the amount + of work needed in moving away from GitHub's API v2. + +.. _switch off API v2: https://github.com/blog/1090-github-api-moving-on +.. _remoteobjects: https://github.com/saymedia/remoteobjects +.. _micromodels: https://github.com/j4mie/micromodels + .. pypi-release:: github2 :prefix: Download :class: sidebar From 406dfb9700e33aae1189984d48a314617cb3a046 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 14 Apr 2012 08:56:13 +0100 Subject: [PATCH 074/110] Added cligh to 'in the wild' doc. --- doc/wild.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/wild.rst b/doc/wild.rst index af21eed..c66abab 100644 --- a/doc/wild.rst +++ b/doc/wild.rst @@ -32,6 +32,13 @@ listed on this page. :PyPI page: :pypi:`bugwarrior` +``cligh`` +''''''''' + + A simple command-line interface to the facilities of GitHub. + +:Git repository: https://github.com/CMB/cligh + ``forkfeed`` '''''''''''' From a1d4f6d8812866685ac55754336258563ae79b30 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 14 Apr 2012 08:58:29 +0100 Subject: [PATCH 075/110] Use 'project' for link references in wild doc. Didn't really like the 'Git repository' look. --- doc/wild.rst | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/wild.rst b/doc/wild.rst index c66abab..8a49b96 100644 --- a/doc/wild.rst +++ b/doc/wild.rst @@ -15,14 +15,14 @@ listed on this page. Applause when a bug gets closed. Extra cheering for old bugs. -:PyPI page: :pypi:`applause` +:PyPI project: :pypi:`applause` ``bitbucket2github`` '''''''''''''''''''' Mirrors all public repos of a BitBucket account to GitHub and vice versa. -:PyPI page: :pypi:`bitbucket2github` +:PyPI project: :pypi:`bitbucket2github` ``bugwarrior`` '''''''''''''' @@ -30,14 +30,14 @@ listed on this page. Pull tickets from github, bitbucket, and trac into `taskwarrior `__ -:PyPI page: :pypi:`bugwarrior` +:PyPI project: :pypi:`bugwarrior` ``cligh`` ''''''''' A simple command-line interface to the facilities of GitHub. -:Git repository: https://github.com/CMB/cligh +:GitHub project: https://github.com/CMB/cligh ``forkfeed`` '''''''''''' @@ -45,7 +45,7 @@ listed on this page. Utility to build atom feeds for all commits in all forks of your projects on GitHub. -:PyPI page: :pypi:`forkfeed` +:PyPI project: :pypi:`forkfeed` ``ghmiles`` ''''''''''' @@ -53,14 +53,14 @@ listed on this page. ``ghmiles`` is a Python library that generates a milestone model from the issues in a GitHub repository. -:PyPI page: :pypi:`ghmiles` +:PyPI project: :pypi:`ghmiles` ``ghsync`` '''''''''' GitHub Syncer. Clones or Pulls all GitHub repos. -:PyPI page: :pypi:`ghsync` +:PyPI project: :pypi:`ghsync` ``github-issues`` ''''''''''''''''' @@ -68,7 +68,7 @@ listed on this page. github-issues allows you to create, close, show, list, and comment on issues on your github project - that's it. -:Git repository: https://github.com/kashifrazzaqui/github-issues +:GitHub project: https://github.com/kashifrazzaqui/github-issues ``github-issues-export`` '''''''''''''''''''''''' @@ -76,14 +76,14 @@ listed on this page. Script to liberate issues from github issues in case you would like to have your data free. -:Git repository: https://github.com/mcepl/github-issues-export +:GitHub project: https://github.com/mcepl/github-issues-export ``github-plots`` '''''''''''''''' Alternative plots from GitHub stats. -:PyPI page: :pypi:`github-plots` +:PyPI project: :pypi:`github-plots` ``hubugs`` '''''''''' @@ -91,7 +91,7 @@ listed on this page. ``hubugs`` is a very simple client for working with `GitHub's issue tracker`_. -:PyPI page: :pypi:`hubugs` +:PyPI project: :pypi:`hubugs` .. _GitHub's issue tracker: http://github.com/blog/411-github-issue-tracker @@ -100,7 +100,7 @@ listed on this page. Shows stats on a given GitHub user. -:PyPI page: :pypi:`humble` +:PyPI project: :pypi:`humble` ``Repos.io`` '''''''''''' @@ -109,7 +109,7 @@ listed on this page. repositories (your own, and watched/liked/followed ones) hosted by different providers (github, bitbucket) -:Git repository: https://github.com/twidi/Repos.io +:GitHub project: https://github.com/twidi/Repos.io ``roundabout`` '''''''''''''' @@ -117,7 +117,7 @@ listed on this page. ``Roundabout`` is a tool that automatically prevents code with failing tests from being merged into a github repository. -:Git repository: https://github.com/ChristopherMacGown/roundabout +:GitHub project: https://github.com/ChristopherMacGown/roundabout .. _open an issue: https://github.com/ask/python-github2/issues/ .. _project website: https://github.com/ask/python-github2/blob/master/doc/wild.rst From 7319f330c0bebba89b306f65da8faedeb5be9762 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Sat, 14 Apr 2012 09:04:16 +0100 Subject: [PATCH 076/110] Document automatic proxy config with httplib2-0.7.4. Closes #75. --- doc/api/client.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/api/client.rst b/doc/api/client.rst index 4954148..f1a9e0c 100644 --- a/doc/api/client.rst +++ b/doc/api/client.rst @@ -42,9 +42,14 @@ API calls are limited by github.com to 1 per second by default. To have the >>> github = Github(username="ask", api_token=".......", ... requests_per_second=1) -If you wish to use a HTTP proxy you can pass in the ``proxy_host`` and -``proxy_port`` settings to enable it. The default for ``proxy_port``, if not -given, is 8080:: +By default, :pypi:`httplib2 (0.7.4)` will use the proxies set in the +:envvar:`http_proxy` andr :envvar:`https_proxy` environment variables. This +means that well configured systems shouldn't need any manual configuration for +proxy support. + +If you wish to manually configure a HTTP proxy you can pass in the +``proxy_host`` and ``proxy_port`` settings to enable it. The default for +``proxy_port``, if not given, is 8080:: >>> from github2.client import Github >>> github = Github(username="ask", api_token=".......", From 4c67559dc0676a0fa7a3ac2044b66f5c33d71da9 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 30 Apr 2012 01:42:05 +0100 Subject: [PATCH 077/110] Fixed using bundled certs on supported OS. This would have failed in the case where an OS is supported, but the certs weren't available. --- github2/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github2/request.py b/github2/request.py index c05394a..9aea264 100644 --- a/github2/request.py +++ b/github2/request.py @@ -56,7 +56,7 @@ elif path.exists(getenv('CURL_CA_BUNDLE', '')): CA_CERTS = getenv('CURL_CA_BUNDLE') CURL_CERTS = True -else: +if not SYSTEM_CERTS and not CURL_CERTS: CA_CERTS = path.join(path.dirname(path.abspath(__file__)), "DigiCert_High_Assurance_EV_Root_CA.crt") From 6432fe9c638c0bd68d4bc60ff9f6fc169f584148 Mon Sep 17 00:00:00 2001 From: modocache Date: Mon, 30 Apr 2012 20:01:10 +0900 Subject: [PATCH 078/110] Change enterprise URL in docs. Closes #76. --- doc/api/client.rst | 2 +- tests/test_unit.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/api/client.rst b/doc/api/client.rst index f1a9e0c..b11eaa8 100644 --- a/doc/api/client.rst +++ b/doc/api/client.rst @@ -61,6 +61,6 @@ https://github.com/. >>> from github2.client import Github >>> github = Github(username="modocache", api_token=".......", - ... github_url="http://git.gree-dev.net/") + ... github_url="http://your-github-enterprise-url.com/") .. _OAuth service: http://develop.github.com/p/oauth.html diff --git a/tests/test_unit.py b/tests/test_unit.py index 2e985a7..7cd3113 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -28,8 +28,9 @@ def test_default_host(self): assert_equals(client.request.github_url, 'https://github.com') def test_non_standard_host(self): - client = Github(github_url="http://git.gree-dev.net/") - assert_equals(client.request.github_url, 'http://git.gree-dev.net/') + client = Github(github_url="http://your-github-enterprise-url.com/") + assert_equals(client.request.github_url, + 'http://your-github-enterprise-url.com/') class RateLimits(utils.HttpMockTestCase): From 6eeeef96f877d44a8e54a75846617fa5b225b313 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 11:33:54 +0100 Subject: [PATCH 079/110] Add per-file licensing info. Removes a -10 'packaging smell', and basically for free with ucopy ;) --- .ucopy.cfg | 21 ++++++++++++ AUTHORS | 49 ++++++++++++++++------------ doc/.templates/layout.html | 7 ++++ doc/api/client.rst | 8 +++++ doc/api/commit.rst | 6 ++++ doc/api/core.rst | 6 ++++ doc/api/index.rst | 6 ++++ doc/api/issues.rst | 6 ++++ doc/api/network.rst | 6 ++++ doc/api/object.rst | 6 ++++ doc/api/organizations.rst | 6 ++++ doc/api/pull_requests.rst | 6 ++++ doc/api/repos.rst | 6 ++++ doc/api/request.rst | 6 ++++ doc/api/teams.rst | 6 ++++ doc/api/users.rst | 6 ++++ doc/bugs.rst | 6 ++++ doc/contributing.rst | 6 ++++ doc/index.rst | 9 ++--- doc/install.rst | 7 ++++ doc/license.rst | 6 ++++ doc/problems.rst | 6 ++++ doc/quickstart.rst | 6 ++++ doc/release.rst | 6 ++++ doc/wild.rst | 7 ++++ examples/friend-or-follow.py | 5 +++ github2/__init__.py | 6 ++++ github2/bin/__init__.py | 4 +++ github2/bin/manage_collaborators.py | 7 ++-- github2/bin/search_repos.py | 4 +++ github2/client.py | 15 +++++++++ github2/commits.py | 9 +++++ github2/core.py | 13 ++++++++ github2/issues.py | 10 ++++++ github2/organizations.py | 7 ++++ github2/pull_requests.py | 9 +++++ github2/repositories.py | 17 ++++++++++ github2/request.py | 21 ++++++++++++ github2/teams.py | 6 ++++ github2/users.py | 9 +++++ setup.py | 10 ++++++ tests/test_charset_header.py | 5 +++ tests/test_commits.py | 5 +++ tests/test_date_handling.py | 4 +++ tests/test_issues.py | 5 +++ tests/test_organizations.py | 5 +++ tests/test_pull_requests.py | 5 +++ tests/test_regression.py | 5 +++ tests/test_repositories.py | 7 ++++ tests/test_request.py | 5 +++ tests/test_teams.py | 5 +++ tests/test_tz_aware_date_handling.py | 4 +++ tests/test_unit.py | 7 ++++ tests/test_user.py | 5 +++ tests/utils.py | 5 +++ 55 files changed, 413 insertions(+), 27 deletions(-) create mode 100644 .ucopy.cfg diff --git a/.ucopy.cfg b/.ucopy.cfg new file mode 100644 index 0000000..530185a --- /dev/null +++ b/.ucopy.cfg @@ -0,0 +1,21 @@ +[repo] +name = python-github2 +license-from = bsd-3 +vcs = git + +[files] +ignore-from = git +ignore-glob = COPYING, README.rst, .keep, test/data/github.com,api* + +[patch] +unicode = python + +[author-override] +Ask Solem = +Chris Vale = +Claudio B. = +Daniel Greenfeld = +Donald von Stufft = +Michael Basnight = +Sameer Al-Sakran = +Stéphane Angel = diff --git a/AUTHORS b/AUTHORS index 99f5070..5e14ae3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,31 +1,38 @@ -Ask Solem -Mark Paschal -Donald von Stufft -Maximillian Dornseif +python-github2 was written by: + +Ask Solem + +with contributions from the following people: + +Adam Vandenberg Asheesh Laroia -Rick Harris -Cody Soyland -Fernando Perez -Evan Broder -Scott Torborg -Claudio B. +Barthelemy Dagenais Chris Vale -Adam Vandenberg -Kenneth Reitz +Christopher MacGown +Claudio B. +Cody Soyland Daniel Greenfeld +Donald von Stufft +Evan Broder +Fernando Perez +Ionuț Arțăriși +James Rowe +Jens Ohlig Jeremy Dunck Jonas Obrist -Sameer Al-Sakran -Vincent Driessen -James Rowe Josh Weinberg -Barthelemy Dagenais -Surajram Kumarave -broderboy -Patryk Zawadzki +Justin Quick +Kenneth Reitz +Mark Paschal +Maximillian Dornseif Michael Basnight -Christopher MacGown +Patryk Zawadzki +Rick Harris Rok Garbas -Ionuț Arțăriși +Sameer Al-Sakran +Scott Torborg Stéphane Angel +Surajram Kumaravel +Vincent Driessen +broderboy modocache diff --git a/doc/.templates/layout.html b/doc/.templates/layout.html index 3560b06..b251a03 100644 --- a/doc/.templates/layout.html +++ b/doc/.templates/layout.html @@ -1,3 +1,10 @@ +{# + Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. +#} {% extends "!layout.html" %} {% block extrahead %} diff --git a/doc/api/client.rst b/doc/api/client.rst index b11eaa8..1cf0ea9 100644 --- a/doc/api/client.rst +++ b/doc/api/client.rst @@ -1,3 +1,11 @@ +.. Copyright (C) 2011-2012 James Rowe + Michael Basnight + modocache + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.client Creating a client diff --git a/doc/api/commit.rst b/doc/api/commit.rst index e4a69bf..ffca1a2 100644 --- a/doc/api/commit.rst +++ b/doc/api/commit.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.commits Commit diff --git a/doc/api/core.rst b/doc/api/core.rst index 9b9e297..1e26d09 100644 --- a/doc/api/core.rst +++ b/doc/api/core.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.core Core diff --git a/doc/api/index.rst b/doc/api/index.rst index cbe2c5c..36fa3a0 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + API documentation ================= diff --git a/doc/api/issues.rst b/doc/api/issues.rst index 6ba740c..1f2dcfb 100644 --- a/doc/api/issues.rst +++ b/doc/api/issues.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.issues Issues diff --git a/doc/api/network.rst b/doc/api/network.rst index f07baa9..1d7312d 100644 --- a/doc/api/network.rst +++ b/doc/api/network.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. currentmodule:: github2.client Network diff --git a/doc/api/object.rst b/doc/api/object.rst index 79842c7..106b685 100644 --- a/doc/api/object.rst +++ b/doc/api/object.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. currentmodule:: github2.client Object diff --git a/doc/api/organizations.rst b/doc/api/organizations.rst index fc46950..b4fb0f6 100644 --- a/doc/api/organizations.rst +++ b/doc/api/organizations.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.organizations Organizations diff --git a/doc/api/pull_requests.rst b/doc/api/pull_requests.rst index 140a824..ee6f518 100644 --- a/doc/api/pull_requests.rst +++ b/doc/api/pull_requests.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.pull_requests Pull requests diff --git a/doc/api/repos.rst b/doc/api/repos.rst index 4f777ee..1d96337 100644 --- a/doc/api/repos.rst +++ b/doc/api/repos.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.repositories Repository diff --git a/doc/api/request.rst b/doc/api/request.rst index 0dd71f2..b3ffc49 100644 --- a/doc/api/request.rst +++ b/doc/api/request.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.request Requests diff --git a/doc/api/teams.rst b/doc/api/teams.rst index dc2102b..4e72746 100644 --- a/doc/api/teams.rst +++ b/doc/api/teams.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.teams Teams diff --git a/doc/api/users.rst b/doc/api/users.rst index 052092a..d9ac95d 100644 --- a/doc/api/users.rst +++ b/doc/api/users.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + .. module:: github2.users Users diff --git a/doc/bugs.rst b/doc/bugs.rst index 6105987..1c838a1 100644 --- a/doc/bugs.rst +++ b/doc/bugs.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + Reporting bugs ============== diff --git a/doc/contributing.rst b/doc/contributing.rst index 8c3b47a..ad846be 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + Contributing ============ diff --git a/doc/index.rst b/doc/index.rst index 55814bf..5b21867 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -1,7 +1,8 @@ -.. python-github2 documentation master file, created by - sphinx-quickstart on Mon Apr 11 16:16:25 2011. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. .. If you prefer you can also read the pre-built documentation at diff --git a/doc/install.rst b/doc/install.rst index 8d309ee..84b57de 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -1,3 +1,10 @@ +.. Copyright (C) 2011-2012 James Rowe + Michael Basnight + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + Installation ------------ diff --git a/doc/license.rst b/doc/license.rst index 7e1c1b4..316b2ae 100644 --- a/doc/license.rst +++ b/doc/license.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + License ======= diff --git a/doc/problems.rst b/doc/problems.rst index 5fabddf..31d3052 100644 --- a/doc/problems.rst +++ b/doc/problems.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + Solving problems ================ diff --git a/doc/quickstart.rst b/doc/quickstart.rst index bb41f5e..2d3988f 100644 --- a/doc/quickstart.rst +++ b/doc/quickstart.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2011-2012 James Rowe + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + Quickstart ========== diff --git a/doc/release.rst b/doc/release.rst index b7baf79..745d419 100644 --- a/doc/release.rst +++ b/doc/release.rst @@ -1,3 +1,9 @@ +.. Copyright (C) 2012 James Rowe + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + Release HOWTO ============= diff --git a/doc/wild.rst b/doc/wild.rst index 8a49b96..07bd653 100644 --- a/doc/wild.rst +++ b/doc/wild.rst @@ -1,3 +1,10 @@ +.. Copyright (C) 2011-2012 James Rowe + Stéphane Angel + + This file is part of python-github2, and is licensed under the 3-clause BSD + License. See the LICENSE file in the top distribution directory for the full + license text. + In the wild ----------- diff --git a/examples/friend-or-follow.py b/examples/friend-or-follow.py index ccef96a..9a19b74 100644 --- a/examples/friend-or-follow.py +++ b/examples/friend-or-follow.py @@ -1,3 +1,8 @@ +# Copyright (C) 2010-2012 Ask Solem +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + import sys import optparse from subprocess import Popen, PIPE diff --git a/github2/__init__.py b/github2/__init__.py index 30d323e..cf56247 100644 --- a/github2/__init__.py +++ b/github2/__init__.py @@ -1,4 +1,10 @@ "Github API v2 library for Python" +# Copyright (C) 2009-2012 Ask Solem +# James Rowe +# Maximillian Dornseif +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. from github2 import _version diff --git a/github2/bin/__init__.py b/github2/bin/__init__.py index 792d600..6c5b974 100644 --- a/github2/bin/__init__.py +++ b/github2/bin/__init__.py @@ -1 +1,5 @@ # +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. diff --git a/github2/bin/manage_collaborators.py b/github2/bin/manage_collaborators.py index 3efafee..6e320fb 100755 --- a/github2/bin/manage_collaborators.py +++ b/github2/bin/manage_collaborators.py @@ -8,8 +8,11 @@ """ # Created by Maximillian Dornseif on 2009-12-31 for HUDORA. -# Copyright (c) 2009 HUDORA. All rights reserved. -# BSD licensed +# Copyright (C) 2009-2012 James Rowe +# Maximillian Dornseif +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. import logging import sys diff --git a/github2/bin/search_repos.py b/github2/bin/search_repos.py index c52be46..3064ff2 100755 --- a/github2/bin/search_repos.py +++ b/github2/bin/search_repos.py @@ -1,6 +1,10 @@ #! /usr/bin/env python # coding: utf-8 """github_search_repos - search for repositories on GitHub""" +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. import logging diff --git a/github2/client.py b/github2/client.py index c585f3b..122fdfa 100644 --- a/github2/client.py +++ b/github2/client.py @@ -1,3 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2009-2012 Ask Solem +# Christopher MacGown +# Evan Broder +# James Rowe +# Jeremy Dunck +# Michael Basnight +# Patryk Zawadzki +# Surajram Kumaravel +# Vincent Driessen +# modocache +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from github2.request import GithubRequest from github2.issues import Issues from github2.repositories import Repositories diff --git a/github2/commits.py b/github2/commits.py index 8910937..f33a9e2 100644 --- a/github2/commits.py +++ b/github2/commits.py @@ -1,3 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2009-2012 Ask Solem +# James Rowe +# Stéphane Angel +# Vincent Driessen +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from github2.core import (BaseData, GithubCommand, Attribute, DateAttribute, repr_string) diff --git a/github2/core.py b/github2/core.py index 856a489..67587f5 100644 --- a/github2/core.py +++ b/github2/core.py @@ -1,3 +1,16 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2009-2012 Ask Solem +# Fernando Perez +# James Rowe +# Mark Paschal +# Patryk Zawadzki +# Sameer Al-Sakran +# Stéphane Angel +# Vincent Driessen +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + import logging import sys diff --git a/github2/issues.py b/github2/issues.py index 851f813..217a154 100644 --- a/github2/issues.py +++ b/github2/issues.py @@ -1,3 +1,13 @@ +# Copyright (C) 2009-2012 Adam Vandenberg +# Ask Solem +# Barthelemy Dagenais +# Fernando Perez +# James Rowe +# Scott Torborg +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + try: from urllib.parse import quote_plus # For Python 3 except ImportError: diff --git a/github2/organizations.py b/github2/organizations.py index 38eac83..cd99c03 100644 --- a/github2/organizations.py +++ b/github2/organizations.py @@ -1,3 +1,10 @@ +# Copyright (C) 2011-2012 James Rowe +# Patryk Zawadzki +# Rok Garbas +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from github2.core import (BaseData, GithubCommand, Attribute, DateAttribute, requires_auth) from github2.repositories import Repository diff --git a/github2/pull_requests.py b/github2/pull_requests.py index b75d62e..3137002 100644 --- a/github2/pull_requests.py +++ b/github2/pull_requests.py @@ -1,3 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2010-2012 Christopher MacGown +# Ionuț Arțăriși +# James Rowe +# Stéphane Angel +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from github2.core import (BaseData, GithubCommand, Attribute, DateAttribute, repr_string) diff --git a/github2/repositories.py b/github2/repositories.py index 89f8e57..6d206bf 100644 --- a/github2/repositories.py +++ b/github2/repositories.py @@ -1,3 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2009-2012 Ask Solem +# Claudio B. +# Daniel Greenfeld +# James Rowe +# Jens Ohlig +# Jeremy Dunck +# Jonas Obrist +# Kenneth Reitz +# Mark Paschal +# Maximillian Dornseif +# Sameer Al-Sakran +# Stéphane Angel +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from github2.core import (BaseData, GithubCommand, Attribute, DateAttribute, requires_auth) diff --git a/github2/request.py b/github2/request.py index 9aea264..7b400bf 100644 --- a/github2/request.py +++ b/github2/request.py @@ -1,3 +1,24 @@ +# Copyright (C) 2009-2012 Adam Vandenberg +# Asheesh Laroia +# Ask Solem +# Chris Vale +# Daniel Greenfeld +# Evan Broder +# James Rowe +# Jeremy Dunck +# Josh Weinberg +# Mark Paschal +# Maximillian Dornseif +# Michael Basnight +# Patryk Zawadzki +# Rick Harris +# Sameer Al-Sakran +# Vincent Driessen +# modocache +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + import datetime import logging import re diff --git a/github2/teams.py b/github2/teams.py index b46116f..2472cf3 100644 --- a/github2/teams.py +++ b/github2/teams.py @@ -1,3 +1,9 @@ +# Copyright (C) 2011-2012 James Rowe +# Patryk Zawadzki +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from github2.core import BaseData, GithubCommand, Attribute, requires_auth from github2.repositories import Repository from github2.users import User diff --git a/github2/users.py b/github2/users.py index ad40fc1..e2c9c58 100644 --- a/github2/users.py +++ b/github2/users.py @@ -1,3 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2009-2012 Ask Solem +# James Rowe +# Sameer Al-Sakran +# Stéphane Angel +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + try: from urllib.parse import quote_plus # For Python 3 except ImportError: diff --git a/setup.py b/setup.py index 8613f1f..06c56bb 100755 --- a/setup.py +++ b/setup.py @@ -1,5 +1,15 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +# Copyright (C) 2009-2012 Ask Solem +# Cody Soyland +# Donald von Stufft +# James Rowe +# Maximillian Dornseif +# Michael Basnight +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + import codecs import sys diff --git a/tests/test_charset_header.py b/tests/test_charset_header.py index 40aff70..3b29635 100644 --- a/tests/test_charset_header.py +++ b/tests/test_charset_header.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from nose.tools import assert_equals from github2.request import charset_from_headers diff --git a/tests/test_commits.py b/tests/test_commits.py index 5d4ee8e..20ed487 100644 --- a/tests/test_commits.py +++ b/tests/test_commits.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from datetime import datetime from nose.tools import assert_equals diff --git a/tests/test_date_handling.py b/tests/test_date_handling.py index fabc8d5..855ccae 100644 --- a/tests/test_date_handling.py +++ b/tests/test_date_handling.py @@ -1,4 +1,8 @@ # -*- coding: utf-8 -*- +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. from datetime import datetime as dt diff --git a/tests/test_issues.py b/tests/test_issues.py index dfd693e..f82302b 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from datetime import datetime from nose.tools import assert_equals diff --git a/tests/test_organizations.py b/tests/test_organizations.py index 9f4e56b..8571e23 100644 --- a/tests/test_organizations.py +++ b/tests/test_organizations.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from datetime import datetime from nose.tools import (assert_equals, assert_true) diff --git a/tests/test_pull_requests.py b/tests/test_pull_requests.py index 50197ce..9c2d35e 100644 --- a/tests/test_pull_requests.py +++ b/tests/test_pull_requests.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from datetime import datetime from nose.tools import assert_equals diff --git a/tests/test_regression.py b/tests/test_regression.py index a2b235c..cad7dc2 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + import httplib2 from nose.tools import assert_equals diff --git a/tests/test_repositories.py b/tests/test_repositories.py index 63f39c0..1cdaab9 100644 --- a/tests/test_repositories.py +++ b/tests/test_repositories.py @@ -1,3 +1,10 @@ +# coding: utf-8 +# Copyright (C) 2011-2012 James Rowe +# Stéphane Angel +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + import datetime from nose.tools import assert_equals diff --git a/tests/test_request.py b/tests/test_request.py index 7c7f93b..0833c00 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + import unittest try: diff --git a/tests/test_teams.py b/tests/test_teams.py index 85689aa..7333edd 100644 --- a/tests/test_teams.py +++ b/tests/test_teams.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + from nose.tools import assert_equals import utils diff --git a/tests/test_tz_aware_date_handling.py b/tests/test_tz_aware_date_handling.py index 5789593..6a501f0 100644 --- a/tests/test_tz_aware_date_handling.py +++ b/tests/test_tz_aware_date_handling.py @@ -1,4 +1,8 @@ # -*- coding: utf-8 -*- +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. from datetime import datetime as dt diff --git a/tests/test_unit.py b/tests/test_unit.py index 7cd3113..f17f9a0 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -1,4 +1,11 @@ # -*- coding: utf-8 -*- +# Copyright (C) 2010-2012 Adam Vandenberg +# James Rowe +# Jeremy Dunck +# modocache +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. import datetime import unittest diff --git a/tests/test_user.py b/tests/test_user.py index aff6ad5..33929db 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + import datetime from nose.tools import (assert_equals, assert_false, assert_true) diff --git a/tests/utils.py b/tests/utils.py index 78fb8c4..598b068 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,3 +1,8 @@ +# Copyright (C) 2011-2012 James Rowe +# +# This file is part of python-github2, and is made available under the 3-clause +# BSD license. See LICENSE for the full details. + import os import sys import unittest From cd436188df09605ad35deef5e80caec0cc9ca6f2 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 11:39:18 +0100 Subject: [PATCH 080/110] [QA] Clean up the ignore list. --- .gitignore | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index ea2d6d3..241d83f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,17 @@ -.DS_Store -.coverage -.noseids -.ropeproject/ -.tox/ -*.py[co] -*~ -*.sqlite -*.sqlite-journal -settings_local.py -local_settings.py +*.egg-info/ + .*.sw[po] +*.py[co] + +build/ dist/ -*.egg-info doc/.build/ -build/ -locale/ +.ropeproject/ +.tox/ + +ChangeLog pip-log.txt + +.DS_Store +.coverage +.noseids From f5324acc71fda0792a1e7e54d7d9fb5c5aa1bb7e Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 15:40:41 +0100 Subject: [PATCH 081/110] [QA] Use Git*H*ub for the service name. --- README.rst | 6 +++--- doc/index.rst | 8 ++++---- examples/friend-or-follow.py | 4 ++-- github2/client.py | 8 ++++---- github2/core.py | 6 +++--- github2/issues.py | 16 ++++++++-------- github2/pull_requests.py | 8 ++++---- github2/repositories.py | 24 ++++++++++++------------ github2/request.py | 4 ++-- github2/users.py | 20 ++++++++++---------- 10 files changed, 52 insertions(+), 52 deletions(-) diff --git a/README.rst b/README.rst index 3e6ab34..a266014 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ ================================================================================ -github2 - Github API v2 library for Python. +github2 - GitHub API v2 library for Python. ================================================================================ :Authors: @@ -16,7 +16,7 @@ github2 - Github API v2 library for Python. of work needed in moving away from GitHub's API v2. This is a Python library implementing all of the features available in version 2 -of the `Github API`_. +of the `GitHub API`_. See the ``doc/`` directory for installation instructions and usage information. If you prefer you can also read the `documentation online`_. @@ -24,7 +24,7 @@ If you prefer you can also read the `documentation online`_. .. _switch off API v2: https://github.com/blog/1090-github-api-moving-on .. _remoteobjects: https://github.com/saymedia/remoteobjects .. _micromodels: https://github.com/j4mie/micromodels -.. _Github API: http://develop.github.com/ +.. _GitHub API: http://develop.github.com/ .. _documentation online: http://packages.python.org/github2 License diff --git a/doc/index.rst b/doc/index.rst index 55814bf..93438c9 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -10,7 +10,7 @@ .. module:: github2 :synopsis: GitHub API v2 library for Python -``github2`` - Github API v2 library for Python +``github2`` - GitHub API v2 library for Python ============================================== .. warning:: @@ -31,15 +31,15 @@ :class: sidebar This is a Python library implementing all of the features available in version 2 -of the `Github API`_. +of the `GitHub API`_. -You should read the developer documentation for the `Github API`_ first. +You should read the developer documentation for the `GitHub API`_ first. :Git repository: https://github.com/ask/python-github2/ :Issue tracker: https://github.com/ask/python-github2/issues/ :Contributors: https://github.com/ask/python-github2/contributors/ -.. _Github API: http://develop.github.com/ +.. _GitHub API: http://develop.github.com/ Contents -------- diff --git a/examples/friend-or-follow.py b/examples/friend-or-follow.py index ccef96a..55b6b8d 100644 --- a/examples/friend-or-follow.py +++ b/examples/friend-or-follow.py @@ -10,10 +10,10 @@ OPTION_LIST = ( optparse.make_option('-t', '--api-token', default=None, action="store", dest="api_token", type="str", - help="Github API token. Default is to find this from git config"), + help="GitHub API token. Default is to find this from git config"), optparse.make_option('-u', '--api-user', default=None, action="store", dest="api_user", type="str", - help="Github Username. Default is to find this from git config"), + help="GitHub Username. Default is to find this from git config"), ) BY_LOWER = lambda value: value.lower() diff --git a/github2/client.py b/github2/client.py index c585f3b..a141879 100644 --- a/github2/client.py +++ b/github2/client.py @@ -59,7 +59,7 @@ def __init__(self, username=None, api_token=None, requests_per_second=None, self.pull_requests = PullRequests(self.request) def project_for_user_repo(self, user, repo): - """Return Github identifier for a user's repository + """Return GitHub identifier for a user's repository :param str user: repository owner :param str repo: repository name @@ -97,7 +97,7 @@ def get_tree(self, project, tree_sha): return tree.get("tree", []) def get_network_meta(self, project): - """Get Github metadata associated with a project + """Get GitHub metadata associated with a project :param str project: GitHub project """ @@ -106,10 +106,10 @@ def get_network_meta(self, project): "network_meta"]), {}) def get_network_data(self, project, nethash, start=None, end=None): - """Get chunk of Github network data + """Get chunk of GitHub network data :param str project: GitHub project - :param str nethash: identifier provided by ``get_network_meta`` + :param str nethash: identifier provided by :meth:`get_network_meta` :param int start: optional start point for data :param int stop: optional end point for data """ diff --git a/github2/core.py b/github2/core.py index 856a489..a83dd6d 100644 --- a/github2/core.py +++ b/github2/core.py @@ -59,7 +59,7 @@ def wrapper(datetime_): @_handle_naive_datetimes def datetime_to_ghdate(datetime_): - """Convert Python datetime to Github date string + """Convert Python datetime to GitHub date string :param datetime datetime_: datetime object to convert """ @@ -68,7 +68,7 @@ def datetime_to_ghdate(datetime_): @_handle_naive_datetimes def datetime_to_commitdate(datetime_): - """Convert Python datetime to Github date string + """Convert Python datetime to GitHub date string :param datetime datetime_: datetime object to convert """ @@ -80,7 +80,7 @@ def datetime_to_commitdate(datetime_): def datetime_to_isodate(datetime_): - """Convert Python datetime to Github date string + """Convert Python datetime to GitHub date string :param str datetime_: datetime object to convert diff --git a/github2/issues.py b/github2/issues.py index 851f813..ae6ef48 100644 --- a/github2/issues.py +++ b/github2/issues.py @@ -86,7 +86,7 @@ def show(self, project, number): """Get all the data for issue by issue-number. :param str project: GitHub project - :param int number: issue number in the Github database + :param int number: issue number in the GitHub database """ return self.get_value("show", project, str(number), filter="issue", datatype=Issue) @@ -108,7 +108,7 @@ def close(self, project, number): """Close an issue :param str project: GitHub project - :param int number: issue number in the Github database + :param int number: issue number in the GitHub database """ return self.get_value("close", project, str(number), filter="issue", datatype=Issue, method="POST") @@ -120,7 +120,7 @@ def reopen(self, project, number): .. versionadded:: 0.3.0 :param str project: GitHub project - :param int number: issue number in the Github database + :param int number: issue number in the GitHub database """ return self.get_value("reopen", project, str(number), filter="issue", datatype=Issue, method="POST") @@ -132,7 +132,7 @@ def edit(self, project, number, title, body): .. versionadded:: 0.3.0 :param str project: GitHub project - :param int number: issue number in the Github database + :param int number: issue number in the GitHub database :param str title: title for issue :param str body: body for issue """ @@ -146,7 +146,7 @@ def add_label(self, project, number, label): """Add a label to an issue :param str project: GitHub project - :param int number: issue number in the Github database + :param int number: issue number in the GitHub database :param str label: label to attach to issue """ return self.get_values("label/add", project, label, str(number), @@ -157,7 +157,7 @@ def remove_label(self, project, number, label): """Remove an existing label from an issue :param str project: GitHub project - :param int number: issue number in the Github database + :param int number: issue number in the GitHub database :param str label: label to remove from issue """ return self.get_values("label/remove", project, label, str(number), @@ -168,7 +168,7 @@ def comment(self, project, number, comment): """Comment on an issue. :param str project: GitHub project - :param int number: issue number in the Github database + :param int number: issue number in the GitHub database :param str comment: comment to attach to issue """ comment_data = {'comment': comment} @@ -180,7 +180,7 @@ def comments(self, project, number): """View comments on an issue. :param str project: GitHub project - :param int number: issue number in the Github database + :param int number: issue number in the GitHub database """ return self.get_values("comments", project, str(number), filter="comments", datatype=Comment) diff --git a/github2/pull_requests.py b/github2/pull_requests.py index b75d62e..fa13b48 100644 --- a/github2/pull_requests.py +++ b/github2/pull_requests.py @@ -53,7 +53,7 @@ def create(self, project, base, head, title=None, body=None, issue=None): issue. If an ``issue`` parameter is supplied the pull request is attached to that issue, else a new pull request is created. - :param str project: the Github project to send the pull request to + :param str project: the GitHub project to send the pull request to :param str base: branch changes should be pulled into :param str head: branch of the changes to be pulled :param str title: title for pull request @@ -78,8 +78,8 @@ def create(self, project, base, head, title=None, body=None, issue=None): def show(self, project, number): """Show a single pull request - :param str project: Github project - :param int number: pull request number in the Github database + :param str project: GitHub project + :param int number: pull request number in the GitHub database """ return self.get_value(project, str(number), filter="pull", datatype=PullRequest) @@ -87,7 +87,7 @@ def show(self, project, number): def list(self, project, state="open", page=1): """List all pull requests for a project - :param str project: Github project + :param str project: GitHub project :param str state: can be either ``open`` or ``closed`` :param int page: optional page number """ diff --git a/github2/repositories.py b/github2/repositories.py index 89f8e57..501ffbb 100644 --- a/github2/repositories.py +++ b/github2/repositories.py @@ -73,7 +73,7 @@ def list(self, user=None, page=1): logged-in user when ``user`` wasn't supplied. This functionality is brittle and will be removed in a future release! - :param str user: Github user name to list repositories for + :param str user: GitHub user name to list repositories for :param int page: optional page number """ user = user or self.request.username @@ -160,8 +160,8 @@ def list_collaborators(self, project): def add_collaborator(self, project, username): """Adds an add_collaborator to a repo - :param str project: Github project - :param str username: Github user to add as collaborator + :param str project: GitHub project + :param str username: GitHub user to add as collaborator """ return self.make_request("collaborators", project, "add", username, method="POST") @@ -170,8 +170,8 @@ def add_collaborator(self, project, username): def remove_collaborator(self, project, username): """Removes an add_collaborator from a repo - :param str project: Github project - :param str username: Github user to add as collaborator + :param str project: GitHub project + :param str username: GitHub user to add as collaborator """ return self.make_request("collaborators", project, "remove", username, method="POST") @@ -179,7 +179,7 @@ def remove_collaborator(self, project, username): def network(self, project): """Get network data for project - :param str project: Github project + :param str project: GitHub project """ return self.get_values("show", project, "network", filter="network", datatype=Repository) @@ -187,7 +187,7 @@ def network(self, project): def languages(self, project): """Get programming language data for project - :param str project: Github project + :param str project: GitHub project """ return self.get_values("show", project, "languages", filter="languages") @@ -195,28 +195,28 @@ def languages(self, project): def tags(self, project): """Get tags for project - :param str project: Github project + :param str project: GitHub project """ return self.get_values("show", project, "tags", filter="tags") def branches(self, project): """Get branch names for project - :param str project: Github project + :param str project: GitHub project """ return self.get_values("show", project, "branches", filter="branches") def watchers(self, project): """Get list of watchers for project - :param str project: Github project + :param str project: GitHub project """ return self.get_values("show", project, "watchers", filter="watchers") def watching(self, for_user=None, page=None): """Lists all the repos a user is watching - :param str for_user: optional Github user name to list repositories for + :param str for_user: optional GitHub user name to list repositories for :param int page: optional page number """ for_user = for_user or self.request.username @@ -226,7 +226,7 @@ def watching(self, for_user=None, page=None): def list_contributors(self, project): """Lists all the contributors in a project - :param str project: Github project + :param str project: GitHub project """ return self.get_values("show", project, "contributors", filter="contributors", datatype=User) diff --git a/github2/request.py b/github2/request.py index 9aea264..c05ea97 100644 --- a/github2/request.py +++ b/github2/request.py @@ -81,11 +81,11 @@ def charset_from_headers(headers): class GithubError(Exception): - """An error occurred when making a request to the Github API.""" + """An error occurred when making a request to the GitHub API.""" class HttpError(RuntimeError): - """A HTTP error occured when making a request to the Github API.""" + """A HTTP error occured when making a request to the GitHub API.""" def __init__(self, message, content, code): """Create a HttpError exception diff --git a/github2/users.py b/github2/users.py index ad40fc1..d6fd9ac 100644 --- a/github2/users.py +++ b/github2/users.py @@ -73,42 +73,42 @@ def search_by_email(self, query): @enhanced_by_auth def show(self, username): - """Get information on Github user + """Get information on GitHub user if ``username`` is ``None`` or an empty string information for the currently authenticated user is returned. - :param str username: Github user name + :param str username: GitHub user name """ return self.get_value("show", username, filter="user", datatype=User) def followers(self, username): - """Get list of Github user's followers + """Get list of GitHub user's followers - :param str username: Github user name + :param str username: GitHub user name """ return self.get_values("show", username, "followers", filter="users") def following(self, username): - """Get list of users a Github user is following + """Get list of users a GitHub user is following - :param str username: Github user name + :param str username: GitHub user name """ return self.get_values("show", username, "following", filter="users") @requires_auth def follow(self, other_user): - """Follow a Github user + """Follow a GitHub user - :param str other_user: Github user name + :param str other_user: GitHub user name """ return self.get_values("follow", other_user, method="POST") @requires_auth def unfollow(self, other_user): - """Unfollow a Github user + """Unfollow a GitHub user - :param str other_user: Github user name + :param str other_user: GitHub user name """ return self.get_values("unfollow", other_user, method="POST") From 71f17c902f8a90d2aaffa06c9e40cd521941716e Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 15:41:05 +0100 Subject: [PATCH 082/110] [QA] Function notes come before param docs. --- github2/core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/github2/core.py b/github2/core.py index a83dd6d..3aed7c1 100644 --- a/github2/core.py +++ b/github2/core.py @@ -82,9 +82,10 @@ def datetime_to_commitdate(datetime_): def datetime_to_isodate(datetime_): """Convert Python datetime to GitHub date string + .. note:: Supports naive and timezone-aware datetimes + :param str datetime_: datetime object to convert - .. note:: Supports naive and timezone-aware datetimes """ if not datetime_.tzinfo: datetime_ = datetime_.replace(tzinfo=tz.tzutc()) From 6dcda6be8047f1672ed598a141ef4e7ac7d3711e Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 15:41:23 +0100 Subject: [PATCH 083/110] Fixed broken deprecated Sphinx directive. --- github2/repositories.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github2/repositories.py b/github2/repositories.py index 501ffbb..2d52fed 100644 --- a/github2/repositories.py +++ b/github2/repositories.py @@ -68,7 +68,7 @@ def pushable(self): def list(self, user=None, page=1): """Return a list of all repositories for a user. - .. deprecated: 0.4.0 + .. deprecated:: 0.4.0 Previous releases would attempt to display repositories for the logged-in user when ``user`` wasn't supplied. This functionality is brittle and will be removed in a future release! From 3a820369c94e9c521a7221cd12efca50abaa6ba1 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 15:47:16 +0100 Subject: [PATCH 084/110] [QA] Minor grammar fix in contributing doc. More fixes always welcome. --- doc/contributing.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/contributing.rst b/doc/contributing.rst index 8c3b47a..7c71bb2 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -4,9 +4,9 @@ Contributing Patches for :mod:`github2` are most welcome! Forks on GitHub_ and patches attached to issues are both great ways to -contribute. If you're comfortable with ``git`` using a fork hosted on GitHub is -probably the simpler solution, both for the package maintainers and you as a -contributor. +contribute. If you're comfortable with ``git`` then using a fork hosted on +GitHub is probably the simpler solution, both for the :mod:`github2` maintainers +and for you as a contributor. Following the simple guidelines below makes it easier to review and integrate your changes: From ec36b5772085c908d600f2171d622bfd690d7a2d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 15:23:44 +0100 Subject: [PATCH 085/110] [QA] Follow PEP 257 whitespace rules. --- github2/bin/manage_collaborators.py | 4 ++- github2/bin/search_repos.py | 4 ++- github2/client.py | 10 +++++-- github2/commits.py | 2 ++ github2/core.py | 21 ++++++++++++++- github2/issues.py | 20 +++++++++++--- github2/organizations.py | 6 +++++ github2/pull_requests.py | 11 ++++++-- github2/repositories.py | 41 ++++++++++++++++++++++------- github2/request.py | 9 +++++-- github2/teams.py | 10 +++++++ github2/users.py | 22 +++++++++++----- 12 files changed, 131 insertions(+), 29 deletions(-) diff --git a/github2/bin/manage_collaborators.py b/github2/bin/manage_collaborators.py index 3efafee..5e585d2 100755 --- a/github2/bin/manage_collaborators.py +++ b/github2/bin/manage_collaborators.py @@ -26,7 +26,9 @@ def print_(text): """Python 2 & 3 compatible print function - We support <2.6, so can't use __future__.print_function""" + We support <2.6, so can't use __future__.print_function + + """ if PY3K: print(text) else: diff --git a/github2/bin/search_repos.py b/github2/bin/search_repos.py index c52be46..737caa2 100755 --- a/github2/bin/search_repos.py +++ b/github2/bin/search_repos.py @@ -19,7 +19,9 @@ def print_(text): """Python 2 & 3 compatible print function - We support <2.6, so can't use __future__.print_function""" + We support <2.6, so can't use __future__.print_function + + """ if PY3K: print(text) else: diff --git a/github2/client.py b/github2/client.py index a141879..7b3d8eb 100644 --- a/github2/client.py +++ b/github2/client.py @@ -13,8 +13,7 @@ class Github(object): def __init__(self, username=None, api_token=None, requests_per_second=None, access_token=None, cache=None, proxy_host=None, proxy_port=8080, github_url=None): - """ - An interface to GitHub's API: + """An interface to GitHub's API: http://develop.github.com/ .. versionadded:: 0.2.0 @@ -42,6 +41,7 @@ def __init__(self, username=None, api_token=None, requests_per_second=None, default to 8080 if a proxy_host is set and no port is set). :param str github_url: the hostname to connect to, for GitHub Enterprise support + """ self.request = GithubRequest(username=username, api_token=api_token, @@ -63,6 +63,7 @@ def project_for_user_repo(self, user, repo): :param str user: repository owner :param str repo: repository name + """ return "/".join([user, repo]) @@ -73,6 +74,7 @@ def get_all_blobs(self, project, tree_sha): :param str project: GitHub project :param str tree_sha: object ID of tree + """ blobs = self.request.get("blob/all", project, tree_sha) return blobs.get("blobs") @@ -83,6 +85,7 @@ def get_blob_info(self, project, tree_sha, path): :param str project: GitHub project :param str tree_sha: object ID of tree :param str path: path within tree to fetch blob for + """ blob = self.request.get("blob/show", project, tree_sha, path) return blob.get("blob") @@ -92,6 +95,7 @@ def get_tree(self, project, tree_sha): :param str project: GitHub project :param str tree_sha: object ID of tree + """ tree = self.request.get("tree/show", project, tree_sha) return tree.get("tree", []) @@ -100,6 +104,7 @@ def get_network_meta(self, project): """Get GitHub metadata associated with a project :param str project: GitHub project + """ return self.request.raw_request("/".join([self.request.github_url, project, @@ -112,6 +117,7 @@ def get_network_data(self, project, nethash, start=None, end=None): :param str nethash: identifier provided by :meth:`get_network_meta` :param int start: optional start point for data :param int stop: optional end point for data + """ data = {"nethash": nethash} if start: diff --git a/github2/commits.py b/github2/commits.py index 8910937..7030a40 100644 --- a/github2/commits.py +++ b/github2/commits.py @@ -39,6 +39,7 @@ def list(self, project, branch="master", file=None, page=1): :param str branch: branch name, or ``master`` if not given :param str file: optional file filter :param int page: optional page number + """ return self.get_values("list", project, branch, file, filter="commits", datatype=Commit, page=page) @@ -48,6 +49,7 @@ def show(self, project, sha): :param str project: project name :param str sha: commit id + """ return self.get_value("show", project, sha, filter="commit", datatype=Commit) diff --git a/github2/core.py b/github2/core.py index 3aed7c1..e783456 100644 --- a/github2/core.py +++ b/github2/core.py @@ -30,6 +30,7 @@ def string_to_datetime(string): """Convert a string to Python datetime :param str github_date: date string to parse + """ parsed = parser.parse(string) if NAIVE: @@ -41,6 +42,7 @@ def _handle_naive_datetimes(f): """Decorator to make datetime arguments use GitHub timezone :param func f: Function to wrap + """ def wrapper(datetime_): if not datetime_.tzinfo: @@ -62,6 +64,7 @@ def datetime_to_ghdate(datetime_): """Convert Python datetime to GitHub date string :param datetime datetime_: datetime object to convert + """ return datetime_.strftime(GITHUB_DATE_FORMAT) @@ -71,6 +74,7 @@ def datetime_to_commitdate(datetime_): """Convert Python datetime to GitHub date string :param datetime datetime_: datetime object to convert + """ date_without_tz = datetime_.strftime(COMMIT_DATE_FORMAT) utcoffset = GITHUB_TZ.utcoffset(datetime_) @@ -95,7 +99,8 @@ def datetime_to_isodate(datetime_): class AuthError(Exception): - """Requires authentication""" + + """Requires authentication.""" def requires_auth(f): @@ -105,6 +110,7 @@ def requires_auth(f): :param func f: Function to wrap :raises AuthError: If function called without an authenticated session + """ # When Python 2.4 support is dropped move straight to functools.wraps, # don't pass go and don't collect $200. @@ -129,6 +135,7 @@ def enhanced_by_auth(f): introspection. :param func f: Function to wrap + """ f.enhanced_by_auth = True f.__doc__ += """\n.. note:: This call is enhanced with authentication""" @@ -141,6 +148,7 @@ def __init__(self, request): """Main API binding interface :param github2.request.GithubRequest request: HTTP request handler + """ self.request = request @@ -155,6 +163,7 @@ def make_request(self, command, *args, **kwargs): data * The value of a ``page`` argument will be used to fetch a specific page of results, default of 1 is assumed if not given + """ filter = kwargs.get("filter") post_data = kwargs.get("post_data") or {} @@ -182,6 +191,7 @@ def get_value(self, *args, **kwargs): If a ``datatype`` parameter is given it defines the :class:`BaseData`-derived class we should build from the provided data + """ datatype = kwargs.pop("datatype", None) value = self.make_request(*args, **kwargs) @@ -200,6 +210,7 @@ def get_values(self, *args, **kwargs): """Process a multi-value response from the API :see: :meth:`get_value` + """ datatype = kwargs.pop("datatype", None) values = self.make_request(*args, **kwargs) @@ -221,6 +232,7 @@ def doc_generator(docstring, attributes): :param str docstring: docstring to augment :param dict attributes: attributes to add to docstring + """ docstring = docstring or "" @@ -237,6 +249,7 @@ def __init__(self, help): """Generic object attribute for use with :class:`BaseData` :param str help: Attribute description + """ self.help = help @@ -260,6 +273,7 @@ def __init__(self, *args, **kwargs): :param str format: The date format to support, see :data:`convertor_for_format` for supported options + """ self.format = kwargs.pop("format", self.format) super(DateAttribute, self).__init__(*args, **kwargs) @@ -318,12 +332,15 @@ class BaseData(BaseDataType('BaseData', (object, ), {})): .. warning:: Supports subscript attribute access purely for backwards compatibility, you shouldn't rely on that functionality in new code + """ + def __getitem__(self, key): """Access objects's attribute using subscript notation This is here purely to maintain compatibility when switching ``dict`` responses to ``BaseData`` derived objects. + """ LOGGER.warning("Subscript access on %r is deprecated, use object " "attributes" % self.__class__.__name__, @@ -336,6 +353,7 @@ def __setitem__(self, key, value): """Update object's attribute using subscript notation :see: :meth:`BaseData.__getitem__` + """ LOGGER.warning("Subscript access on %r is deprecated, use object " "attributes" % self.__class__.__name__, @@ -350,6 +368,7 @@ def repr_string(string): :param str string: string to operate on :return: string, with maximum length of 20 characters + """ if len(string) > 20: string = string[:17] + '...' diff --git a/github2/issues.py b/github2/issues.py index ae6ef48..ad7aa35 100644 --- a/github2/issues.py +++ b/github2/issues.py @@ -49,6 +49,7 @@ def search(self, project, term, state="open"): :param str project: GitHub project :param str term: term to search issues for :param str state: can be either ``open`` or ``closed``. + """ return self.get_values("search", project, state, quote_plus(term), filter="issues", datatype=Issue) @@ -58,6 +59,7 @@ def list(self, project, state="open"): :param str project: GitHub project :param str state: can be either ``open`` or ``closed``. + """ return self.get_values("list", project, state, filter="issues", datatype=Issue) @@ -69,6 +71,7 @@ def list_by_label(self, project, label): :param str project: GitHub project :param str label: a string representing a label (e.g., ``bug``). + """ return self.get_values("list", project, "label", label, filter="issues", datatype=Issue) @@ -79,6 +82,7 @@ def list_labels(self, project): .. versionadded:: 0.3.0 :param str project: GitHub project + """ return self.get_values("labels", project, filter="labels") @@ -86,7 +90,8 @@ def show(self, project, number): """Get all the data for issue by issue-number. :param str project: GitHub project - :param int number: issue number in the GitHub database + :param int number: issue number in the Github database + """ return self.get_value("show", project, str(number), filter="issue", datatype=Issue) @@ -98,6 +103,7 @@ def open(self, project, title, body): :param str project: GitHub project :param str title: title for issue :param str body: body for issue + """ issue_data = {"title": title, "body": body} return self.get_value("open", project, post_data=issue_data, @@ -108,7 +114,8 @@ def close(self, project, number): """Close an issue :param str project: GitHub project - :param int number: issue number in the GitHub database + :param int number: issue number in the Github database + """ return self.get_value("close", project, str(number), filter="issue", datatype=Issue, method="POST") @@ -120,7 +127,8 @@ def reopen(self, project, number): .. versionadded:: 0.3.0 :param str project: GitHub project - :param int number: issue number in the GitHub database + :param int number: issue number in the Github database + """ return self.get_value("reopen", project, str(number), filter="issue", datatype=Issue, method="POST") @@ -135,6 +143,7 @@ def edit(self, project, number, title, body): :param int number: issue number in the GitHub database :param str title: title for issue :param str body: body for issue + """ issue_data = {"title": title, "body": body} return self.get_value("edit", project, str(number), @@ -148,6 +157,7 @@ def add_label(self, project, number, label): :param str project: GitHub project :param int number: issue number in the GitHub database :param str label: label to attach to issue + """ return self.get_values("label/add", project, label, str(number), filter="labels", method="POST") @@ -159,6 +169,7 @@ def remove_label(self, project, number, label): :param str project: GitHub project :param int number: issue number in the GitHub database :param str label: label to remove from issue + """ return self.get_values("label/remove", project, label, str(number), filter="labels", method="POST") @@ -170,6 +181,7 @@ def comment(self, project, number, comment): :param str project: GitHub project :param int number: issue number in the GitHub database :param str comment: comment to attach to issue + """ comment_data = {'comment': comment} return self.get_value("comment", project, str(number), @@ -180,7 +192,7 @@ def comments(self, project, number): """View comments on an issue. :param str project: GitHub project - :param int number: issue number in the GitHub database + """ return self.get_values("comments", project, str(number), filter="comments", datatype=Comment) diff --git a/github2/organizations.py b/github2/organizations.py index 38eac83..8baa328 100644 --- a/github2/organizations.py +++ b/github2/organizations.py @@ -42,6 +42,7 @@ def show(self, organization): """Get information on organization :param str organization: organization to show + """ return self.get_value(organization, filter="organization", datatype=Organization) @@ -58,6 +59,7 @@ def repositories(self, organization=''): repositories for all organizations the authenticated user belongs to. :param: str organization: organization to list repositories for + """ return self.get_values(organization, 'repositories', filter="repositories", datatype=Repository) @@ -66,6 +68,7 @@ def public_repositories(self, organization): """Get list of public repositories in an organization :param str organization: organization to list public repositories for + """ return self.get_values(organization, 'public_repositories', filter="repositories", datatype=Repository) @@ -74,6 +77,7 @@ def public_members(self, organization): """Get list of public members in an organization :param str organization: organization to list members for + """ return self.get_values(organization, 'public_members', filter="users", datatype=User) @@ -82,6 +86,7 @@ def teams(self, organization): """Get list of teams in an organization :param str organization: organization to list teams for + """ return self.get_values(organization, 'teams', filter="teams", datatype=Team) @@ -94,6 +99,7 @@ def add_team(self, organization, name, permission='pull', projects=None): :param str team: name of team to add :param str permission: permissions for team(push, pull or admin) :param list projects: optional GitHub projects for this team + """ team_data = {'team[name]': name, 'team[permission]': permission} if projects: diff --git a/github2/pull_requests.py b/github2/pull_requests.py index fa13b48..9a0ba58 100644 --- a/github2/pull_requests.py +++ b/github2/pull_requests.py @@ -6,7 +6,9 @@ class PullRequest(BaseData): """Pull request encapsulation .. versionadded:: 0.5.0 + """ + state = Attribute("The pull request state") base = Attribute("The base repo") head = Attribute("The head of the pull request") @@ -43,7 +45,9 @@ class PullRequests(GithubCommand): """Operations on pull requests .. versionadded:: 0.5.0 + """ + domain = "pulls" def create(self, project, base, head, title=None, body=None, issue=None): @@ -59,6 +63,7 @@ def create(self, project, base, head, title=None, body=None, issue=None): :param str title: title for pull request :param str body: optional body for pull request :param str issue: existing issue to attach pull request to + """ post_data = {"base": base, "head": head} if issue: @@ -78,8 +83,9 @@ def create(self, project, base, head, title=None, body=None, issue=None): def show(self, project, number): """Show a single pull request - :param str project: GitHub project - :param int number: pull request number in the GitHub database + :param str project: Github project + :param int number: pull request number in the Github database + """ return self.get_value(project, str(number), filter="pull", datatype=PullRequest) @@ -90,6 +96,7 @@ def list(self, project, state="open", page=1): :param str project: GitHub project :param str state: can be either ``open`` or ``closed`` :param int page: optional page number + """ return self.get_values(project, state, filter="pulls", datatype=PullRequest, page=page) diff --git a/github2/repositories.py b/github2/repositories.py index 2d52fed..4f9b0cf 100644 --- a/github2/repositories.py +++ b/github2/repositories.py @@ -44,6 +44,7 @@ def search(self, query): Returns at most 100 repositories :param str query: term to search issues for + """ return self.get_values("search", query, filter="repositories", datatype=Repository) @@ -52,6 +53,7 @@ def show(self, project): """Get repository object for project. :param str project: GitHub project + """ return self.get_value("show", project, filter="repository", datatype=Repository) @@ -61,6 +63,7 @@ def pushable(self): """Return a list of repos you can push to that are not your own. .. versionadded:: 0.3.0 + """ return self.get_values("pushable", filter="repositories", datatype=Repository) @@ -75,6 +78,7 @@ def list(self, user=None, page=1): :param str user: GitHub user name to list repositories for :param int page: optional page number + """ user = user or self.request.username return self.get_values("show", user, filter="repositories", @@ -85,6 +89,7 @@ def watch(self, project): """Watch a project :param str project: GitHub project + """ return self.get_value("watch", project, filter='repository', datatype=Repository) @@ -94,6 +99,7 @@ def unwatch(self, project): """Unwatch a project :param str project: GitHub project + """ return self.get_value("unwatch", project, filter='repository', datatype=Repository) @@ -103,6 +109,7 @@ def fork(self, project): """Fork a project :param str project: GitHub project + """ return self.get_value("fork", project, filter="repository", datatype=Repository) @@ -115,6 +122,7 @@ def create(self, project, description=None, homepage=None, public=True): :param str description: optional project description :param str homepage: optional project homepage :param bool public: whether to make a public project + """ repo_data = {"name": project, "description": description, "homepage": homepage, "public": str(int(public))} @@ -126,6 +134,7 @@ def delete(self, project): """Delete a repository :param str project: project name to delete + """ # Two-step delete mechanism. We must echo the delete_token value back # to GitHub to actually delete a repository @@ -137,6 +146,7 @@ def set_private(self, project): """Mark repository as private :param str project: project name to set as private + """ return self.make_request("set/private", project) @@ -145,6 +155,7 @@ def set_public(self, project): """Mark repository as public :param str project: project name to set as public + """ return self.make_request("set/public", project) @@ -152,6 +163,7 @@ def list_collaborators(self, project): """Lists all the collaborators in a project :param str project: GitHub project + """ return self.get_values("show", project, "collaborators", filter="collaborators") @@ -160,8 +172,9 @@ def list_collaborators(self, project): def add_collaborator(self, project, username): """Adds an add_collaborator to a repo - :param str project: GitHub project - :param str username: GitHub user to add as collaborator + :param str project: Github project + :param str username: Github user to add as collaborator + """ return self.make_request("collaborators", project, "add", username, method="POST") @@ -170,8 +183,9 @@ def add_collaborator(self, project, username): def remove_collaborator(self, project, username): """Removes an add_collaborator from a repo - :param str project: GitHub project - :param str username: GitHub user to add as collaborator + :param str project: Github project + :param str username: Github user to add as collaborator + """ return self.make_request("collaborators", project, "remove", username, method="POST") @@ -179,7 +193,8 @@ def remove_collaborator(self, project, username): def network(self, project): """Get network data for project - :param str project: GitHub project + :param str project: Github project + """ return self.get_values("show", project, "network", filter="network", datatype=Repository) @@ -187,7 +202,8 @@ def network(self, project): def languages(self, project): """Get programming language data for project - :param str project: GitHub project + :param str project: Github project + """ return self.get_values("show", project, "languages", filter="languages") @@ -195,21 +211,24 @@ def languages(self, project): def tags(self, project): """Get tags for project - :param str project: GitHub project + :param str project: Github project + """ return self.get_values("show", project, "tags", filter="tags") def branches(self, project): """Get branch names for project - :param str project: GitHub project + :param str project: Github project + """ return self.get_values("show", project, "branches", filter="branches") def watchers(self, project): """Get list of watchers for project - :param str project: GitHub project + :param str project: Github project + """ return self.get_values("show", project, "watchers", filter="watchers") @@ -218,6 +237,7 @@ def watching(self, for_user=None, page=None): :param str for_user: optional GitHub user name to list repositories for :param int page: optional page number + """ for_user = for_user or self.request.username return self.get_values("watched", for_user, filter="repositories", @@ -226,7 +246,8 @@ def watching(self, for_user=None, page=None): def list_contributors(self, project): """Lists all the contributors in a project - :param str project: GitHub project + :param str project: Github project + """ return self.get_values("show", project, "contributors", filter="contributors", datatype=User) diff --git a/github2/request.py b/github2/request.py index c05ea97..12a9363 100644 --- a/github2/request.py +++ b/github2/request.py @@ -71,6 +71,7 @@ def charset_from_headers(headers): :param httplib2.Response headers: Request headers :return: Defined encoding, or default to ASCII + """ match = re.search("charset=([^ ;]+)", headers.get('content-type', "")) if match: @@ -81,17 +82,21 @@ def charset_from_headers(headers): class GithubError(Exception): - """An error occurred when making a request to the GitHub API.""" + + """An error occurred when making a request to the Github API.""" class HttpError(RuntimeError): - """A HTTP error occured when making a request to the GitHub API.""" + + """A HTTP error occured when making a request to the Github API.""" + def __init__(self, message, content, code): """Create a HttpError exception :param str message: Exception string :param str content: Full content of HTTP request :param int code: HTTP status code + """ self.args = (message, content, code) self.message = message diff --git a/github2/teams.py b/github2/teams.py index b46116f..c2c7945 100644 --- a/github2/teams.py +++ b/github2/teams.py @@ -4,7 +4,9 @@ class Team(BaseData): + """.. versionadded:: 0.4.0""" + id = Attribute("The team id") name = Attribute("Name of the team") permission = Attribute("Permissions of the team") @@ -14,13 +16,16 @@ def __repr__(self): class Teams(GithubCommand): + """.. versionadded:: 0.4.0""" + domain = "teams" def show(self, team_id): """Get information on team_id :param int team_id: team to get information for + """ return self.get_value(str(team_id), filter="team", datatype=Team) @@ -28,6 +33,7 @@ def members(self, team_id): """Get list of all team members :param int team_id: team to get information for + """ return self.get_values(str(team_id), "members", filter="users", datatype=User) @@ -38,6 +44,7 @@ def add_member(self, team_id, username): :param int team_id: team to add new member to :param str username: GitHub username to add to team + """ return self.get_values(str(team_id), 'members', method='POST', post_data={'name': username}, filter='users', @@ -47,6 +54,7 @@ def repositories(self, team_id): """Get list of all team repositories :param int team_id: team to get information for + """ return self.get_values(str(team_id), "repositories", filter="repositories", datatype=Repository) @@ -57,6 +65,7 @@ def add_project(self, team_id, project): :param int team_id: team to add repository to :param str project: GitHub project + """ if isinstance(project, Repository): project = project.project @@ -70,6 +79,7 @@ def remove_project(self, team_id, project): :param int team_id: team to remove project from :param str project: GitHub project + """ if isinstance(project, Repository): project = project.project diff --git a/github2/users.py b/github2/users.py index d6fd9ac..50b761e 100644 --- a/github2/users.py +++ b/github2/users.py @@ -43,7 +43,9 @@ class User(BaseData): def is_authenticated(self): """Test for user authentication - :return bool: ``True`` if user is authenticated""" + :return bool: ``True`` if user is authenticated + + """ return self.plan is not None def __repr__(self): @@ -60,6 +62,7 @@ def search(self, query): Returns at most 100 users :param str query: term to search for + """ return self.get_values("search", quote_plus(query), filter="users", datatype=User) @@ -68,6 +71,7 @@ def search_by_email(self, query): """Search for users by email address :param str query: email to search for + """ return self.get_value("email", query, filter="user", datatype=User) @@ -78,21 +82,23 @@ def show(self, username): if ``username`` is ``None`` or an empty string information for the currently authenticated user is returned. - :param str username: GitHub user name + """ return self.get_value("show", username, filter="user", datatype=User) def followers(self, username): """Get list of GitHub user's followers - :param str username: GitHub user name + :param str username: Github user name + """ return self.get_values("show", username, "followers", filter="users") def following(self, username): """Get list of users a GitHub user is following - :param str username: GitHub user name + :param str username: Github user name + """ return self.get_values("show", username, "following", filter="users") @@ -100,7 +106,8 @@ def following(self, username): def follow(self, other_user): """Follow a GitHub user - :param str other_user: GitHub user name + :param str other_user: Github user name + """ return self.get_values("follow", other_user, method="POST") @@ -108,7 +115,8 @@ def follow(self, other_user): def unfollow(self, other_user): """Unfollow a GitHub user - :param str other_user: GitHub user name + :param str other_user: Github user name + """ return self.get_values("unfollow", other_user, method="POST") @@ -123,6 +131,7 @@ def add_key(self, key, title=''): :param str key: SSH key identifier :param str title: Optional title for the SSH key + """ return self.get_values("key/add", post_data={'key': key, 'title': title}, @@ -134,6 +143,7 @@ def remove_key(self, key_id): """Remove a SSH key for the authenticated user :param int key_id: SSH key's GitHub identifier + """ return self.get_values('key/remove', post_data={'id': str(key_id)}, filter='public_keys', datatype=Key) From d4441b921c83437bd65cf62df6170224dc6e6fee Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 15:28:50 +0100 Subject: [PATCH 086/110] [QA] Use PEP 257 punctuation guidelines. --- github2/bin/manage_collaborators.py | 6 ++--- github2/bin/search_repos.py | 6 ++--- github2/client.py | 12 ++++----- github2/commits.py | 4 +-- github2/core.py | 40 ++++++++++++++--------------- github2/issues.py | 16 ++++++------ github2/organizations.py | 14 +++++----- github2/pull_requests.py | 10 ++++---- github2/repositories.py | 34 ++++++++++++------------ github2/request.py | 4 +-- github2/teams.py | 12 ++++----- github2/users.py | 22 ++++++++-------- 12 files changed, 90 insertions(+), 90 deletions(-) diff --git a/github2/bin/manage_collaborators.py b/github2/bin/manage_collaborators.py index 5e585d2..79da700 100755 --- a/github2/bin/manage_collaborators.py +++ b/github2/bin/manage_collaborators.py @@ -24,7 +24,7 @@ def print_(text): - """Python 2 & 3 compatible print function + """Python 2 & 3 compatible print function. We support <2.6, so can't use __future__.print_function @@ -36,7 +36,7 @@ def print_(text): def parse_commandline(): - """Parse the comandline and return parsed options.""" + """Parse the command line and return parsed options.""" parser = OptionParser() parser.description = __doc__ @@ -75,7 +75,7 @@ def parse_commandline(): def main(): - """This implements the actual program functionality""" + """Implement the actual program functionality.""" options, args = parse_commandline() diff --git a/github2/bin/search_repos.py b/github2/bin/search_repos.py index 737caa2..895d874 100755 --- a/github2/bin/search_repos.py +++ b/github2/bin/search_repos.py @@ -17,7 +17,7 @@ def print_(text): - """Python 2 & 3 compatible print function + """Python 2 & 3 compatible print function. We support <2.6, so can't use __future__.print_function @@ -29,7 +29,7 @@ def print_(text): def parse_commandline(): - """Parse the comandline and return parsed options.""" + """Parse the command line and return parsed options.""" parser = OptionParser() parser.description = __doc__ @@ -48,7 +48,7 @@ def parse_commandline(): def main(): - """This implements the actual program functionality""" + """Implement the actual program functionality.""" return_value = 0 options, term = parse_commandline() diff --git a/github2/client.py b/github2/client.py index 7b3d8eb..0296be4 100644 --- a/github2/client.py +++ b/github2/client.py @@ -59,7 +59,7 @@ def __init__(self, username=None, api_token=None, requests_per_second=None, self.pull_requests = PullRequests(self.request) def project_for_user_repo(self, user, repo): - """Return GitHub identifier for a user's repository + """Return Github identifier for a user's repository. :param str user: repository owner :param str repo: repository name @@ -68,7 +68,7 @@ def project_for_user_repo(self, user, repo): return "/".join([user, repo]) def get_all_blobs(self, project, tree_sha): - """Get a list of all blobs for a specific tree + """Get a list of all blobs for a specific tree. .. versionadded:: 0.3.0 @@ -80,7 +80,7 @@ def get_all_blobs(self, project, tree_sha): return blobs.get("blobs") def get_blob_info(self, project, tree_sha, path): - """Get the blob for a file within a specific tree + """Get the blob for a file within a specific tree. :param str project: GitHub project :param str tree_sha: object ID of tree @@ -91,7 +91,7 @@ def get_blob_info(self, project, tree_sha, path): return blob.get("blob") def get_tree(self, project, tree_sha): - """Get tree information for a specifc tree + """Get tree information for a specifc tree. :param str project: GitHub project :param str tree_sha: object ID of tree @@ -101,7 +101,7 @@ def get_tree(self, project, tree_sha): return tree.get("tree", []) def get_network_meta(self, project): - """Get GitHub metadata associated with a project + """Get Github metadata associated with a project. :param str project: GitHub project @@ -111,7 +111,7 @@ def get_network_meta(self, project): "network_meta"]), {}) def get_network_data(self, project, nethash, start=None, end=None): - """Get chunk of GitHub network data + """Get chunk of Github network data. :param str project: GitHub project :param str nethash: identifier provided by :meth:`get_network_meta` diff --git a/github2/commits.py b/github2/commits.py index 7030a40..2bfd152 100644 --- a/github2/commits.py +++ b/github2/commits.py @@ -28,7 +28,7 @@ class Commits(GithubCommand): domain = "commits" def list(self, project, branch="master", file=None, page=1): - """List commits on a project + """List commits on a project. .. warning:: Not all projects use ``master`` as their default branch, you can @@ -45,7 +45,7 @@ def list(self, project, branch="master", file=None, page=1): datatype=Commit, page=page) def show(self, project, sha): - """Get a specific commit + """Get a specific commit. :param str project: project name :param str sha: commit id diff --git a/github2/core.py b/github2/core.py index e783456..9329e5e 100644 --- a/github2/core.py +++ b/github2/core.py @@ -27,7 +27,7 @@ def string_to_datetime(string): - """Convert a string to Python datetime + """Convert a string to Python datetime. :param str github_date: date string to parse @@ -39,7 +39,7 @@ def string_to_datetime(string): def _handle_naive_datetimes(f): - """Decorator to make datetime arguments use GitHub timezone + """Decorator to make datetime arguments use GitHub timezone. :param func f: Function to wrap @@ -61,7 +61,7 @@ def wrapper(datetime_): @_handle_naive_datetimes def datetime_to_ghdate(datetime_): - """Convert Python datetime to GitHub date string + """Convert Python datetime to Github date string. :param datetime datetime_: datetime object to convert @@ -71,7 +71,7 @@ def datetime_to_ghdate(datetime_): @_handle_naive_datetimes def datetime_to_commitdate(datetime_): - """Convert Python datetime to GitHub date string + """Convert Python datetime to Github date string. :param datetime datetime_: datetime object to convert @@ -84,12 +84,11 @@ def datetime_to_commitdate(datetime_): def datetime_to_isodate(datetime_): - """Convert Python datetime to GitHub date string - - .. note:: Supports naive and timezone-aware datetimes + """Convert Python datetime to Github date string. :param str datetime_: datetime object to convert + .. note:: Supports naive and timezone-aware datetimes """ if not datetime_.tzinfo: datetime_ = datetime_.replace(tzinfo=tz.tzutc()) @@ -104,7 +103,7 @@ class AuthError(Exception): def requires_auth(f): - """Decorate to check a function call for authentication + """Decorate to check a function call for authentication. Sets a ``requires_auth`` attribute on functions, for use in introspection. @@ -129,7 +128,7 @@ def wrapper(self, *args, **kwargs): def enhanced_by_auth(f): - """Decorator to mark a function as enhanced by authentication + """Decorator to mark a function as enhanced by authentication. Sets a ``enhanced_by_auth`` attribute on functions, for use in introspection. @@ -145,7 +144,7 @@ def enhanced_by_auth(f): class GithubCommand(object): def __init__(self, request): - """Main API binding interface + """Main API binding interface. :param github2.request.GithubRequest request: HTTP request handler @@ -153,7 +152,7 @@ def __init__(self, request): self.request = request def make_request(self, command, *args, **kwargs): - """Make an API request + """Make an API request. Various options are supported if they exist in ``kwargs``: @@ -187,7 +186,7 @@ def make_request(self, command, *args, **kwargs): return response def get_value(self, *args, **kwargs): - """Process a single-value response from the API + """Process a single-value response from the API. If a ``datatype`` parameter is given it defines the :class:`BaseData`-derived class we should build from the provided data @@ -207,7 +206,7 @@ def get_value(self, *args, **kwargs): return value def get_values(self, *args, **kwargs): - """Process a multi-value response from the API + """Process a multi-value response from the API. :see: :meth:`get_value` @@ -228,7 +227,7 @@ def get_values(self, *args, **kwargs): def doc_generator(docstring, attributes): - """Utility function to augment BaseDataType docstring + """Utility function to augment BaseDataType docstring. :param str docstring: docstring to augment :param dict attributes: attributes to add to docstring @@ -246,7 +245,7 @@ def bullet(title, text): class Attribute(object): def __init__(self, help): - """Generic object attribute for use with :class:`BaseData` + """Generic object attribute for use with :class:`BaseData`. :param str help: Attribute description @@ -269,7 +268,7 @@ class DateAttribute(Attribute): } def __init__(self, *args, **kwargs): - """Date handling attribute for use with :class:`BaseData` + """Date handling attribute for use with :class:`BaseData`. :param str format: The date format to support, see :data:`convertor_for_format` for supported options @@ -327,7 +326,8 @@ def iterate(self): # Ugly base class definition for Python 2 and 3 compatibility, where metaclass # syntax is incompatible class BaseData(BaseDataType('BaseData', (object, ), {})): - """Wrapper for API responses + + """Wrapper for API responses. .. warning:: Supports subscript attribute access purely for backwards compatibility, @@ -336,7 +336,7 @@ class BaseData(BaseDataType('BaseData', (object, ), {})): """ def __getitem__(self, key): - """Access objects's attribute using subscript notation + """Access objects's attribute using subscript notation. This is here purely to maintain compatibility when switching ``dict`` responses to ``BaseData`` derived objects. @@ -350,7 +350,7 @@ def __getitem__(self, key): return getattr(self, key) def __setitem__(self, key, value): - """Update object's attribute using subscript notation + """Update object's attribute using subscript notation. :see: :meth:`BaseData.__getitem__` @@ -364,7 +364,7 @@ def __setitem__(self, key, value): def repr_string(string): - """Shorten string for use in repr() output + """Shorten string for use in repr() output. :param str string: string to operate on :return: string, with maximum length of 20 characters diff --git a/github2/issues.py b/github2/issues.py index ad7aa35..0f72908 100644 --- a/github2/issues.py +++ b/github2/issues.py @@ -48,7 +48,7 @@ def search(self, project, term, state="open"): :param str project: GitHub project :param str term: term to search issues for - :param str state: can be either ``open`` or ``closed``. + :param str state: can be either ``open`` or ``closed`` """ return self.get_values("search", project, state, quote_plus(term), @@ -58,7 +58,7 @@ def list(self, project, state="open"): """Get all issues for project with given state. :param str project: GitHub project - :param str state: can be either ``open`` or ``closed``. + :param str state: can be either ``open`` or ``closed`` """ return self.get_values("list", project, state, filter="issues", @@ -70,7 +70,7 @@ def list_by_label(self, project, label): .. versionadded:: 0.3.0 :param str project: GitHub project - :param str label: a string representing a label (e.g., ``bug``). + :param str label: a string representing a label (e.g., ``bug``) """ return self.get_values("list", project, "label", label, @@ -111,7 +111,7 @@ def open(self, project, title, body): @requires_auth def close(self, project, number): - """Close an issue + """Close an issue. :param str project: GitHub project :param int number: issue number in the Github database @@ -122,7 +122,7 @@ def close(self, project, number): @requires_auth def reopen(self, project, number): - """Reopen a closed issue + """Reopen a closed issue. .. versionadded:: 0.3.0 @@ -135,7 +135,7 @@ def reopen(self, project, number): @requires_auth def edit(self, project, number, title, body): - """Edit an existing issue + """Edit an existing issue. .. versionadded:: 0.3.0 @@ -152,7 +152,7 @@ def edit(self, project, number, title, body): @requires_auth def add_label(self, project, number, label): - """Add a label to an issue + """Add a label to an issue. :param str project: GitHub project :param int number: issue number in the GitHub database @@ -164,7 +164,7 @@ def add_label(self, project, number, label): @requires_auth def remove_label(self, project, number, label): - """Remove an existing label from an issue + """Remove an existing label from an issue. :param str project: GitHub project :param int number: issue number in the GitHub database diff --git a/github2/organizations.py b/github2/organizations.py index 8baa328..263990b 100644 --- a/github2/organizations.py +++ b/github2/organizations.py @@ -39,7 +39,7 @@ class Organizations(GithubCommand): domain = "organizations" def show(self, organization): - """Get information on organization + """Get information on organization. :param str organization: organization to show @@ -48,12 +48,12 @@ def show(self, organization): datatype=Organization) def list(self): - """Get list of all of your organizations""" + """Get list of all of your organizations.""" return self.get_values('', filter="organizations", datatype=Organization) def repositories(self, organization=''): - """Get list of all repositories in an organization + """Get list of all repositories in an organization. If organization is not given, or is empty, then this will list repositories for all organizations the authenticated user belongs to. @@ -65,7 +65,7 @@ def repositories(self, organization=''): filter="repositories", datatype=Repository) def public_repositories(self, organization): - """Get list of public repositories in an organization + """Get list of public repositories in an organization. :param str organization: organization to list public repositories for @@ -74,7 +74,7 @@ def public_repositories(self, organization): filter="repositories", datatype=Repository) def public_members(self, organization): - """Get list of public members in an organization + """Get list of public members in an organization. :param str organization: organization to list members for @@ -83,7 +83,7 @@ def public_members(self, organization): datatype=User) def teams(self, organization): - """Get list of teams in an organization + """Get list of teams in an organization. :param str organization: organization to list teams for @@ -93,7 +93,7 @@ def teams(self, organization): @requires_auth def add_team(self, organization, name, permission='pull', projects=None): - """Add a team to an organization + """Add a team to an organization. :param str organization: organization to add team to :param str team: name of team to add diff --git a/github2/pull_requests.py b/github2/pull_requests.py index 9a0ba58..bc82814 100644 --- a/github2/pull_requests.py +++ b/github2/pull_requests.py @@ -3,7 +3,7 @@ class PullRequest(BaseData): - """Pull request encapsulation + """Pull request encapsulation. .. versionadded:: 0.5.0 @@ -42,7 +42,7 @@ def __repr__(self): class PullRequests(GithubCommand): - """Operations on pull requests + """Operations on pull requests. .. versionadded:: 0.5.0 @@ -51,7 +51,7 @@ class PullRequests(GithubCommand): domain = "pulls" def create(self, project, base, head, title=None, body=None, issue=None): - """Create a new pull request + """Create a new pull request. Pull requests can be created from scratch, or attached to an existing issue. If an ``issue`` parameter is supplied the pull request is @@ -81,7 +81,7 @@ def create(self, project, base, head, title=None, body=None, issue=None): filter="pull", datatype=PullRequest) def show(self, project, number): - """Show a single pull request + """Show a single pull request. :param str project: Github project :param int number: pull request number in the Github database @@ -91,7 +91,7 @@ def show(self, project, number): datatype=PullRequest) def list(self, project, state="open", page=1): - """List all pull requests for a project + """List all pull requests for a project. :param str project: GitHub project :param str state: can be either ``open`` or ``closed`` diff --git a/github2/repositories.py b/github2/repositories.py index 4f9b0cf..8a2b82e 100644 --- a/github2/repositories.py +++ b/github2/repositories.py @@ -86,7 +86,7 @@ def list(self, user=None, page=1): @requires_auth def watch(self, project): - """Watch a project + """Watch a project. :param str project: GitHub project @@ -96,7 +96,7 @@ def watch(self, project): @requires_auth def unwatch(self, project): - """Unwatch a project + """Unwatch a project. :param str project: GitHub project @@ -106,7 +106,7 @@ def unwatch(self, project): @requires_auth def fork(self, project): - """Fork a project + """Fork a project. :param str project: GitHub project @@ -116,7 +116,7 @@ def fork(self, project): @requires_auth def create(self, project, description=None, homepage=None, public=True): - """Create a repository + """Create a repository. :param str project: new project name :param str description: optional project description @@ -131,7 +131,7 @@ def create(self, project, description=None, homepage=None, public=True): @requires_auth def delete(self, project): - """Delete a repository + """Delete a repository. :param str project: project name to delete @@ -143,7 +143,7 @@ def delete(self, project): @requires_auth def set_private(self, project): - """Mark repository as private + """Mark repository as private. :param str project: project name to set as private @@ -152,7 +152,7 @@ def set_private(self, project): @requires_auth def set_public(self, project): - """Mark repository as public + """Mark repository as public. :param str project: project name to set as public @@ -160,7 +160,7 @@ def set_public(self, project): return self.make_request("set/public", project) def list_collaborators(self, project): - """Lists all the collaborators in a project + """Lists all the collaborators in a project. :param str project: GitHub project @@ -170,7 +170,7 @@ def list_collaborators(self, project): @requires_auth def add_collaborator(self, project, username): - """Adds an add_collaborator to a repo + """Adds an add_collaborator to a repo. :param str project: Github project :param str username: Github user to add as collaborator @@ -181,7 +181,7 @@ def add_collaborator(self, project, username): @requires_auth def remove_collaborator(self, project, username): - """Removes an add_collaborator from a repo + """Removes an add_collaborator from a repo. :param str project: Github project :param str username: Github user to add as collaborator @@ -191,7 +191,7 @@ def remove_collaborator(self, project, username): username, method="POST") def network(self, project): - """Get network data for project + """Get network data for project. :param str project: Github project @@ -200,7 +200,7 @@ def network(self, project): datatype=Repository) def languages(self, project): - """Get programming language data for project + """Get programming language data for project. :param str project: Github project @@ -209,7 +209,7 @@ def languages(self, project): filter="languages") def tags(self, project): - """Get tags for project + """Get tags for project. :param str project: Github project @@ -217,7 +217,7 @@ def tags(self, project): return self.get_values("show", project, "tags", filter="tags") def branches(self, project): - """Get branch names for project + """Get branch names for project. :param str project: Github project @@ -225,7 +225,7 @@ def branches(self, project): return self.get_values("show", project, "branches", filter="branches") def watchers(self, project): - """Get list of watchers for project + """Get list of watchers for project. :param str project: Github project @@ -233,7 +233,7 @@ def watchers(self, project): return self.get_values("show", project, "watchers", filter="watchers") def watching(self, for_user=None, page=None): - """Lists all the repos a user is watching + """Lists all the repos a user is watching. :param str for_user: optional GitHub user name to list repositories for :param int page: optional page number @@ -244,7 +244,7 @@ def watching(self, for_user=None, page=None): datatype=Repository, page=page) def list_contributors(self, project): - """Lists all the contributors in a project + """Lists all the contributors in a project. :param str project: Github project diff --git a/github2/request.py b/github2/request.py index 12a9363..8ccfe39 100644 --- a/github2/request.py +++ b/github2/request.py @@ -67,7 +67,7 @@ def charset_from_headers(headers): - """Parse charset from headers + """Parse charset from headers. :param httplib2.Response headers: Request headers :return: Defined encoding, or default to ASCII @@ -91,7 +91,7 @@ class HttpError(RuntimeError): """A HTTP error occured when making a request to the Github API.""" def __init__(self, message, content, code): - """Create a HttpError exception + """Create a HttpError exception. :param str message: Exception string :param str content: Full content of HTTP request diff --git a/github2/teams.py b/github2/teams.py index c2c7945..0feb720 100644 --- a/github2/teams.py +++ b/github2/teams.py @@ -22,7 +22,7 @@ class Teams(GithubCommand): domain = "teams" def show(self, team_id): - """Get information on team_id + """Get information on team_id. :param int team_id: team to get information for @@ -30,7 +30,7 @@ def show(self, team_id): return self.get_value(str(team_id), filter="team", datatype=Team) def members(self, team_id): - """Get list of all team members + """Get list of all team members. :param int team_id: team to get information for @@ -40,7 +40,7 @@ def members(self, team_id): @requires_auth def add_member(self, team_id, username): - """Add a new member to a team + """Add a new member to a team. :param int team_id: team to add new member to :param str username: GitHub username to add to team @@ -51,7 +51,7 @@ def add_member(self, team_id, username): datatype=User) def repositories(self, team_id): - """Get list of all team repositories + """Get list of all team repositories. :param int team_id: team to get information for @@ -61,7 +61,7 @@ def repositories(self, team_id): @requires_auth def add_project(self, team_id, project): - """Add a project to a team + """Add a project to a team. :param int team_id: team to add repository to :param str project: GitHub project @@ -75,7 +75,7 @@ def add_project(self, team_id, project): @requires_auth def remove_project(self, team_id, project): - """Remove a project to a team + """Remove a project to a team. :param int team_id: team to remove project from :param str project: GitHub project diff --git a/github2/users.py b/github2/users.py index 50b761e..65d7702 100644 --- a/github2/users.py +++ b/github2/users.py @@ -41,7 +41,7 @@ class User(BaseData): format="user") def is_authenticated(self): - """Test for user authentication + """Test for user authentication. :return bool: ``True`` if user is authenticated @@ -56,7 +56,7 @@ class Users(GithubCommand): domain = "user" def search(self, query): - """Search for users + """Search for users. .. warning: Returns at most 100 users @@ -68,7 +68,7 @@ def search(self, query): datatype=User) def search_by_email(self, query): - """Search for users by email address + """Search for users by email address. :param str query: email to search for @@ -77,7 +77,7 @@ def search_by_email(self, query): @enhanced_by_auth def show(self, username): - """Get information on GitHub user + """Get information on Github user. if ``username`` is ``None`` or an empty string information for the currently authenticated user is returned. @@ -87,7 +87,7 @@ def show(self, username): return self.get_value("show", username, filter="user", datatype=User) def followers(self, username): - """Get list of GitHub user's followers + """Get list of Github user's followers. :param str username: Github user name @@ -95,7 +95,7 @@ def followers(self, username): return self.get_values("show", username, "followers", filter="users") def following(self, username): - """Get list of users a GitHub user is following + """Get list of users a Github user is following. :param str username: Github user name @@ -104,7 +104,7 @@ def following(self, username): @requires_auth def follow(self, other_user): - """Follow a GitHub user + """Follow a Github user. :param str other_user: Github user name @@ -113,7 +113,7 @@ def follow(self, other_user): @requires_auth def unfollow(self, other_user): - """Unfollow a GitHub user + """Unfollow a Github user. :param str other_user: Github user name @@ -122,12 +122,12 @@ def unfollow(self, other_user): @requires_auth def list_keys(self): - """Get list of SSH keys for the authenticated user""" + """Get list of SSH keys for the authenticated user.""" return self.get_values('keys', filter='public_keys', datatype=Key) @requires_auth def add_key(self, key, title=''): - """Add a SSH key for the authenticated user + """Add a SSH key for the authenticated user. :param str key: SSH key identifier :param str title: Optional title for the SSH key @@ -140,7 +140,7 @@ def add_key(self, key, title=''): @requires_auth def remove_key(self, key_id): - """Remove a SSH key for the authenticated user + """Remove a SSH key for the authenticated user. :param int key_id: SSH key's GitHub identifier From 4902ffc5f29675e138e055f6beef8d28bd625430 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 15:30:24 +0100 Subject: [PATCH 087/110] [QA] Use imperative form as per PEP 257. --- github2/repositories.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/github2/repositories.py b/github2/repositories.py index 8a2b82e..c515955 100644 --- a/github2/repositories.py +++ b/github2/repositories.py @@ -160,7 +160,7 @@ def set_public(self, project): return self.make_request("set/public", project) def list_collaborators(self, project): - """Lists all the collaborators in a project. + """List all the collaborators in a project. :param str project: GitHub project @@ -170,7 +170,7 @@ def list_collaborators(self, project): @requires_auth def add_collaborator(self, project, username): - """Adds an add_collaborator to a repo. + """Add an add_collaborator to a repo. :param str project: Github project :param str username: Github user to add as collaborator @@ -181,7 +181,7 @@ def add_collaborator(self, project, username): @requires_auth def remove_collaborator(self, project, username): - """Removes an add_collaborator from a repo. + """Remove a collaborator from a repo. :param str project: Github project :param str username: Github user to add as collaborator @@ -233,7 +233,7 @@ def watchers(self, project): return self.get_values("show", project, "watchers", filter="watchers") def watching(self, for_user=None, page=None): - """Lists all the repos a user is watching. + """List all the repos a user is watching. :param str for_user: optional GitHub user name to list repositories for :param int page: optional page number @@ -244,7 +244,7 @@ def watching(self, for_user=None, page=None): datatype=Repository, page=page) def list_contributors(self, project): - """Lists all the contributors in a project. + """List all the contributors in a project. :param str project: Github project From e3ef6bc59d77adaaa358aa78d3c9b891852e1bb9 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 15:31:49 +0100 Subject: [PATCH 088/110] Added some more missing docstrings. --- github2/client.py | 5 +++-- github2/commits.py | 6 ++++++ github2/core.py | 14 +++++++++++--- github2/issues.py | 9 +++++++++ github2/organizations.py | 16 ++++++++++++++-- github2/pull_requests.py | 6 ++++-- github2/repositories.py | 5 +++++ github2/request.py | 11 +++++++---- github2/teams.py | 12 ++++++++++-- github2/users.py | 9 +++++++++ 10 files changed, 78 insertions(+), 15 deletions(-) diff --git a/github2/client.py b/github2/client.py index 0296be4..5cf8d7e 100644 --- a/github2/client.py +++ b/github2/client.py @@ -10,11 +10,12 @@ class Github(object): + """Interface to GitHub's API v2.""" + def __init__(self, username=None, api_token=None, requests_per_second=None, access_token=None, cache=None, proxy_host=None, proxy_port=8080, github_url=None): - """An interface to GitHub's API: - http://develop.github.com/ + """Setup GitHub API object. .. versionadded:: 0.2.0 The ``requests_per_second`` parameter diff --git a/github2/commits.py b/github2/commits.py index 2bfd152..a04892f 100644 --- a/github2/commits.py +++ b/github2/commits.py @@ -3,6 +3,9 @@ class Commit(BaseData): + + """Commit container.""" + message = Attribute("Commit message.") parents = Attribute("List of parents for this commit.") url = Attribute("Canonical URL for this commit.") @@ -25,6 +28,9 @@ def __repr__(self): class Commits(GithubCommand): + + """GitHub API commits functionality.""" + domain = "commits" def list(self, project, branch="master", file=None, page=1): diff --git a/github2/core.py b/github2/core.py index 9329e5e..807aa93 100644 --- a/github2/core.py +++ b/github2/core.py @@ -143,8 +143,10 @@ def enhanced_by_auth(f): class GithubCommand(object): + """Main API binding interface.""" + def __init__(self, request): - """Main API binding interface. + """Setup command object. :param github2.request.GithubRequest request: HTTP request handler @@ -244,8 +246,11 @@ def bullet(title, text): class Attribute(object): + + """Generic object attribute for use with :class:`BaseData`.""" + def __init__(self, help): - """Generic object attribute for use with :class:`BaseData`. + """Setup Attribute object. :param str help: Attribute description @@ -259,6 +264,9 @@ def to_python(self, value): class DateAttribute(Attribute): + + """Date handling attribute for use with :class:`BaseData`.""" + format = "github" converter_for_format = { "github": datetime_to_ghdate, @@ -268,7 +276,7 @@ class DateAttribute(Attribute): } def __init__(self, *args, **kwargs): - """Date handling attribute for use with :class:`BaseData`. + """Setup DateAttribute object. :param str format: The date format to support, see :data:`convertor_for_format` for supported options diff --git a/github2/issues.py b/github2/issues.py index 0f72908..89dcf17 100644 --- a/github2/issues.py +++ b/github2/issues.py @@ -8,6 +8,9 @@ class Issue(BaseData): + + """Issue container.""" + position = Attribute("The position of this issue in a list.") number = Attribute("The issue number (unique for project).") votes = Attribute("Number of votes for this issue.") @@ -28,6 +31,9 @@ def __repr__(self): class Comment(BaseData): + + """Comment container.""" + created_at = DateAttribute("The date this comment was created.") updated_at = DateAttribute("The date when this comment was last updated.") body = Attribute("The full text of this comment.") @@ -39,6 +45,9 @@ def __repr__(self): class Issues(GithubCommand): + + """GitHub API issues functionality.""" + domain = "issues" def search(self, project, term, state="open"): diff --git a/github2/organizations.py b/github2/organizations.py index 263990b..3ac66c1 100644 --- a/github2/organizations.py +++ b/github2/organizations.py @@ -6,7 +6,13 @@ class Organization(BaseData): - """.. versionadded:: 0.4.0""" + + """Organization container. + + .. versionadded:: 0.4.0 + + """ + id = Attribute("The organization id.") name = Attribute("The full name of the organization.") blog = Attribute("The organization's blog.") @@ -35,7 +41,13 @@ def __repr__(self): class Organizations(GithubCommand): - """.. versionadded:: 0.4.0""" + + """GitHub API organizations functionality. + + .. versionadded:: 0.4.0 + + """ + domain = "organizations" def show(self, organization): diff --git a/github2/pull_requests.py b/github2/pull_requests.py index bc82814..b168b66 100644 --- a/github2/pull_requests.py +++ b/github2/pull_requests.py @@ -3,7 +3,8 @@ class PullRequest(BaseData): - """Pull request encapsulation. + + """Pull request container. .. versionadded:: 0.5.0 @@ -42,7 +43,8 @@ def __repr__(self): class PullRequests(GithubCommand): - """Operations on pull requests. + + """GitHub API pull request functionality. .. versionadded:: 0.5.0 diff --git a/github2/repositories.py b/github2/repositories.py index c515955..10f07a0 100644 --- a/github2/repositories.py +++ b/github2/repositories.py @@ -5,6 +5,9 @@ class Repository(BaseData): + + """Repository container.""" + name = Attribute("Name of repository.") description = Attribute("Repository description.") forks = Attribute("Number of forks of this repository.") @@ -35,6 +38,8 @@ def __repr__(self): class Repositories(GithubCommand): + """GitHub API repository functionality.""" + domain = "repos" def search(self, query): diff --git a/github2/request.py b/github2/request.py index 8ccfe39..6dcb371 100644 --- a/github2/request.py +++ b/github2/request.py @@ -111,6 +111,13 @@ def __init__(self, message, content, code): class GithubRequest(object): + + """Make an API request. + + :see: :class:`github2.client.Github` + + """ + url_format = "%(github_url)s/api/%(api_version)s/%(api_format)s" api_version = "v2" api_format = "json" @@ -120,10 +127,6 @@ def __init__(self, username=None, api_token=None, url_prefix=None, requests_per_second=None, access_token=None, cache=None, proxy_host=None, proxy_port=None, github_url=None): - """Make an API request. - - :see: :class:`github2.client.Github` - """ self.username = username self.api_token = api_token self.access_token = access_token diff --git a/github2/teams.py b/github2/teams.py index 0feb720..7c44e86 100644 --- a/github2/teams.py +++ b/github2/teams.py @@ -5,7 +5,11 @@ class Team(BaseData): - """.. versionadded:: 0.4.0""" + """Team container. + + .. versionadded:: 0.4.0 + + """ id = Attribute("The team id") name = Attribute("Name of the team") @@ -17,7 +21,11 @@ def __repr__(self): class Teams(GithubCommand): - """.. versionadded:: 0.4.0""" + """GitHub API teams functionality. + + .. versionadded:: 0.4.0 + + """ domain = "teams" diff --git a/github2/users.py b/github2/users.py index 65d7702..4ea8c2d 100644 --- a/github2/users.py +++ b/github2/users.py @@ -8,6 +8,9 @@ class Key(BaseData): + + """SSH key container.""" + id = Attribute('The key id') key = Attribute('The SSH key data') title = Attribute('The title for the SSH key') @@ -17,6 +20,9 @@ def __repr__(self): class User(BaseData): + + """GitHub user container.""" + id = Attribute("The user id") login = Attribute("The login username") name = Attribute("The users full name") @@ -53,6 +59,9 @@ def __repr__(self): class Users(GithubCommand): + + """GitHub API user functionality.""" + domain = "user" def search(self, query): From 031018edaccd4dcee233f2dcebf7fb6d7e5261ad Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 15:32:46 +0100 Subject: [PATCH 089/110] Use class docstring with autodoc. --- doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index ea950db..d74babe 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -229,7 +229,7 @@ [u'Ask Solem'], 1) ] -autoclass_content = "init" +autoclass_content = "class" autodoc_default_flags = ['members', ] intersphinx_mapping = { From 862d52238f34d614aca939b8d042b8eddd65f321 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 20:39:28 +0100 Subject: [PATCH 090/110] Added pip requirements files. --- extra/requirements-doc.txt | 4 ++++ extra/requirements-py25.txt | 2 ++ extra/requirements-py3.txt | 2 ++ extra/requirements-test.txt | 3 +++ extra/requirements.txt | 2 ++ 5 files changed, 13 insertions(+) create mode 100644 extra/requirements-doc.txt create mode 100644 extra/requirements-py25.txt create mode 100644 extra/requirements-py3.txt create mode 100644 extra/requirements-test.txt create mode 100644 extra/requirements.txt diff --git a/extra/requirements-doc.txt b/extra/requirements-doc.txt new file mode 100644 index 0000000..709ee46 --- /dev/null +++ b/extra/requirements-doc.txt @@ -0,0 +1,4 @@ +-r requirements.txt +cloud_sptheme>=1.2 +sphinx>=1.1 +sphinxcontrib-cheeseshop diff --git a/extra/requirements-py25.txt b/extra/requirements-py25.txt new file mode 100644 index 0000000..33f97ee --- /dev/null +++ b/extra/requirements-py25.txt @@ -0,0 +1,2 @@ +-r requirements.txt +simplejson>=2.0.9 diff --git a/extra/requirements-py3.txt b/extra/requirements-py3.txt new file mode 100644 index 0000000..457b3fb --- /dev/null +++ b/extra/requirements-py3.txt @@ -0,0 +1,2 @@ +httplib2>=0.7.0 +python-dateutil>=2.0 diff --git a/extra/requirements-test.txt b/extra/requirements-test.txt new file mode 100644 index 0000000..c8d6b88 --- /dev/null +++ b/extra/requirements-test.txt @@ -0,0 +1,3 @@ +-r requirements.txt +coverage>=3.5 +nose>=1.1.2 diff --git a/extra/requirements.txt b/extra/requirements.txt new file mode 100644 index 0000000..57c76c4 --- /dev/null +++ b/extra/requirements.txt @@ -0,0 +1,2 @@ +httplib2>=0.7.0 +python-dateutil<2.0 From 3f60faf6f6969b23206b9ee19a46986d1fbd823b Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 19:34:48 +0100 Subject: [PATCH 091/110] Use nose.tools.eq_ instead of assert_equals. --- tests/test_charset_header.py | 6 +- tests/test_commits.py | 62 +++---- tests/test_date_handling.py | 258 ++++++++++++-------------- tests/test_issues.py | 72 ++++---- tests/test_organizations.py | 52 +++--- tests/test_pull_requests.py | 69 ++++--- tests/test_regression.py | 8 +- tests/test_repositories.py | 103 +++++------ tests/test_teams.py | 4 +- tests/test_tz_aware_date_handling.py | 266 +++++++++++++-------------- tests/test_unit.py | 30 +-- tests/test_user.py | 59 +++--- 12 files changed, 473 insertions(+), 516 deletions(-) diff --git a/tests/test_charset_header.py b/tests/test_charset_header.py index 3b29635..2786673 100644 --- a/tests/test_charset_header.py +++ b/tests/test_charset_header.py @@ -3,16 +3,16 @@ # This file is part of python-github2, and is made available under the 3-clause # BSD license. See LICENSE for the full details. -from nose.tools import assert_equals +from nose.tools import eq_ from github2.request import charset_from_headers def no_match_test(): d = {} - assert_equals("ascii", charset_from_headers(d)) + eq_("ascii", charset_from_headers(d)) def utf_test(): d = {'content-type': 'application/json; charset=utf-8'} - assert_equals("utf-8", charset_from_headers(d)) + eq_("utf-8", charset_from_headers(d)) diff --git a/tests/test_commits.py b/tests/test_commits.py index 20ed487..33f037c 100644 --- a/tests/test_commits.py +++ b/tests/test_commits.py @@ -5,7 +5,7 @@ from datetime import datetime -from nose.tools import assert_equals +from nose.tools import eq_ import utils @@ -16,28 +16,25 @@ class CommitProperties(utils.HttpMockTestCase): def test_commit(self): commit = self.client.commits.show('ask/python-github2', self.commit_id) - assert_equals(commit.message, - 'Added cache support to manage_collaborators.') - assert_equals(commit.parents, - [{"id": '7d1c855d2f44a55e4b90b40017be697cf70cb4a0'}]) - assert_equals(commit.url, - '/ask/python-github2/commit/%s' % self.commit_id) - assert_equals(commit.author['login'], 'JNRowe') - assert_equals(commit.id, self.commit_id) - assert_equals(commit.committed_date, - datetime(2011, 6, 6, 16, 13, 50)) - assert_equals(commit.authored_date, datetime(2011, 6, 6, 16, 13, 50)) - assert_equals(commit.tree, 'f48fcc1a0b8ea97f3147dc42cf7cdb6683493e94') - assert_equals(commit.committer['login'], 'JNRowe') - assert_equals(commit.added, None) - assert_equals(commit.removed, None) - assert_equals(commit.modified[0]['filename'], - 'github2/bin/manage_collaborators.py') + eq_(commit.message, 'Added cache support to manage_collaborators.') + eq_(commit.parents, + [{"id": '7d1c855d2f44a55e4b90b40017be697cf70cb4a0'}]) + eq_(commit.url, '/ask/python-github2/commit/%s' % self.commit_id) + eq_(commit.author['login'], 'JNRowe') + eq_(commit.id, self.commit_id) + eq_(commit.committed_date, datetime(2011, 6, 6, 16, 13, 50)) + eq_(commit.authored_date, datetime(2011, 6, 6, 16, 13, 50)) + eq_(commit.tree, 'f48fcc1a0b8ea97f3147dc42cf7cdb6683493e94') + eq_(commit.committer['login'], 'JNRowe') + eq_(commit.added, None) + eq_(commit.removed, None) + eq_(commit.modified[0]['filename'], + 'github2/bin/manage_collaborators.py') def test_repr(self): commit = self.client.commits.show('ask/python-github2', self.commit_id) - assert_equals(repr(commit), - '' % self.commit_id[:8]) + eq_(repr(commit), + '' % self.commit_id[:8]) class CommitsQueries(utils.HttpMockTestCase): @@ -45,32 +42,27 @@ class CommitsQueries(utils.HttpMockTestCase): def test_list(self): commits = self.client.commits.list('JNRowe/misc-overlay') - assert_equals(len(commits), 35) - assert_equals(commits[0].id, - '4de0834d58b37ef3020c49df43c95649217a2def') + eq_(len(commits), 35) + eq_(commits[0].id, '4de0834d58b37ef3020c49df43c95649217a2def') def test_list_with_page(self): commits = self.client.commits.list('JNRowe/jnrowe-misc', page=2) - assert_equals(len(commits), 35) - assert_equals(commits[0].id, - '1f5ad2c3206bafc4aca9e6ce50f5c605befdb3d6') + eq_(len(commits), 35) + eq_(commits[0].id, '1f5ad2c3206bafc4aca9e6ce50f5c605befdb3d6') def test_list_with_branch(self): commits = self.client.commits.list('JNRowe/misc-overlay', 'gh-pages') - assert_equals(len(commits), 35) - assert_equals(commits[0].id, - '025148bdaa6fb6bdac9c3522d481fadf1c0a456f') + eq_(len(commits), 35) + eq_(commits[0].id, '025148bdaa6fb6bdac9c3522d481fadf1c0a456f') def test_list_with_file(self): commits = self.client.commits.list('JNRowe/misc-overlay', file='Makefile') - assert_equals(len(commits), 35) - assert_equals(commits[0].id, - 'fc12b924d34dc38c8ce76d27a866221faa88cb72') + eq_(len(commits), 35) + eq_(commits[0].id, 'fc12b924d34dc38c8ce76d27a866221faa88cb72') def test_list_with_branch_and_file(self): commits = self.client.commits.list('JNRowe/misc-overlay', 'gh-pages', 'packages/dev-python.html') - assert_equals(len(commits), 35) - assert_equals(commits[0].id, - '025148bdaa6fb6bdac9c3522d481fadf1c0a456f') + eq_(len(commits), 35) + eq_(commits[0].id, '025148bdaa6fb6bdac9c3522d481fadf1c0a456f') diff --git a/tests/test_date_handling.py b/tests/test_date_handling.py index 855ccae..b696a74 100644 --- a/tests/test_date_handling.py +++ b/tests/test_date_handling.py @@ -6,7 +6,7 @@ from datetime import datetime as dt -from nose.tools import assert_equals +from nose.tools import eq_ from github2.core import (datetime_to_ghdate, datetime_to_commitdate, datetime_to_isodate, string_to_datetime) @@ -16,154 +16,138 @@ # naïve datetime objects used in the current code base def test_ghdate_to_datetime(): - assert_equals(string_to_datetime('2011/05/22 00:24:15 -0700'), - dt(2011, 5, 22, 0, 24, 15)) - - assert_equals(string_to_datetime('2009/04/18 13:04:09 -0700'), - dt(2009, 4, 18, 13, 4, 9)) - #assert_equals(string_to_datetime('2009/11/12 21:15:17 -0800'), - # dt(2009, 11, 12, 21, 15, 17)) - #assert_equals(string_to_datetime('2009/11/12 21:16:20 -0800'), - # dt(2009, 11, 12, 21, 16, 20)) - assert_equals(string_to_datetime('2010/04/17 17:24:29 -0700'), - dt(2010, 4, 17, 17, 24, 29)) - assert_equals(string_to_datetime('2010/05/18 06:10:36 -0700'), - dt(2010, 5, 18, 6, 10, 36)) - assert_equals(string_to_datetime('2010/05/25 21:59:37 -0700'), - dt(2010, 5, 25, 21, 59, 37)) - assert_equals(string_to_datetime('2010/05/26 17:08:41 -0700'), - dt(2010, 5, 26, 17, 8, 41)) - assert_equals(string_to_datetime('2010/06/20 06:13:37 -0700'), - dt(2010, 6, 20, 6, 13, 37)) - assert_equals(string_to_datetime('2010/07/28 12:56:51 -0700'), - dt(2010, 7, 28, 12, 56, 51)) - assert_equals(string_to_datetime('2010/09/20 21:32:49 -0700'), - dt(2010, 9, 20, 21, 32, 49)) + eq_(string_to_datetime('2011/05/22 00:24:15 -0700'), + dt(2011, 5, 22, 0, 24, 15)) + + eq_(string_to_datetime('2009/04/18 13:04:09 -0700'), + dt(2009, 4, 18, 13, 4, 9)) + #eq_(string_to_datetime('2009/11/12 21:15:17 -0800'), + # dt(2009, 11, 12, 21, 15, 17)) + #eq_(string_to_datetime('2009/11/12 21:16:20 -0800'), + # dt(2009, 11, 12, 21, 16, 20)) + eq_(string_to_datetime('2010/04/17 17:24:29 -0700'), + dt(2010, 4, 17, 17, 24, 29)) + eq_(string_to_datetime('2010/05/18 06:10:36 -0700'), + dt(2010, 5, 18, 6, 10, 36)) + eq_(string_to_datetime('2010/05/25 21:59:37 -0700'), + dt(2010, 5, 25, 21, 59, 37)) + eq_(string_to_datetime('2010/05/26 17:08:41 -0700'), + dt(2010, 5, 26, 17, 8, 41)) + eq_(string_to_datetime('2010/06/20 06:13:37 -0700'), + dt(2010, 6, 20, 6, 13, 37)) + eq_(string_to_datetime('2010/07/28 12:56:51 -0700'), + dt(2010, 7, 28, 12, 56, 51)) + eq_(string_to_datetime('2010/09/20 21:32:49 -0700'), + dt(2010, 9, 20, 21, 32, 49)) def test_datetime_to_ghdate(): - assert_equals(datetime_to_ghdate(dt(2011, 5, 22, 0, 24, 15)), - '2011/05/22 00:24:15 -0700') - - assert_equals(datetime_to_ghdate(dt(2009, 4, 18, 20, 4, 9)), - '2009/04/18 20:04:09 -0700') - #assert_equals(datetime_to_ghdate(dt(2009, 11, 13, 4, 15, 17)), - # '2009/11/13 04:15:17 -0800') - #assert_equals(datetime_to_ghdate(dt(2009, 11, 13, 4, 16, 20)), - # '2009/11/13 04:16:20 -0800') - assert_equals(datetime_to_ghdate(dt(2010, 4, 18, 0, 24, 29)), - '2010/04/18 00:24:29 -0700') - assert_equals(datetime_to_ghdate(dt(2010, 5, 18, 13, 10, 36)), - '2010/05/18 13:10:36 -0700') - assert_equals(datetime_to_ghdate(dt(2010, 5, 26, 5, 59, 37)), - '2010/05/26 05:59:37 -0700') - assert_equals(datetime_to_ghdate(dt(2010, 5, 27, 0, 8, 41)), - '2010/05/27 00:08:41 -0700') - assert_equals(datetime_to_ghdate(dt(2010, 6, 20, 13, 13, 37)), - '2010/06/20 13:13:37 -0700') - assert_equals(datetime_to_ghdate(dt(2010, 7, 28, 19, 56, 51)), - '2010/07/28 19:56:51 -0700') - assert_equals(datetime_to_ghdate(dt(2010, 9, 21, 4, 32, 49)), - '2010/09/21 04:32:49 -0700') + eq_(datetime_to_ghdate(dt(2011, 5, 22, 0, 24, 15)), + '2011/05/22 00:24:15 -0700') + + eq_(datetime_to_ghdate(dt(2009, 4, 18, 20, 4, 9)), + '2009/04/18 20:04:09 -0700') + #eq_(datetime_to_ghdate(dt(2009, 11, 13, 4, 15, 17)), + # '2009/11/13 04:15:17 -0800') + #eq_(datetime_to_ghdate(dt(2009, 11, 13, 4, 16, 20)), + # '2009/11/13 04:16:20 -0800') + eq_(datetime_to_ghdate(dt(2010, 4, 18, 0, 24, 29)), + '2010/04/18 00:24:29 -0700') + eq_(datetime_to_ghdate(dt(2010, 5, 18, 13, 10, 36)), + '2010/05/18 13:10:36 -0700') + eq_(datetime_to_ghdate(dt(2010, 5, 26, 5, 59, 37)), + '2010/05/26 05:59:37 -0700') + eq_(datetime_to_ghdate(dt(2010, 5, 27, 0, 8, 41)), + '2010/05/27 00:08:41 -0700') + eq_(datetime_to_ghdate(dt(2010, 6, 20, 13, 13, 37)), + '2010/06/20 13:13:37 -0700') + eq_(datetime_to_ghdate(dt(2010, 7, 28, 19, 56, 51)), + '2010/07/28 19:56:51 -0700') + eq_(datetime_to_ghdate(dt(2010, 9, 21, 4, 32, 49)), + '2010/09/21 04:32:49 -0700') def test_commitdate_to_datetime(): - assert_equals(string_to_datetime('2011-05-22T00:24:15-07:00'), - dt(2011, 5, 22, 0, 24, 15)) - - assert_equals(string_to_datetime('2011-04-09T10:07:30-07:00'), - dt(2011, 4, 9, 10, 7, 30)) - #assert_equals(string_to_datetime('2011-02-19T07:16:11-08:00'), - # dt(2011, 2, 19, 7, 16, 11)) - #assert_equals(string_to_datetime('2010-12-21T12:34:27-08:00'), - # dt(2010, 12, 21, 12, 34, 27)) - assert_equals(string_to_datetime('2011-04-09T10:20:05-07:00'), - dt(2011, 4, 9, 10, 20, 5)) - assert_equals(string_to_datetime('2011-04-09T10:05:58-07:00'), - dt(2011, 4, 9, 10, 5, 58)) - assert_equals(string_to_datetime('2011-04-09T09:53:00-07:00'), - dt(2011, 4, 9, 9, 53, 0)) - assert_equals(string_to_datetime('2011-04-09T10:00:21-07:00'), - dt(2011, 4, 9, 10, 0, 21)) - #assert_equals(string_to_datetime('2010-12-16T15:10:59-08:00'), - # dt(2010, 12, 16, 15, 10, 59)) - assert_equals(string_to_datetime('2011-04-09T09:53:00-07:00'), - dt(2011, 4, 9, 9, 53, 0)) - assert_equals(string_to_datetime('2011-04-09T09:53:00-07:00'), - dt(2011, 4, 9, 9, 53, 0)) + eq_(string_to_datetime('2011-05-22T00:24:15-07:00'), + dt(2011, 5, 22, 0, 24, 15)) + + eq_(string_to_datetime('2011-04-09T10:07:30-07:00'), + dt(2011, 4, 9, 10, 7, 30)) + #eq_(string_to_datetime('2011-02-19T07:16:11-08:00'), + # dt(2011, 2, 19, 7, 16, 11)) + #eq_(string_to_datetime('2010-12-21T12:34:27-08:00'), + # dt(2010, 12, 21, 12, 34, 27)) + eq_(string_to_datetime('2011-04-09T10:20:05-07:00'), + dt(2011, 4, 9, 10, 20, 5)) + eq_(string_to_datetime('2011-04-09T10:05:58-07:00'), + dt(2011, 4, 9, 10, 5, 58)) + eq_(string_to_datetime('2011-04-09T09:53:00-07:00'), + dt(2011, 4, 9, 9, 53, 0)) + eq_(string_to_datetime('2011-04-09T10:00:21-07:00'), + dt(2011, 4, 9, 10, 0, 21)) + #eq_(string_to_datetime('2010-12-16T15:10:59-08:00'), + # dt(2010, 12, 16, 15, 10, 59)) + eq_(string_to_datetime('2011-04-09T09:53:00-07:00'), + dt(2011, 4, 9, 9, 53, 0)) + eq_(string_to_datetime('2011-04-09T09:53:00-07:00'), + dt(2011, 4, 9, 9, 53, 0)) def test_datetime_to_commitdate(): - assert_equals(datetime_to_commitdate(dt(2011, 5, 22, 0, 24, 15)), - '2011-05-22T00:24:15-07:00') - - assert_equals(datetime_to_commitdate(dt(2011, 4, 9, 10, 7, 30)), - '2011-04-09T10:07:30-07:00') - #assert_equals(datetime_to_commitdate(dt(2011, 2, 19, 7, 16, 11)), - # '2011-02-19T07:16:11-08:00') - #assert_equals(datetime_to_commitdate(dt(2010, 12, 21, 12, 34, 27)), - # '2010-12-21T12:34:27-08:00') - assert_equals(datetime_to_commitdate(dt(2011, 4, 9, 10, 20, 5)), - '2011-04-09T10:20:05-07:00') - assert_equals(datetime_to_commitdate(dt(2011, 4, 9, 10, 5, 58)), - '2011-04-09T10:05:58-07:00') - assert_equals(datetime_to_commitdate(dt(2011, 4, 9, 9, 53, 0)), - '2011-04-09T09:53:00-07:00') - assert_equals(datetime_to_commitdate(dt(2011, 4, 9, 10, 0, 21)), - '2011-04-09T10:00:21-07:00') - #assert_equals(datetime_to_commitdate(dt(2010, 12, 16, 15, 10, 59)), - # '2010-12-16T15:10:59-08:00') - assert_equals(datetime_to_commitdate(dt(2011, 4, 9, 9, 53, 0)), - '2011-04-09T09:53:00-07:00') - assert_equals(datetime_to_commitdate(dt(2011, 4, 9, 9, 53, 0)), - '2011-04-09T09:53:00-07:00') + eq_(datetime_to_commitdate(dt(2011, 5, 22, 0, 24, 15)), + '2011-05-22T00:24:15-07:00') + + eq_(datetime_to_commitdate(dt(2011, 4, 9, 10, 7, 30)), + '2011-04-09T10:07:30-07:00') + #eq_(datetime_to_commitdate(dt(2011, 2, 19, 7, 16, 11)), + # '2011-02-19T07:16:11-08:00') + #eq_(datetime_to_commitdate(dt(2010, 12, 21, 12, 34, 27)), + # '2010-12-21T12:34:27-08:00') + eq_(datetime_to_commitdate(dt(2011, 4, 9, 10, 20, 5)), + '2011-04-09T10:20:05-07:00') + eq_(datetime_to_commitdate(dt(2011, 4, 9, 10, 5, 58)), + '2011-04-09T10:05:58-07:00') + eq_(datetime_to_commitdate(dt(2011, 4, 9, 9, 53, 0)), + '2011-04-09T09:53:00-07:00') + eq_(datetime_to_commitdate(dt(2011, 4, 9, 10, 0, 21)), + '2011-04-09T10:00:21-07:00') + #eq_(datetime_to_commitdate(dt(2010, 12, 16, 15, 10, 59)), + # '2010-12-16T15:10:59-08:00') + eq_(datetime_to_commitdate(dt(2011, 4, 9, 9, 53, 0)), + '2011-04-09T09:53:00-07:00') + eq_(datetime_to_commitdate(dt(2011, 4, 9, 9, 53, 0)), + '2011-04-09T09:53:00-07:00') def test_isodate_to_datetime(): - assert_equals(string_to_datetime('2011-05-22T00:24:15Z'), - dt(2011, 5, 22, 0, 24, 15)) - assert_equals(string_to_datetime('2011-04-09T10:07:30Z'), - dt(2011, 4, 9, 10, 7, 30)) - assert_equals(string_to_datetime('2011-02-19T07:16:11Z'), - dt(2011, 2, 19, 7, 16, 11)) - assert_equals(string_to_datetime('2010-12-21T12:34:27Z'), - dt(2010, 12, 21, 12, 34, 27)) - assert_equals(string_to_datetime('2011-04-09T10:20:05Z'), - dt(2011, 4, 9, 10, 20, 5)) - assert_equals(string_to_datetime('2011-04-09T10:05:58Z'), - dt(2011, 4, 9, 10, 5, 58)) - assert_equals(string_to_datetime('2011-04-09T09:53:00Z'), - dt(2011, 4, 9, 9, 53, 0)) - assert_equals(string_to_datetime('2011-04-09T10:00:21Z'), - dt(2011, 4, 9, 10, 0, 21)) - assert_equals(string_to_datetime('2010-12-16T15:10:59Z'), - dt(2010, 12, 16, 15, 10, 59)) - assert_equals(string_to_datetime('2011-04-09T09:53:00Z'), - dt(2011, 4, 9, 9, 53, 0)) - assert_equals(string_to_datetime('2011-04-09T09:53:00Z'), - dt(2011, 4, 9, 9, 53, 0)) + eq_(string_to_datetime('2011-05-22T00:24:15Z'), dt(2011, 5, 22, 0, 24, 15)) + eq_(string_to_datetime('2011-04-09T10:07:30Z'), dt(2011, 4, 9, 10, 7, 30)) + eq_(string_to_datetime('2011-02-19T07:16:11Z'), dt(2011, 2, 19, 7, 16, 11)) + eq_(string_to_datetime('2010-12-21T12:34:27Z'), + dt(2010, 12, 21, 12, 34, 27)) + eq_(string_to_datetime('2011-04-09T10:20:05Z'), dt(2011, 4, 9, 10, 20, 5)) + eq_(string_to_datetime('2011-04-09T10:05:58Z'), dt(2011, 4, 9, 10, 5, 58)) + eq_(string_to_datetime('2011-04-09T09:53:00Z'), dt(2011, 4, 9, 9, 53, 0)) + eq_(string_to_datetime('2011-04-09T10:00:21Z'), dt(2011, 4, 9, 10, 0, 21)) + eq_(string_to_datetime('2010-12-16T15:10:59Z'), + dt(2010, 12, 16, 15, 10, 59)) + eq_(string_to_datetime('2011-04-09T09:53:00Z'), dt(2011, 4, 9, 9, 53, 0)) + eq_(string_to_datetime('2011-04-09T09:53:00Z'), dt(2011, 4, 9, 9, 53, 0)) def test_datetime_to_isodate(): - assert_equals(datetime_to_isodate(dt(2011, 5, 22, 0, 24, 15)), - '2011-05-22T00:24:15Z') - assert_equals(datetime_to_isodate(dt(2011, 4, 9, 10, 7, 30)), - '2011-04-09T10:07:30Z') - assert_equals(datetime_to_isodate(dt(2011, 2, 19, 7, 16, 11)), - '2011-02-19T07:16:11Z') - assert_equals(datetime_to_isodate(dt(2010, 12, 21, 12, 34, 27)), - '2010-12-21T12:34:27Z') - assert_equals(datetime_to_isodate(dt(2011, 4, 9, 10, 20, 5)), - '2011-04-09T10:20:05Z') - assert_equals(datetime_to_isodate(dt(2011, 4, 9, 10, 5, 58)), - '2011-04-09T10:05:58Z') - assert_equals(datetime_to_isodate(dt(2011, 4, 9, 9, 53, 0)), - '2011-04-09T09:53:00Z') - assert_equals(datetime_to_isodate(dt(2011, 4, 9, 10, 0, 21)), - '2011-04-09T10:00:21Z') - assert_equals(datetime_to_isodate(dt(2010, 12, 16, 15, 10, 59)), - '2010-12-16T15:10:59Z') - assert_equals(datetime_to_isodate(dt(2011, 4, 9, 9, 53, 0)), - '2011-04-09T09:53:00Z') - assert_equals(datetime_to_isodate(dt(2011, 4, 9, 9, 53, 0)), - '2011-04-09T09:53:00Z') + eq_(datetime_to_isodate(dt(2011, 5, 22, 0, 24, 15)), + '2011-05-22T00:24:15Z') + eq_(datetime_to_isodate(dt(2011, 4, 9, 10, 7, 30)), '2011-04-09T10:07:30Z') + eq_(datetime_to_isodate(dt(2011, 2, 19, 7, 16, 11)), + '2011-02-19T07:16:11Z') + eq_(datetime_to_isodate(dt(2010, 12, 21, 12, 34, 27)), + '2010-12-21T12:34:27Z') + eq_(datetime_to_isodate(dt(2011, 4, 9, 10, 20, 5)), '2011-04-09T10:20:05Z') + eq_(datetime_to_isodate(dt(2011, 4, 9, 10, 5, 58)), '2011-04-09T10:05:58Z') + eq_(datetime_to_isodate(dt(2011, 4, 9, 9, 53, 0)), '2011-04-09T09:53:00Z') + eq_(datetime_to_isodate(dt(2011, 4, 9, 10, 0, 21)), '2011-04-09T10:00:21Z') + eq_(datetime_to_isodate(dt(2010, 12, 16, 15, 10, 59)), + '2010-12-16T15:10:59Z') + eq_(datetime_to_isodate(dt(2011, 4, 9, 9, 53, 0)), '2011-04-09T09:53:00Z') + eq_(datetime_to_isodate(dt(2011, 4, 9, 9, 53, 0)), '2011-04-09T09:53:00Z') diff --git a/tests/test_issues.py b/tests/test_issues.py index f82302b..2abf495 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -5,7 +5,7 @@ from datetime import datetime -from nose.tools import assert_equals +from nose.tools import eq_ import utils @@ -13,44 +13,42 @@ class Issue(utils.HttpMockTestCase): def test_properties(self): issue = self.client.issues.show('ask/python-github2', 24) - assert_equals(issue.position, 24.0) - assert_equals(issue.number, 24) - assert_equals(issue.votes, 0) - assert_equals(len(issue.body), 164) - assert_equals(issue.title, 'Pagination support for commits.') - assert_equals(issue.user, 'svetlyak40wt') - assert_equals(issue.state, 'open') - assert_equals(issue.labels, []) - assert_equals(issue.created_at, datetime(2010, 12, 8, 23, 50, 26)) - assert_equals(issue.closed_at, None) - assert_equals(issue.updated_at, datetime(2011, 1, 4, 16, 26, 7)) - assert_equals(issue.diff_url, - 'https://github.com/ask/python-github2/pull/24.diff') - assert_equals(issue.patch_url, - 'https://github.com/ask/python-github2/pull/24.patch') - assert_equals(issue.pull_request_url, - 'https://github.com/ask/python-github2/pull/24') + eq_(issue.position, 24.0) + eq_(issue.number, 24) + eq_(issue.votes, 0) + eq_(len(issue.body), 164) + eq_(issue.title, 'Pagination support for commits.') + eq_(issue.user, 'svetlyak40wt') + eq_(issue.state, 'open') + eq_(issue.labels, []) + eq_(issue.created_at, datetime(2010, 12, 8, 23, 50, 26)) + eq_(issue.closed_at, None) + eq_(issue.updated_at, datetime(2011, 1, 4, 16, 26, 7)) + eq_(issue.diff_url, + 'https://github.com/ask/python-github2/pull/24.diff') + eq_(issue.patch_url, + 'https://github.com/ask/python-github2/pull/24.patch') + eq_(issue.pull_request_url, + 'https://github.com/ask/python-github2/pull/24') def test_issue_repr(self): issue = self.client.issues.show('ask/python-github2', 24) - assert_equals(repr(issue), - '') + eq_(repr(issue), '') class Comment(utils.HttpMockTestCase): def test_properties(self): comments = self.client.issues.comments('ask/python-github2', 24) comment = comments[0] - assert_equals(comment.created_at, datetime(2010, 12, 9, 22, 37, 26)) - assert_equals(comment.updated_at, datetime(2010, 12, 9, 22, 37, 26)) - assert_equals(len(comment.body), 267) - assert_equals(comment.id, 601871) - assert_equals(comment.user, 'nvie') + eq_(comment.created_at, datetime(2010, 12, 9, 22, 37, 26)) + eq_(comment.updated_at, datetime(2010, 12, 9, 22, 37, 26)) + eq_(len(comment.body), 267) + eq_(comment.id, 601871) + eq_(comment.user, 'nvie') def test_comment_repr(self): comments = self.client.issues.comments('ask/python-github2', 24) - assert_equals(repr(comments[1]), - '') + eq_(repr(comments[1]), '') class IssueQueries(utils.HttpMockTestCase): @@ -58,25 +56,25 @@ class IssueQueries(utils.HttpMockTestCase): def test_search(self): issues = self.client.issues.search('ask/python-github2', 'timezone', 'closed') - assert_equals(len(issues), 2) - assert_equals(issues[1].number, 39) + eq_(len(issues), 2) + eq_(issues[1].number, 39) def test_list(self): issues = self.client.issues.list('ask/python-github2') - assert_equals(len(issues), 4) - assert_equals(issues[-1].number, 58) + eq_(len(issues), 4) + eq_(issues[-1].number, 58) def test_list_with_state(self): issues = self.client.issues.list('ask/python-github2', "closed") - assert_equals(len(issues), 55) - assert_equals(issues[0].number, 59) + eq_(len(issues), 55) + eq_(issues[0].number, 59) def test_issue_labels(self): labels = self.client.issues.list_labels('JNRowe/misc-overlay') - assert_equals(len(labels), 4) - assert_equals(labels[0], 'feature') + eq_(len(labels), 4) + eq_(labels[0], 'feature') def test_list_by_label(self): issues = self.client.issues.list_by_label('JNRowe/misc-overlay', 'bug') - assert_equals(len(issues), 30) - assert_equals(issues[-1].number, 328) + eq_(len(issues), 30) + eq_(issues[-1].number, 328) diff --git a/tests/test_organizations.py b/tests/test_organizations.py index 8571e23..399d450 100644 --- a/tests/test_organizations.py +++ b/tests/test_organizations.py @@ -5,7 +5,7 @@ from datetime import datetime -from nose.tools import (assert_equals, assert_true) +from nose.tools import (eq_, assert_true) import utils @@ -13,23 +13,21 @@ class OrganizationProperties(utils.HttpMockTestCase): def test_properties(self): organization = self.client.organizations.show('github') - assert_equals(organization.id, 9919) - assert_equals(organization.name, 'GitHub') - assert_equals(organization.blog, 'https://github.com/about') - assert_equals(organization.location, 'San Francisco, CA') - assert_equals(organization.gravatar_id, - '61024896f291303615bcd4f7a0dcfb74') - assert_equals(organization.login, 'github') - assert_equals(organization.email, 'support@github.com') - assert_equals(organization.company, None) - assert_equals(organization.created_at, - datetime(2008, 5, 10, 21, 37, 31)) - assert_equals(organization.following_count, 0) - assert_equals(organization.followers_count, 591) - assert_equals(organization.public_gist_count, 0) - assert_equals(organization.public_repo_count, 31) - assert_equals(organization.permission, None) - assert_equals(organization.plan, None) + eq_(organization.id, 9919) + eq_(organization.name, 'GitHub') + eq_(organization.blog, 'https://github.com/about') + eq_(organization.location, 'San Francisco, CA') + eq_(organization.gravatar_id, '61024896f291303615bcd4f7a0dcfb74') + eq_(organization.login, 'github') + eq_(organization.email, 'support@github.com') + eq_(organization.company, None) + eq_(organization.created_at, datetime(2008, 5, 10, 21, 37, 31)) + eq_(organization.following_count, 0) + eq_(organization.followers_count, 591) + eq_(organization.public_gist_count, 0) + eq_(organization.public_repo_count, 31) + eq_(organization.permission, None) + eq_(organization.plan, None) def test_is_authenticated(self): organization = self.client.organizations.show('github') @@ -41,29 +39,28 @@ def test_is_authenticated(self): class Organization(utils.HttpMockTestCase): def test_repr(self): organization = self.client.organizations.show('github') - assert_equals(repr(organization), - '') + eq_(repr(organization), '') class OrganizationQueries(utils.HttpMockTestCase): """Test organisation querying""" def test_public_repositories(self): repos = self.client.organizations.public_repositories('github') - assert_equals(len(repos), 31) - assert_equals(repos[2].name, 'hubahuba') + eq_(len(repos), 31) + eq_(repos[2].name, 'hubahuba') def test_public_members(self): members = self.client.organizations.public_members('github') - assert_equals(len(members), 35) - assert_equals(members[2].name, 'Ben Burkert') + eq_(len(members), 35) + eq_(members[2].name, 'Ben Burkert') class OrganizationsEdits(utils.HttpMockAuthenticatedTestCase): def test_add_team(self): team = self.client.organizations.add_team('JNRowe-test-org', 'test_pull', 'pull') - assert_equals(team.name, 'team_pull') - assert_equals(team.permission, 'pull') + eq_(team.name, 'team_pull') + eq_(team.permission, 'pull') def test_add_team_with_repos(self): projects = ['JNRowe-test-org/test1', 'JNRowe-test-org/test2'] @@ -72,5 +69,4 @@ def test_add_team_with_repos(self): projects) team_repos = self.client.teams.repositories(team.id) - assert_equals(['/'.join([x.organization, x.name]) for x in team_repos], - projects) + eq_(['/'.join([x.organization, x.name]) for x in team_repos], projects) diff --git a/tests/test_pull_requests.py b/tests/test_pull_requests.py index 9c2d35e..efe486c 100644 --- a/tests/test_pull_requests.py +++ b/tests/test_pull_requests.py @@ -5,7 +5,7 @@ from datetime import datetime -from nose.tools import assert_equals +from nose.tools import eq_ import utils @@ -13,55 +13,48 @@ class PullRequest(utils.HttpMockTestCase): def test_properties(self): pull_request = self.client.pull_requests.show('ask/python-github2', 39) - assert_equals(pull_request.state, 'closed') - assert_equals(pull_request.base['sha'], + eq_(pull_request.state, 'closed') + eq_(pull_request.base['sha'], '0786a96c80afad7bbd0747df590f649eaa46ca04') - assert_equals(pull_request.head['sha'], + eq_(pull_request.head['sha'], '5438e41d9c390f53089ed3fa0842831fafc73d8e') - assert_equals(pull_request.issue_user['login'], 'JNRowe') - assert_equals(pull_request.user['login'], 'JNRowe') - assert_equals(pull_request.title, 'Datetime timezone handling.') - assert_equals(len(pull_request.body), 1442) - assert_equals(pull_request.position, 39.0) - assert_equals(pull_request.number, 39.0) - assert_equals(pull_request.votes, 0) - assert_equals(pull_request.comments, 4) - assert_equals(pull_request.diff_url, - 'https://github.com/ask/python-github2/pull/39.diff') - assert_equals(pull_request.patch_url, - 'https://github.com/ask/python-github2/pull/39.patch') - assert_equals(pull_request.labels, []) - assert_equals(pull_request.html_url, - 'https://github.com/ask/python-github2/pull/39') - assert_equals(pull_request.issue_created_at, - datetime(2011, 4, 18, 15, 25, 47)) - assert_equals(pull_request.issue_updated_at, - datetime(2011, 6, 23, 9, 33, 57)) - assert_equals(pull_request.created_at, - datetime(2011, 6, 20, 16, 51, 24)) - assert_equals(pull_request.updated_at, - datetime(2011, 6, 23, 9, 28, 42)) - assert_equals(pull_request.closed_at, - datetime(2011, 6, 23, 9, 33, 57)) - assert_equals(len(pull_request.discussion), 13) - assert_equals(pull_request.mergeable, True) + eq_(pull_request.issue_user['login'], 'JNRowe') + eq_(pull_request.user['login'], 'JNRowe') + eq_(pull_request.title, 'Datetime timezone handling.') + eq_(len(pull_request.body), 1442) + eq_(pull_request.position, 39.0) + eq_(pull_request.number, 39.0) + eq_(pull_request.votes, 0) + eq_(pull_request.comments, 4) + eq_(pull_request.diff_url, + 'https://github.com/ask/python-github2/pull/39.diff') + eq_(pull_request.patch_url, + 'https://github.com/ask/python-github2/pull/39.patch') + eq_(pull_request.labels, []) + eq_(pull_request.html_url, + 'https://github.com/ask/python-github2/pull/39') + eq_(pull_request.issue_created_at, datetime(2011, 4, 18, 15, 25, 47)) + eq_(pull_request.issue_updated_at, datetime(2011, 6, 23, 9, 33, 57)) + eq_(pull_request.created_at, datetime(2011, 6, 20, 16, 51, 24)) + eq_(pull_request.updated_at, datetime(2011, 6, 23, 9, 28, 42)) + eq_(pull_request.closed_at, datetime(2011, 6, 23, 9, 33, 57)) + eq_(len(pull_request.discussion), 13) + eq_(pull_request.mergeable, True) def test_repr(self): pull_request = self.client.pull_requests.show('ask/python-github2', 39) - assert_equals(repr(pull_request), - '') + eq_(repr(pull_request), '') class PullRequestQueries(utils.HttpMockTestCase): """Test pull request querying""" def test_list(self): pull_requests = self.client.pull_requests.list('ask/python-github2') - assert_equals(len(pull_requests), 1) - assert_equals(pull_requests[0].title, - 'Pagination support for commits.') + eq_(len(pull_requests), 1) + eq_(pull_requests[0].title, 'Pagination support for commits.') def test_list_with_page(self): pull_requests = self.client.pull_requests.list('robbyrussell/oh-my-zsh', page=2) - assert_equals(len(pull_requests), 52) - assert_equals(pull_requests[1].title, 'Added my own custom theme') + eq_(len(pull_requests), 52) + eq_(pull_requests[1].title, 'Added my own custom theme') diff --git a/tests/test_regression.py b/tests/test_regression.py index cad7dc2..d5ff091 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -5,7 +5,7 @@ import httplib2 -from nose.tools import assert_equals +from nose.tools import eq_ from github2.client import Github @@ -21,8 +21,8 @@ def test_issue_50(): client = Github(proxy_host="my.proxy.com", proxy_port=9000) setup_args = client.request._http.called_with - assert_equals(type(setup_args['proxy_info']), httplib2.ProxyInfo) - assert_equals(setup_args['proxy_info'].proxy_host, 'my.proxy.com') - assert_equals(setup_args['proxy_info'].proxy_port, 9000) + eq_(type(setup_args['proxy_info']), httplib2.ProxyInfo) + eq_(setup_args['proxy_info'].proxy_host, 'my.proxy.com') + eq_(setup_args['proxy_info'].proxy_port, 9000) utils.unset_http_mock() diff --git a/tests/test_repositories.py b/tests/test_repositories.py index 1cdaab9..39017df 100644 --- a/tests/test_repositories.py +++ b/tests/test_repositories.py @@ -7,7 +7,7 @@ import datetime -from nose.tools import assert_equals +from nose.tools import eq_ import utils @@ -15,7 +15,7 @@ class Repo(utils.HttpMockTestCase): def test_repr(self): repo = self.client.repos.show('JNRowe/misc-overlay') - assert_equals(repr(repo), '') + eq_(repr(repo), '') class RepoProperties(utils.HttpMockTestCase): @@ -23,103 +23,98 @@ class RepoProperties(utils.HttpMockTestCase): def test_repo(self): repo = self.client.repos.show('JNRowe/misc-overlay') - assert_equals(repo.name, 'misc-overlay') - assert_equals(repo.description, - 'Gentoo overlay -- miscellaneous packages') - assert_equals(repo.url, 'https://github.com/JNRowe/misc-overlay') - assert_equals(repo.owner, 'JNRowe') - assert_equals(repo.homepage, 'http://jnrowe.github.com/misc-overlay/') + eq_(repo.name, 'misc-overlay') + eq_(repo.description, 'Gentoo overlay -- miscellaneous packages') + eq_(repo.url, 'https://github.com/JNRowe/misc-overlay') + eq_(repo.owner, 'JNRowe') + eq_(repo.homepage, 'http://jnrowe.github.com/misc-overlay/') - assert_equals(repo.project, 'JNRowe/misc-overlay') + eq_(repo.project, 'JNRowe/misc-overlay') def test_meta(self): repo = self.client.repos.show('JNRowe/misc-overlay') - assert_equals(repo.forks, 0) - assert_equals(repo.watchers, 5) - assert_equals(repo.private, False) - assert_equals(repo.fork, False) - assert_equals(repo.master_branch, None) - assert_equals(repo.integration_branch, None) - assert_equals(repo.open_issues, 13) - assert_equals(repo.created_at, - datetime.datetime(2009, 5, 2, 7, 32, 50)) - assert_equals(repo.pushed_at, - datetime.datetime(2011, 8, 11, 11, 46, 23)) - assert_equals(repo.has_downloads, True) - assert_equals(repo.has_wiki, True) - assert_equals(repo.has_issues, True) - assert_equals(repo.language, 'Python') + eq_(repo.forks, 0) + eq_(repo.watchers, 5) + eq_(repo.private, False) + eq_(repo.fork, False) + eq_(repo.master_branch, None) + eq_(repo.integration_branch, None) + eq_(repo.open_issues, 13) + eq_(repo.created_at, datetime.datetime(2009, 5, 2, 7, 32, 50)) + eq_(repo.pushed_at, datetime.datetime(2011, 8, 11, 11, 46, 23)) + eq_(repo.has_downloads, True) + eq_(repo.has_wiki, True) + eq_(repo.has_issues, True) + eq_(repo.language, 'Python') def test_fork_properties(self): repo = self.client.repos.show('JNRowe/python-github2') - assert_equals(repo.forks, 0) - assert_equals(repo.fork, True) - assert_equals(repo.parent, 'ask/python-github2') - assert_equals(repo.source, 'ask/python-github2') + eq_(repo.forks, 0) + eq_(repo.fork, True) + eq_(repo.parent, 'ask/python-github2') + eq_(repo.source, 'ask/python-github2') class RepoQueries(utils.HttpMockTestCase): """Test repository querying""" def test_search(self): repos = self.client.repos.search('surfraw') - assert_equals(len(repos), 8) - assert_equals(repos[0].owner, 'JNRowe') + eq_(len(repos), 8) + eq_(repos[0].owner, 'JNRowe') def test_list(self): repos = self.client.repos.list('JNRowe') - assert_equals(len(repos), 48) - assert_equals(repos[0].name, 'bfm') + eq_(len(repos), 48) + eq_(repos[0].name, 'bfm') def test_list_with_page(self): repos = self.client.repos.list('tekkub', page=2) - assert_equals(len(repos), 37) - assert_equals(repos[0].name, 'OhSnap') + eq_(len(repos), 37) + eq_(repos[0].name, 'OhSnap') def test_watching(self): repos = self.client.repos.watching('JNRowe') - assert_equals(len(repos), 90) - assert_equals(repos[0].name, 'nerdtree') + eq_(len(repos), 90) + eq_(repos[0].name, 'nerdtree') def test_watching_with_page(self): repos = self.client.repos.watching('tekkub', page=2) - assert_equals(len(repos), 39) - assert_equals(repos[0].name, 'Buffoon') + eq_(len(repos), 39) + eq_(repos[0].name, 'Buffoon') def test_contributors(self): contributors = self.client.repos.list_contributors('ask/python-github2') - assert_equals(len(contributors), 29) - assert_equals(contributors[1].name, 'Ask Solem Hoel') + eq_(len(contributors), 29) + eq_(contributors[1].name, 'Ask Solem Hoel') def test_list_collaborators(self): collaborators = self.client.repos.list_collaborators('ask/python-github2') - assert_equals(len(collaborators), 4) - assert_equals(collaborators[2], 'JNRowe') + eq_(len(collaborators), 4) + eq_(collaborators[2], 'JNRowe') def test_languages(self): languages = self.client.repos.languages('JNRowe/misc-overlay') - assert_equals(len(languages), 2) - assert_equals(languages['Python'], 11194) + eq_(len(languages), 2) + eq_(languages['Python'], 11194) def test_tags(self): tags = self.client.repos.tags('ask/python-github2') - assert_equals(len(tags), 7) - assert_equals(tags['0.4.1'], - '96b0a41dd249c521323700bc11a0a721a7c9e642') + eq_(len(tags), 7) + eq_(tags['0.4.1'], '96b0a41dd249c521323700bc11a0a721a7c9e642') def test_branches(self): branches = self.client.repos.branches('ask/python-github2') - assert_equals(len(branches), 1) - assert_equals(branches['master'], - '1c83cde9b5a7c396a01af1007fb7b88765b9ae45') + eq_(len(branches), 1) + eq_(branches['master'], '1c83cde9b5a7c396a01af1007fb7b88765b9ae45') def test_watchers(self): watchers = self.client.repos.watchers('ask/python-github2') - assert_equals(len(watchers), 143) - assert_equals(watchers[0], 'ask') + eq_(len(watchers), 143) + eq_(watchers[0], 'ask') class AuthenticatedRepoQueries(utils.HttpMockAuthenticatedTestCase): def test_pushable(self): repos = self.client.repos.pushable() - assert_equals(len(repos), 1) - assert_equals(repos[0].name, 'python-github2') + eq_(len(repos), 1) + eq_(repos[0].name, 'python-github2') diff --git a/tests/test_teams.py b/tests/test_teams.py index 7333edd..cd18166 100644 --- a/tests/test_teams.py +++ b/tests/test_teams.py @@ -3,7 +3,7 @@ # This file is part of python-github2, and is made available under the 3-clause # BSD license. See LICENSE for the full details. -from nose.tools import assert_equals +from nose.tools import eq_ import utils @@ -11,4 +11,4 @@ class TeamEdits(utils.HttpMockAuthenticatedTestCase): def test_add_member(self): users = self.client.teams.add_member(121990, 'JNRowe') - assert_equals(users[0].login, 'JNRowe') + eq_(users[0].login, 'JNRowe') diff --git a/tests/test_tz_aware_date_handling.py b/tests/test_tz_aware_date_handling.py index 6a501f0..77302ba 100644 --- a/tests/test_tz_aware_date_handling.py +++ b/tests/test_tz_aware_date_handling.py @@ -7,7 +7,7 @@ from datetime import datetime as dt from dateutil.tz import tzutc -from nose.tools import assert_equals +from nose.tools import eq_ from github2 import core from github2.core import (datetime_to_ghdate, datetime_to_commitdate, @@ -33,150 +33,150 @@ def dt_utz(year, month, day, hour, minute, second): def test_ghdate_to_datetime(): - assert_equals(string_to_datetime('2011/05/22 00:24:15 -0700'), - dt_utz(2011, 5, 22, 7, 24, 15)) - assert_equals(string_to_datetime('2009/04/18 13:04:09 -0700'), - dt_utz(2009, 4, 18, 20, 4, 9)) - assert_equals(string_to_datetime('2009/11/12 21:15:17 -0800'), - dt_utz(2009, 11, 13, 5, 15, 17)) - assert_equals(string_to_datetime('2009/11/12 21:16:20 -0800'), - dt_utz(2009, 11, 13, 5, 16, 20)) - assert_equals(string_to_datetime('2010/04/17 17:24:29 -0700'), - dt_utz(2010, 4, 18, 0, 24, 29)) - assert_equals(string_to_datetime('2010/05/18 06:10:36 -0700'), - dt_utz(2010, 5, 18, 13, 10, 36)) - assert_equals(string_to_datetime('2010/05/25 21:59:37 -0700'), - dt_utz(2010, 5, 26, 4, 59, 37)) - assert_equals(string_to_datetime('2010/05/26 17:08:41 -0700'), - dt_utz(2010, 5, 27, 0, 8, 41)) - assert_equals(string_to_datetime('2010/06/20 06:13:37 -0700'), - dt_utz(2010, 6, 20, 13, 13, 37)) - assert_equals(string_to_datetime('2010/07/28 12:56:51 -0700'), - dt_utz(2010, 7, 28, 19, 56, 51)) - assert_equals(string_to_datetime('2010/09/20 21:32:49 -0700'), - dt_utz(2010, 9, 21, 4, 32, 49)) + eq_(string_to_datetime('2011/05/22 00:24:15 -0700'), + dt_utz(2011, 5, 22, 7, 24, 15)) + eq_(string_to_datetime('2009/04/18 13:04:09 -0700'), + dt_utz(2009, 4, 18, 20, 4, 9)) + eq_(string_to_datetime('2009/11/12 21:15:17 -0800'), + dt_utz(2009, 11, 13, 5, 15, 17)) + eq_(string_to_datetime('2009/11/12 21:16:20 -0800'), + dt_utz(2009, 11, 13, 5, 16, 20)) + eq_(string_to_datetime('2010/04/17 17:24:29 -0700'), + dt_utz(2010, 4, 18, 0, 24, 29)) + eq_(string_to_datetime('2010/05/18 06:10:36 -0700'), + dt_utz(2010, 5, 18, 13, 10, 36)) + eq_(string_to_datetime('2010/05/25 21:59:37 -0700'), + dt_utz(2010, 5, 26, 4, 59, 37)) + eq_(string_to_datetime('2010/05/26 17:08:41 -0700'), + dt_utz(2010, 5, 27, 0, 8, 41)) + eq_(string_to_datetime('2010/06/20 06:13:37 -0700'), + dt_utz(2010, 6, 20, 13, 13, 37)) + eq_(string_to_datetime('2010/07/28 12:56:51 -0700'), + dt_utz(2010, 7, 28, 19, 56, 51)) + eq_(string_to_datetime('2010/09/20 21:32:49 -0700'), + dt_utz(2010, 9, 21, 4, 32, 49)) def test_datetime_to_ghdate(): - assert_equals(datetime_to_ghdate(dt_utz(2011, 5, 22, 7, 24, 15)), - '2011/05/22 00:24:15 -0700') - assert_equals(datetime_to_ghdate(dt_utz(2009, 4, 18, 20, 4, 9)), - '2009/04/18 13:04:09 -0700') - assert_equals(datetime_to_ghdate(dt_utz(2009, 11, 13, 4, 15, 17)), - '2009/11/12 20:15:17 -0800') - assert_equals(datetime_to_ghdate(dt_utz(2009, 11, 13, 4, 16, 20)), - '2009/11/12 20:16:20 -0800') - assert_equals(datetime_to_ghdate(dt_utz(2010, 4, 18, 0, 24, 29)), - '2010/04/17 17:24:29 -0700') - assert_equals(datetime_to_ghdate(dt_utz(2010, 5, 18, 13, 10, 36)), - '2010/05/18 06:10:36 -0700') - assert_equals(datetime_to_ghdate(dt_utz(2010, 5, 26, 5, 59, 37)), - '2010/05/25 22:59:37 -0700') - assert_equals(datetime_to_ghdate(dt_utz(2010, 5, 27, 0, 8, 41)), - '2010/05/26 17:08:41 -0700') - assert_equals(datetime_to_ghdate(dt_utz(2010, 6, 20, 13, 13, 37)), - '2010/06/20 06:13:37 -0700') - assert_equals(datetime_to_ghdate(dt_utz(2010, 7, 28, 19, 56, 51)), - '2010/07/28 12:56:51 -0700') - assert_equals(datetime_to_ghdate(dt_utz(2010, 9, 21, 4, 32, 49)), - '2010/09/20 21:32:49 -0700') + eq_(datetime_to_ghdate(dt_utz(2011, 5, 22, 7, 24, 15)), + '2011/05/22 00:24:15 -0700') + eq_(datetime_to_ghdate(dt_utz(2009, 4, 18, 20, 4, 9)), + '2009/04/18 13:04:09 -0700') + eq_(datetime_to_ghdate(dt_utz(2009, 11, 13, 4, 15, 17)), + '2009/11/12 20:15:17 -0800') + eq_(datetime_to_ghdate(dt_utz(2009, 11, 13, 4, 16, 20)), + '2009/11/12 20:16:20 -0800') + eq_(datetime_to_ghdate(dt_utz(2010, 4, 18, 0, 24, 29)), + '2010/04/17 17:24:29 -0700') + eq_(datetime_to_ghdate(dt_utz(2010, 5, 18, 13, 10, 36)), + '2010/05/18 06:10:36 -0700') + eq_(datetime_to_ghdate(dt_utz(2010, 5, 26, 5, 59, 37)), + '2010/05/25 22:59:37 -0700') + eq_(datetime_to_ghdate(dt_utz(2010, 5, 27, 0, 8, 41)), + '2010/05/26 17:08:41 -0700') + eq_(datetime_to_ghdate(dt_utz(2010, 6, 20, 13, 13, 37)), + '2010/06/20 06:13:37 -0700') + eq_(datetime_to_ghdate(dt_utz(2010, 7, 28, 19, 56, 51)), + '2010/07/28 12:56:51 -0700') + eq_(datetime_to_ghdate(dt_utz(2010, 9, 21, 4, 32, 49)), + '2010/09/20 21:32:49 -0700') def test_commitdate_to_datetime(): - assert_equals(string_to_datetime('2011-05-22T00:24:15-07:00'), - dt_utz(2011, 5, 22, 7, 24, 15)) - assert_equals(string_to_datetime('2011-04-09T10:07:30-07:00'), - dt_utz(2011, 4, 9, 17, 7, 30)) - assert_equals(string_to_datetime('2011-02-19T07:16:11-08:00'), - dt_utz(2011, 2, 19, 15, 16, 11)) - assert_equals(string_to_datetime('2010-12-21T12:34:27-08:00'), - dt_utz(2010, 12, 21, 20, 34, 27)) - assert_equals(string_to_datetime('2011-04-09T10:20:05-07:00'), - dt_utz(2011, 4, 9, 17, 20, 5)) - assert_equals(string_to_datetime('2011-04-09T10:05:58-07:00'), - dt_utz(2011, 4, 9, 17, 5, 58)) - assert_equals(string_to_datetime('2011-04-09T09:53:00-07:00'), - dt_utz(2011, 4, 9, 16, 53, 0)) - assert_equals(string_to_datetime('2011-04-09T10:00:21-07:00'), - dt_utz(2011, 4, 9, 17, 0, 21)) - assert_equals(string_to_datetime('2010-12-16T15:10:59-08:00'), - dt_utz(2010, 12, 16, 23, 10, 59)) - assert_equals(string_to_datetime('2011-04-09T09:53:00-07:00'), - dt_utz(2011, 4, 9, 16, 53, 0)) - assert_equals(string_to_datetime('2011-04-09T09:53:00-07:00'), - dt_utz(2011, 4, 9, 16, 53, 0)) + eq_(string_to_datetime('2011-05-22T00:24:15-07:00'), + dt_utz(2011, 5, 22, 7, 24, 15)) + eq_(string_to_datetime('2011-04-09T10:07:30-07:00'), + dt_utz(2011, 4, 9, 17, 7, 30)) + eq_(string_to_datetime('2011-02-19T07:16:11-08:00'), + dt_utz(2011, 2, 19, 15, 16, 11)) + eq_(string_to_datetime('2010-12-21T12:34:27-08:00'), + dt_utz(2010, 12, 21, 20, 34, 27)) + eq_(string_to_datetime('2011-04-09T10:20:05-07:00'), + dt_utz(2011, 4, 9, 17, 20, 5)) + eq_(string_to_datetime('2011-04-09T10:05:58-07:00'), + dt_utz(2011, 4, 9, 17, 5, 58)) + eq_(string_to_datetime('2011-04-09T09:53:00-07:00'), + dt_utz(2011, 4, 9, 16, 53, 0)) + eq_(string_to_datetime('2011-04-09T10:00:21-07:00'), + dt_utz(2011, 4, 9, 17, 0, 21)) + eq_(string_to_datetime('2010-12-16T15:10:59-08:00'), + dt_utz(2010, 12, 16, 23, 10, 59)) + eq_(string_to_datetime('2011-04-09T09:53:00-07:00'), + dt_utz(2011, 4, 9, 16, 53, 0)) + eq_(string_to_datetime('2011-04-09T09:53:00-07:00'), + dt_utz(2011, 4, 9, 16, 53, 0)) def test_datetime_to_commitdate(): - assert_equals(datetime_to_commitdate(dt_utz(2011, 5, 22, 7, 24, 15)), - '2011-05-22T00:24:15-07:00') - assert_equals(datetime_to_commitdate(dt_utz(2011, 4, 9, 17, 7, 30)), - '2011-04-09T10:07:30-07:00') - assert_equals(datetime_to_commitdate(dt_utz(2011, 2, 19, 15, 16, 11)), - '2011-02-19T07:16:11-08:00') - assert_equals(datetime_to_commitdate(dt_utz(2010, 12, 21, 20, 34, 27)), - '2010-12-21T12:34:27-08:00') - assert_equals(datetime_to_commitdate(dt_utz(2011, 4, 9, 17, 20, 5)), - '2011-04-09T10:20:05-07:00') - assert_equals(datetime_to_commitdate(dt_utz(2011, 4, 9, 17, 5, 58)), - '2011-04-09T10:05:58-07:00') - assert_equals(datetime_to_commitdate(dt_utz(2011, 4, 9, 16, 53, 0)), - '2011-04-09T09:53:00-07:00') - assert_equals(datetime_to_commitdate(dt_utz(2011, 4, 9, 17, 0, 21)), - '2011-04-09T10:00:21-07:00') - assert_equals(datetime_to_commitdate(dt_utz(2010, 12, 16, 23, 10, 59)), - '2010-12-16T15:10:59-08:00') - assert_equals(datetime_to_commitdate(dt_utz(2011, 4, 9, 16, 53, 0)), - '2011-04-09T09:53:00-07:00') - assert_equals(datetime_to_commitdate(dt_utz(2011, 4, 9, 16, 53, 0)), - '2011-04-09T09:53:00-07:00') + eq_(datetime_to_commitdate(dt_utz(2011, 5, 22, 7, 24, 15)), + '2011-05-22T00:24:15-07:00') + eq_(datetime_to_commitdate(dt_utz(2011, 4, 9, 17, 7, 30)), + '2011-04-09T10:07:30-07:00') + eq_(datetime_to_commitdate(dt_utz(2011, 2, 19, 15, 16, 11)), + '2011-02-19T07:16:11-08:00') + eq_(datetime_to_commitdate(dt_utz(2010, 12, 21, 20, 34, 27)), + '2010-12-21T12:34:27-08:00') + eq_(datetime_to_commitdate(dt_utz(2011, 4, 9, 17, 20, 5)), + '2011-04-09T10:20:05-07:00') + eq_(datetime_to_commitdate(dt_utz(2011, 4, 9, 17, 5, 58)), + '2011-04-09T10:05:58-07:00') + eq_(datetime_to_commitdate(dt_utz(2011, 4, 9, 16, 53, 0)), + '2011-04-09T09:53:00-07:00') + eq_(datetime_to_commitdate(dt_utz(2011, 4, 9, 17, 0, 21)), + '2011-04-09T10:00:21-07:00') + eq_(datetime_to_commitdate(dt_utz(2010, 12, 16, 23, 10, 59)), + '2010-12-16T15:10:59-08:00') + eq_(datetime_to_commitdate(dt_utz(2011, 4, 9, 16, 53, 0)), + '2011-04-09T09:53:00-07:00') + eq_(datetime_to_commitdate(dt_utz(2011, 4, 9, 16, 53, 0)), + '2011-04-09T09:53:00-07:00') def test_isodate_to_datetime(): - assert_equals(string_to_datetime('2011-05-22T00:24:15Z'), - dt_utz(2011, 5, 22, 0, 24, 15)) - assert_equals(string_to_datetime('2011-04-09T10:07:30Z'), - dt_utz(2011, 4, 9, 10, 7, 30)) - assert_equals(string_to_datetime('2011-02-19T07:16:11Z'), - dt_utz(2011, 2, 19, 7, 16, 11)) - assert_equals(string_to_datetime('2010-12-21T12:34:27Z'), - dt_utz(2010, 12, 21, 12, 34, 27)) - assert_equals(string_to_datetime('2011-04-09T10:20:05Z'), - dt_utz(2011, 4, 9, 10, 20, 5)) - assert_equals(string_to_datetime('2011-04-09T10:05:58Z'), - dt_utz(2011, 4, 9, 10, 5, 58)) - assert_equals(string_to_datetime('2011-04-09T09:53:00Z'), - dt_utz(2011, 4, 9, 9, 53, 0)) - assert_equals(string_to_datetime('2011-04-09T10:00:21Z'), - dt_utz(2011, 4, 9, 10, 0, 21)) - assert_equals(string_to_datetime('2010-12-16T15:10:59Z'), - dt_utz(2010, 12, 16, 15, 10, 59)) - assert_equals(string_to_datetime('2011-04-09T09:53:00Z'), - dt_utz(2011, 4, 9, 9, 53, 0)) - assert_equals(string_to_datetime('2011-04-09T09:53:00Z'), - dt_utz(2011, 4, 9, 9, 53, 0)) + eq_(string_to_datetime('2011-05-22T00:24:15Z'), + dt_utz(2011, 5, 22, 0, 24, 15)) + eq_(string_to_datetime('2011-04-09T10:07:30Z'), + dt_utz(2011, 4, 9, 10, 7, 30)) + eq_(string_to_datetime('2011-02-19T07:16:11Z'), + dt_utz(2011, 2, 19, 7, 16, 11)) + eq_(string_to_datetime('2010-12-21T12:34:27Z'), + dt_utz(2010, 12, 21, 12, 34, 27)) + eq_(string_to_datetime('2011-04-09T10:20:05Z'), + dt_utz(2011, 4, 9, 10, 20, 5)) + eq_(string_to_datetime('2011-04-09T10:05:58Z'), + dt_utz(2011, 4, 9, 10, 5, 58)) + eq_(string_to_datetime('2011-04-09T09:53:00Z'), + dt_utz(2011, 4, 9, 9, 53, 0)) + eq_(string_to_datetime('2011-04-09T10:00:21Z'), + dt_utz(2011, 4, 9, 10, 0, 21)) + eq_(string_to_datetime('2010-12-16T15:10:59Z'), + dt_utz(2010, 12, 16, 15, 10, 59)) + eq_(string_to_datetime('2011-04-09T09:53:00Z'), + dt_utz(2011, 4, 9, 9, 53, 0)) + eq_(string_to_datetime('2011-04-09T09:53:00Z'), + dt_utz(2011, 4, 9, 9, 53, 0)) def test_datetime_to_isodate(): - assert_equals(datetime_to_isodate(dt_utz(2011, 5, 22, 0, 24, 15)), - '2011-05-22T00:24:15Z') - assert_equals(datetime_to_isodate(dt_utz(2011, 4, 9, 10, 7, 30)), - '2011-04-09T10:07:30Z') - assert_equals(datetime_to_isodate(dt_utz(2011, 2, 19, 7, 16, 11)), - '2011-02-19T07:16:11Z') - assert_equals(datetime_to_isodate(dt_utz(2010, 12, 21, 12, 34, 27)), - '2010-12-21T12:34:27Z') - assert_equals(datetime_to_isodate(dt_utz(2011, 4, 9, 10, 20, 5)), - '2011-04-09T10:20:05Z') - assert_equals(datetime_to_isodate(dt_utz(2011, 4, 9, 10, 5, 58)), - '2011-04-09T10:05:58Z') - assert_equals(datetime_to_isodate(dt_utz(2011, 4, 9, 9, 53, 0)), - '2011-04-09T09:53:00Z') - assert_equals(datetime_to_isodate(dt_utz(2011, 4, 9, 10, 0, 21)), - '2011-04-09T10:00:21Z') - assert_equals(datetime_to_isodate(dt_utz(2010, 12, 16, 15, 10, 59)), - '2010-12-16T15:10:59Z') - assert_equals(datetime_to_isodate(dt_utz(2011, 4, 9, 9, 53, 0)), - '2011-04-09T09:53:00Z') - assert_equals(datetime_to_isodate(dt_utz(2011, 4, 9, 9, 53, 0)), - '2011-04-09T09:53:00Z') + eq_(datetime_to_isodate(dt_utz(2011, 5, 22, 0, 24, 15)), + '2011-05-22T00:24:15Z') + eq_(datetime_to_isodate(dt_utz(2011, 4, 9, 10, 7, 30)), + '2011-04-09T10:07:30Z') + eq_(datetime_to_isodate(dt_utz(2011, 2, 19, 7, 16, 11)), + '2011-02-19T07:16:11Z') + eq_(datetime_to_isodate(dt_utz(2010, 12, 21, 12, 34, 27)), + '2010-12-21T12:34:27Z') + eq_(datetime_to_isodate(dt_utz(2011, 4, 9, 10, 20, 5)), + '2011-04-09T10:20:05Z') + eq_(datetime_to_isodate(dt_utz(2011, 4, 9, 10, 5, 58)), + '2011-04-09T10:05:58Z') + eq_(datetime_to_isodate(dt_utz(2011, 4, 9, 9, 53, 0)), + '2011-04-09T09:53:00Z') + eq_(datetime_to_isodate(dt_utz(2011, 4, 9, 10, 0, 21)), + '2011-04-09T10:00:21Z') + eq_(datetime_to_isodate(dt_utz(2010, 12, 16, 15, 10, 59)), + '2010-12-16T15:10:59Z') + eq_(datetime_to_isodate(dt_utz(2011, 4, 9, 9, 53, 0)), + '2011-04-09T09:53:00Z') + eq_(datetime_to_isodate(dt_utz(2011, 4, 9, 9, 53, 0)), + '2011-04-09T09:53:00Z') diff --git a/tests/test_unit.py b/tests/test_unit.py index f17f9a0..1769751 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -10,7 +10,7 @@ import datetime import unittest -from nose.tools import (assert_equals, assert_true) +from nose.tools import (eq_, assert_true) from github2.core import repr_string from github2.issues import Issue @@ -26,18 +26,18 @@ def test_issue(self): """Issues can have non-ASCII characters in the title.""" title = 'abcdé' i = Issue(title=title) - assert_equals(str, type(repr(i))) + eq_(str, type(repr(i))) class HostSetting(unittest.TestCase): def test_default_host(self): client = Github() - assert_equals(client.request.github_url, 'https://github.com') + eq_(client.request.github_url, 'https://github.com') def test_non_standard_host(self): client = Github(github_url="http://your-github-enterprise-url.com/") - assert_equals(client.request.github_url, - 'http://your-github-enterprise-url.com/') + eq_(client.request.github_url, + 'http://your-github-enterprise-url.com/') class RateLimits(utils.HttpMockTestCase): @@ -70,21 +70,21 @@ class BaseDataDict(utils.HttpMockTestCase): """Test __getitem__ availability on objects""" def test_getitem(self): user = self.client.users.show('defunkt') - assert_equals(user['blog'], user.blog) - assert_equals(user['company'], user.company) - assert_equals(user['email'], user.email) - assert_equals(user['location'], user.location) - assert_equals(user['login'], user.login) - assert_equals(user['name'], user.name) + eq_(user['blog'], user.blog) + eq_(user['company'], user.company) + eq_(user['email'], user.email) + eq_(user['location'], user.location) + eq_(user['login'], user.login) + eq_(user['name'], user.name) def test_project_for_user_repo(): client = Github() - assert_equals(client.project_for_user_repo('JNRowe', 'misc-overlay'), + eq_(client.project_for_user_repo('JNRowe', 'misc-overlay'), 'JNRowe/misc-overlay') def test_repr_string(): - assert_equals(repr_string('test'), 'test') - assert_equals(repr_string('abcdefghijklmnopqrst'), 'abcdefghijklmnopqrst') - assert_equals(repr_string('abcdefghijklmnopqrstu'), 'abcdefghijklmnopq...') + eq_(repr_string('test'), 'test') + eq_(repr_string('abcdefghijklmnopqrst'), 'abcdefghijklmnopqrst') + eq_(repr_string('abcdefghijklmnopqrstu'), 'abcdefghijklmnopq...') diff --git a/tests/test_user.py b/tests/test_user.py index 33929db..0d80359 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -5,7 +5,7 @@ import datetime -from nose.tools import (assert_equals, assert_false, assert_true) +from nose.tools import (eq_, assert_false, assert_true) import utils @@ -14,29 +14,28 @@ class UserProperties(utils.HttpMockTestCase): """Test user property handling""" def test_user(self): user = self.client.users.show('defunkt') - assert_equals(user.blog, 'http://chriswanstrath.com/') - assert_equals(user.company, 'GitHub') - assert_equals(user.email, 'chris@wanstrath.com') - assert_equals(user.location, 'San Francisco') - assert_equals(user.login, 'defunkt') - assert_equals(user.name, 'Chris Wanstrath') + eq_(user.blog, 'http://chriswanstrath.com/') + eq_(user.company, 'GitHub') + eq_(user.email, 'chris@wanstrath.com') + eq_(user.location, 'San Francisco') + eq_(user.login, 'defunkt') + eq_(user.name, 'Chris Wanstrath') def test_meta(self): user = self.client.users.show('defunkt') - assert_equals(user.created_at, - datetime.datetime(2007, 10, 19, 22, 24, 19)) - assert_equals(user.followers_count, 3402) - assert_equals(user.following_count, 212) - assert_equals(user.gravatar_id, 'b8dbb1987e8e5318584865f880036796') - assert_equals(user.id, 2) - assert_equals(user.public_gist_count, 278) - assert_equals(user.public_repo_count, 93) + eq_(user.created_at, datetime.datetime(2007, 10, 19, 22, 24, 19)) + eq_(user.followers_count, 3402) + eq_(user.following_count, 212) + eq_(user.gravatar_id, 'b8dbb1987e8e5318584865f880036796') + eq_(user.id, 2) + eq_(user.public_gist_count, 278) + eq_(user.public_repo_count, 93) def test_followers(self): - assert_equals(len(self.client.users.followers('defunkt')), 3402) + eq_(len(self.client.users.followers('defunkt')), 3402) def test_following(self): - assert_equals(len(self.client.users.following('defunkt')), 212) + eq_(len(self.client.users.following('defunkt')), 212) def test_is_not_authenticated(self): user = self.client.users.show('defunkt') @@ -46,12 +45,12 @@ def test_is_not_authenticated(self): class UserQueries(utils.HttpMockTestCase): """Test user querying """ def test_search(self): - assert_equals(repr(self.client.users.search('James Rowe')), - '[, ]') + eq_(repr(self.client.users.search('James Rowe')), + '[, ]') def test_search_by_email(self): user = self.client.users.search_by_email('jnrowe@gmail.com') - assert_equals(repr(user), '') + eq_(repr(user), '') class AuthenticatedUserMethods(utils.HttpMockAuthenticatedTestCase): @@ -69,21 +68,21 @@ def test_is_authenticated(self): def test_list_keys(self): keys = self.client.users.list_keys() - assert_equals(keys[0].id, 1337) + eq_(keys[0].id, 1337) class AuthenticatedUserProperties(utils.HttpMockAuthenticatedTestCase): def test_private_data(self): user = self.client.users.show('') - assert_equals(user.total_private_repo_count, 0) - assert_equals(user.collaborators, 0) - assert_equals(user.disk_usage, 66069) - assert_equals(user.owned_private_repo_count, 0) - assert_equals(user.private_gist_count, 7) + eq_(user.total_private_repo_count, 0) + eq_(user.collaborators, 0) + eq_(user.disk_usage, 66069) + eq_(user.owned_private_repo_count, 0) + eq_(user.private_gist_count, 7) def test_plan_data(self): user = self.client.users.show('') - assert_equals(user.plan['name'], "free") - assert_equals(user.plan['collaborators'], 0) - assert_equals(user.plan['space'], 307200) - assert_equals(user.plan['private_repos'], 0) + eq_(user.plan['name'], "free") + eq_(user.plan['collaborators'], 0) + eq_(user.plan['space'], 307200) + eq_(user.plan['private_repos'], 0) From 01fdd82966c044e17b8f786369197203ec8b8b8a Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 19:38:26 +0100 Subject: [PATCH 092/110] Use nose.tools.ok_ instead of assert_true. --- tests/test_organizations.py | 6 +++--- tests/test_unit.py | 10 +++++----- tests/test_user.py | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/test_organizations.py b/tests/test_organizations.py index 399d450..e2ddc77 100644 --- a/tests/test_organizations.py +++ b/tests/test_organizations.py @@ -5,7 +5,7 @@ from datetime import datetime -from nose.tools import (eq_, assert_true) +from nose.tools import (eq_, ok_) import utils @@ -31,9 +31,9 @@ def test_properties(self): def test_is_authenticated(self): organization = self.client.organizations.show('github') - assert_true(organization.is_authenticated() is False) + ok_(organization.is_authenticated() is False) organization = self.client.organizations.show('fake_org_with_auth') - assert_true(organization.is_authenticated() is True) + ok_(organization.is_authenticated() is True) class Organization(utils.HttpMockTestCase): diff --git a/tests/test_unit.py b/tests/test_unit.py index 1769751..ce93198 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -10,7 +10,7 @@ import datetime import unittest -from nose.tools import (eq_, assert_true) +from nose.tools import (eq_, ok_) from github2.core import repr_string from github2.issues import Issue @@ -53,9 +53,9 @@ def test_delays(self): delta = end - start delta_seconds = delta.days * 24 * 60 * 60 + delta.seconds - assert_true(delta_seconds >= 2, - "Expected .5 reqs per second to require a 2 second delay " - "between calls.") + ok_(delta_seconds >= 2, + "Expected .5 reqs per second to require a 2 second delay between " + "calls.") class BaseDataIter(utils.HttpMockTestCase): @@ -63,7 +63,7 @@ class BaseDataIter(utils.HttpMockTestCase): def test_iter(self): commit_id = '1c83cde9b5a7c396a01af1007fb7b88765b9ae45' commit = self.client.commits.show('ask/python-github2', commit_id) - assert_true('__iter__' in dir(commit)) + ok_('__iter__' in dir(commit)) class BaseDataDict(utils.HttpMockTestCase): diff --git a/tests/test_user.py b/tests/test_user.py index 0d80359..61fbc5c 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -5,7 +5,7 @@ import datetime -from nose.tools import (eq_, assert_false, assert_true) +from nose.tools import (eq_, assert_false, ok_) import utils @@ -39,7 +39,7 @@ def test_following(self): def test_is_not_authenticated(self): user = self.client.users.show('defunkt') - assert_true(user.is_authenticated() is False) + ok_(user.is_authenticated() is False) class UserQueries(utils.HttpMockTestCase): @@ -56,7 +56,7 @@ def test_search_by_email(self): class AuthenticatedUserMethods(utils.HttpMockAuthenticatedTestCase): def test_follow(self): result = self.client.users.follow('defunkt') - assert_true('defunkt' in result['users']) + ok_('defunkt' in result['users']) def test_unfollow(self): result = self.client.users.unfollow('defunkt') @@ -64,7 +64,7 @@ def test_unfollow(self): def test_is_authenticated(self): user = self.client.users.show('') - assert_true(user.is_authenticated() is True) + ok_(user.is_authenticated() is True) def test_list_keys(self): keys = self.client.users.list_keys() From bb968da0cc90dd60cf1709341a4b760d93a8405c Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 19:42:00 +0100 Subject: [PATCH 093/110] [QA] PEP 257 fixes to tests. --- tests/test_commits.py | 5 ++++- tests/test_issues.py | 4 +++- tests/test_regression.py | 2 +- tests/test_repositories.py | 4 +++- tests/test_request.py | 4 +++- tests/test_tz_aware_date_handling.py | 7 ++++--- tests/test_unit.py | 15 +++++++++++---- tests/test_user.py | 8 ++++++-- tests/utils.py | 14 +++++++++----- 9 files changed, 44 insertions(+), 19 deletions(-) diff --git a/tests/test_commits.py b/tests/test_commits.py index 33f037c..b27fbd3 100644 --- a/tests/test_commits.py +++ b/tests/test_commits.py @@ -11,7 +11,9 @@ class CommitProperties(utils.HttpMockTestCase): - """Test commit property handling""" + + """Test commit property handling.""" + commit_id = '1c83cde9b5a7c396a01af1007fb7b88765b9ae45' def test_commit(self): @@ -38,6 +40,7 @@ def test_repr(self): class CommitsQueries(utils.HttpMockTestCase): + """Test commit querying""" def test_list(self): diff --git a/tests/test_issues.py b/tests/test_issues.py index 2abf495..67cbff7 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -52,7 +52,9 @@ def test_comment_repr(self): class IssueQueries(utils.HttpMockTestCase): - """Test issue querying""" + + """Test issue querying.""" + def test_search(self): issues = self.client.issues.search('ask/python-github2', 'timezone', 'closed') diff --git a/tests/test_regression.py b/tests/test_regression.py index d5ff091..d9de696 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -13,7 +13,7 @@ def test_issue_50(): - """Erroneous init of ``Http`` with proxy setup + """Erroneous init of ``Http`` with proxy setup. See https://github.com/ask/python-github2/pull/50 """ diff --git a/tests/test_repositories.py b/tests/test_repositories.py index 39017df..8abbc30 100644 --- a/tests/test_repositories.py +++ b/tests/test_repositories.py @@ -19,7 +19,9 @@ def test_repr(self): class RepoProperties(utils.HttpMockTestCase): - """Test repository property handling""" + + """Test repository property handling.""" + def test_repo(self): repo = self.client.repos.show('JNRowe/misc-overlay') diff --git a/tests/test_request.py b/tests/test_request.py index 0833c00..529de26 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -35,7 +35,9 @@ def assert_params_contain(first, second): class TestAuthEncode(unittest.TestCase): - """Test processing of authentication data""" + + """Test processing of authentication data.""" + def setUp(self): self.r = request.GithubRequest() diff --git a/tests/test_tz_aware_date_handling.py b/tests/test_tz_aware_date_handling.py index 77302ba..c2b152f 100644 --- a/tests/test_tz_aware_date_handling.py +++ b/tests/test_tz_aware_date_handling.py @@ -15,19 +15,20 @@ def setup_module(): - """Enable timezone-aware datetime handling for this module's tests""" + """Enable timezone-aware datetime handling for this module's tests.""" core.NAIVE = False def teardown_module(): - """Disable timezone-aware datetime handling when tests have completed""" + """Disable timezone-aware datetime handling when tests have completed.""" core.NAIVE = True def dt_utz(year, month, day, hour, minute, second): - """Produce a UTC-anchored datetime object + """Produce a UTC-anchored datetime object. :see: :class:`datetime.datetime` + """ return dt(year, month, day, hour, minute, second, tzinfo=tzutc()) diff --git a/tests/test_unit.py b/tests/test_unit.py index ce93198..2095952 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -20,6 +20,7 @@ class ReprTests(unittest.TestCase): + """__repr__ must return strings, not unicode objects.""" def test_issue(self): @@ -41,9 +42,11 @@ def test_non_standard_host(self): class RateLimits(utils.HttpMockTestCase): - """Test API rate-limitting""" + + """Test API rate-limitting.""" + def test_delays(self): - """Test call delay is at least one second""" + """Test call delay is at least one second.""" client = Github(requests_per_second=.5) client.users.show('defunkt') start = datetime.datetime.utcnow() @@ -59,7 +62,9 @@ def test_delays(self): class BaseDataIter(utils.HttpMockTestCase): - """Test iter availability of objects""" + + """Test iter availability of objects.""" + def test_iter(self): commit_id = '1c83cde9b5a7c396a01af1007fb7b88765b9ae45' commit = self.client.commits.show('ask/python-github2', commit_id) @@ -67,7 +72,9 @@ def test_iter(self): class BaseDataDict(utils.HttpMockTestCase): - """Test __getitem__ availability on objects""" + + """Test __getitem__ availability on objects.""" + def test_getitem(self): user = self.client.users.show('defunkt') eq_(user['blog'], user.blog) diff --git a/tests/test_user.py b/tests/test_user.py index 61fbc5c..c2fab11 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -11,7 +11,9 @@ class UserProperties(utils.HttpMockTestCase): - """Test user property handling""" + + """Test user property handling.""" + def test_user(self): user = self.client.users.show('defunkt') eq_(user.blog, 'http://chriswanstrath.com/') @@ -43,7 +45,9 @@ def test_is_not_authenticated(self): class UserQueries(utils.HttpMockTestCase): - """Test user querying """ + + """Test user querying.""" + def test_search(self): eq_(repr(self.client.users.search('James Rowe')), '[, ]') diff --git a/tests/utils.py b/tests/utils.py index 598b068..1b38949 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -25,9 +25,10 @@ class HttpMock(object): - """Simple Http mock that returns saved entries + """Simple Http mock that returns saved entries. + + Implementation tests should never span network boundaries. - Implementation tests should never span network boundaries """ def __init__(self, cache=None, timeout=None, proxy_info=None, @@ -55,33 +56,36 @@ def request(self, uri, method='GET', body=None, headers=None, class HttpMockTestCase(unittest.TestCase): def setUp(self): - """Prepare test fixtures + """Prepare test fixtures. `httplib2.Http` is patched to return cached entries via :class:`HttpMock`. :attr:`client` is an unauthenticated :obj:`Github` object for easy use in tests. + """ httplib2.Http = HttpMock self.client = Github() def tearDown(self): - """Remove test fixtures + """Remove test fixtures. `httplib2.Http` is returned to its original state. + """ httplib2.Http = ORIG_HTTP_OBJECT class HttpMockAuthenticatedTestCase(HttpMockTestCase): def setUp(self): - """Prepare test fixtures + """Prepare test fixtures. :see: :class:`HttpMockTestCase` :attr:`client` is an authenticated :obj:`Github` object for easy use in tests. + """ httplib2.Http = HttpMock self.client = Github(access_token='xxx') From 0010b09bb1d4b71ef98b55c67bbe8249557df394 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 19:42:29 +0100 Subject: [PATCH 094/110] Mark rate limit test with 'slow' attribute. --- tests/test_unit.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_unit.py b/tests/test_unit.py index 2095952..5a5b55c 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -11,6 +11,7 @@ import unittest from nose.tools import (eq_, ok_) +from nose.plugins.attrib import attr from github2.core import repr_string from github2.issues import Issue @@ -45,6 +46,7 @@ class RateLimits(utils.HttpMockTestCase): """Test API rate-limitting.""" + @attr('slow') def test_delays(self): """Test call delay is at least one second.""" client = Github(requests_per_second=.5) From e1b7047a1439346c1d5a83cb497b0c1478cfd73d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 19:43:10 +0100 Subject: [PATCH 095/110] Rewrite issue 50 test without using Http mock. --- tests/test_regression.py | 14 ++++---------- tests/utils.py | 11 ++--------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index d9de696..b5fee60 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -9,20 +9,14 @@ from github2.client import Github -import utils - def test_issue_50(): """Erroneous init of ``Http`` with proxy setup. See https://github.com/ask/python-github2/pull/50 """ - utils.set_http_mock() - client = Github(proxy_host="my.proxy.com", proxy_port=9000) - setup_args = client.request._http.called_with - eq_(type(setup_args['proxy_info']), httplib2.ProxyInfo) - eq_(setup_args['proxy_info'].proxy_host, 'my.proxy.com') - eq_(setup_args['proxy_info'].proxy_port, 9000) - - utils.unset_http_mock() + proxy_info = client.request._http.proxy_info + eq_(type(proxy_info), httplib2.ProxyInfo) + eq_(proxy_info.proxy_host, 'my.proxy.com') + eq_(proxy_info.proxy_port, 9000) diff --git a/tests/utils.py b/tests/utils.py index 1b38949..e66284b 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -31,15 +31,8 @@ class HttpMock(object): """ - def __init__(self, cache=None, timeout=None, proxy_info=None, - ca_certs=None): - """Create a mock httplib.Http object - - .. attribute: called_with - - ``locals()`` during ``__init__``, for testing call spec - """ - self.called_with = locals() + def __init__(self, *args, **kwargs): + pass def request(self, uri, method='GET', body=None, headers=None, redirections=5, connection_type=None): From 6035cc3784543650fa8c9a731908c1b49d327cb4 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 19:45:03 +0100 Subject: [PATCH 096/110] Http mocking switched to use mock.Mock object. --- extra/requirements-test.txt | 1 + tests/utils.py | 58 +++++++++++++------------------------ 2 files changed, 21 insertions(+), 38 deletions(-) diff --git a/extra/requirements-test.txt b/extra/requirements-test.txt index c8d6b88..d271169 100644 --- a/extra/requirements-test.txt +++ b/extra/requirements-test.txt @@ -1,3 +1,4 @@ -r requirements.txt coverage>=3.5 +mock>=0.7.1 nose>=1.1.2 diff --git a/tests/utils.py b/tests/utils.py index e66284b..313836e 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -11,6 +11,8 @@ import httplib2 +from mock import Mock + from github2.client import Github from github2.request import charset_from_headers @@ -19,32 +21,26 @@ bytes = lambda x, enc: x -HTTP_DATA_DIR = "tests/data/" - -ORIG_HTTP_OBJECT = httplib2.Http +ORIG_REQUEST_METHOD = httplib2.Http.request -class HttpMock(object): - """Simple Http mock that returns saved entries. +def request_mock(uri, method='GET', body=None, headers=None, + redirections=5, connection_type=None): + """Http mock side effect that returns saved entries. Implementation tests should never span network boundaries. """ - def __init__(self, *args, **kwargs): - pass - - def request(self, uri, method='GET', body=None, headers=None, - redirections=5, connection_type=None): - file = os.path.join(HTTP_DATA_DIR, httplib2.safename(uri)) - if os.path.exists(file): - response = message_from_file(open(file)) - headers = httplib2.Response(response) - body = bytes(response.get_payload(), charset_from_headers(headers)) - return (headers, body) - else: - return (httplib2.Response({"status": "404"}), - "Resource %r unavailable from test data store" % file) + file = os.path.join("tests/data", httplib2.safename(uri)) + if os.path.exists(file): + response = message_from_file(open(file)) + headers = httplib2.Response(response) + body = bytes(response.get_payload(), charset_from_headers(headers)) + return (headers, body) + else: + return (httplib2.Response({"status": "404"}), + "Resource %r unavailable from test data store" % file) class HttpMockTestCase(unittest.TestCase): @@ -58,7 +54,8 @@ def setUp(self): in tests. """ - httplib2.Http = HttpMock + httplib2.Http.request = Mock(spec_set=httplib2.Http.request, + side_effect=request_mock) self.client = Github() def tearDown(self): @@ -67,7 +64,7 @@ def tearDown(self): `httplib2.Http` is returned to its original state. """ - httplib2.Http = ORIG_HTTP_OBJECT + httplib2.Http.request = ORIG_REQUEST_METHOD class HttpMockAuthenticatedTestCase(HttpMockTestCase): @@ -80,21 +77,6 @@ def setUp(self): in tests. """ - httplib2.Http = HttpMock + httplib2.Http.request = Mock(spec_set=httplib2.Http.request, + side_effect=request_mock) self.client = Github(access_token='xxx') - - -def set_http_mock(): - """Function to enable ``Http`` mock - - This is useful in simple `nose`-compliant test functions - """ - httplib2.Http = HttpMock - - -def unset_http_mock(): - """Function to disable ``Http`` mock - - :see: :func:`set_http_mock` - """ - httplib2.Http = ORIG_HTTP_OBJECT From 62472a34b18636219c286e2b9770ed8b4cfae5c6 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 20:48:07 +0100 Subject: [PATCH 097/110] Added test for requires_auth decorator. --- tests/test_unit.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/test_unit.py b/tests/test_unit.py index 5a5b55c..988d8d6 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -10,10 +10,10 @@ import datetime import unittest -from nose.tools import (eq_, ok_) +from nose.tools import (eq_, ok_, raises) from nose.plugins.attrib import attr -from github2.core import repr_string +from github2.core import (AuthError, repr_string, requires_auth) from github2.issues import Issue from github2.client import Github @@ -97,3 +97,12 @@ def test_repr_string(): eq_(repr_string('test'), 'test') eq_(repr_string('abcdefghijklmnopqrst'), 'abcdefghijklmnopqrst') eq_(repr_string('abcdefghijklmnopqrstu'), 'abcdefghijklmnopq...') + + +class RequiresAuth(utils.HttpMockTestCase): + @raises(AuthError) + def test_no_auth(self): + f = lambda: None + f.__doc__ = 'test func' + wrapped = requires_auth(f) + wrapped(self.client) From fd2a2ba8196a7150fa90cb882fd6806265bc8f3e Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 20:59:13 +0100 Subject: [PATCH 098/110] Added BaseData dict key failure test. --- tests/test_unit.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_unit.py b/tests/test_unit.py index 988d8d6..50312d0 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -86,6 +86,11 @@ def test_getitem(self): eq_(user['login'], user.login) eq_(user['name'], user.name) + @raises(KeyError) + def test_getitem_failure(self): + user = self.client.users.show('defunkt') + ok_(user['invalid_key']) + def test_project_for_user_repo(): client = Github() From fbe6e453a5d828c9317642f5647ea47e32da4670 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 21:07:25 +0100 Subject: [PATCH 099/110] Added BaseData dict setting tests. --- tests/test_unit.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test_unit.py b/tests/test_unit.py index 50312d0..d49dc38 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -75,7 +75,7 @@ def test_iter(self): class BaseDataDict(utils.HttpMockTestCase): - """Test __getitem__ availability on objects.""" + """Test dict compatibility on objects.""" def test_getitem(self): user = self.client.users.show('defunkt') @@ -91,6 +91,16 @@ def test_getitem_failure(self): user = self.client.users.show('defunkt') ok_(user['invalid_key']) + def test_setitem(self): + user = self.client.users.show('defunkt') + user['blog'] = 'http://example.com' + eq_(user['blog'], 'http://example.com') + + @raises(KeyError) + def test_setitem_failure(self): + user = self.client.users.show('defunkt') + user['invalid_key'] = 'test' + def test_project_for_user_repo(): client = Github() From 5c60b01d58359da94c11c4e8cd016050185a8fa8 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 21:54:45 +0100 Subject: [PATCH 100/110] Use mock for sleep in rate limit tests. --- tests/test_unit.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/tests/test_unit.py b/tests/test_unit.py index d49dc38..104256d 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -7,11 +7,10 @@ # This file is part of python-github2, and is made available under the 3-clause # BSD license. See LICENSE for the full details. -import datetime import unittest +from mock import patch from nose.tools import (eq_, ok_, raises) -from nose.plugins.attrib import attr from github2.core import (AuthError, repr_string, requires_auth) from github2.issues import Issue @@ -44,23 +43,17 @@ def test_non_standard_host(self): class RateLimits(utils.HttpMockTestCase): - """Test API rate-limitting.""" + """Test API rate-limiting.""" - @attr('slow') - def test_delays(self): - """Test call delay is at least one second.""" + @patch('github2.request.time.sleep') + def test_delays(self, sleep): + """Test calls in quick succession are delayed.""" client = Github(requests_per_second=.5) client.users.show('defunkt') - start = datetime.datetime.utcnow() client.users.show('mojombo') - end = datetime.datetime.utcnow() - delta = end - start - delta_seconds = delta.days * 24 * 60 * 60 + delta.seconds - - ok_(delta_seconds >= 2, - "Expected .5 reqs per second to require a 2 second delay between " - "calls.") + # 0.5 requests per second, means a two second delay + sleep.assert_called_once_with(2.0) class BaseDataIter(utils.HttpMockTestCase): From 614d8b25f49af6d29ad77aa529a0e7cb09b41bb8 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 21:56:30 +0100 Subject: [PATCH 101/110] Fix BaseData dict compat logging. --- github2/core.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/github2/core.py b/github2/core.py index f1629fd..86d4788 100644 --- a/github2/core.py +++ b/github2/core.py @@ -364,8 +364,7 @@ def __getitem__(self, key): """ LOGGER.warning("Subscript access on %r is deprecated, use object " - "attributes" % self.__class__.__name__, - DeprecationWarning) + "attributes" % self.__class__.__name__) if not key in self._meta.keys(): raise KeyError(key) return getattr(self, key) @@ -377,8 +376,7 @@ def __setitem__(self, key, value): """ LOGGER.warning("Subscript access on %r is deprecated, use object " - "attributes" % self.__class__.__name__, - DeprecationWarning) + "attributes" % self.__class__.__name__) if not key in self._meta.keys(): raise KeyError(key) setattr(self, key, value) From 32a076965d578fb62208939e9b8f5711df1e3e9e Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 16 May 2012 21:57:55 +0100 Subject: [PATCH 102/110] Handle symlinked certificate bundles for httplib2, --- github2/request.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/github2/request.py b/github2/request.py index 31afa78..1314c77 100644 --- a/github2/request.py +++ b/github2/request.py @@ -59,8 +59,12 @@ #: Logger for requests module LOGGER = logging.getLogger('github2.request') +# Fetch actual path for httplib2's default cert bundle, for distributions that +# symlink their system certs +_HTTPLIB2_BUNDLE = path.realpath(path.dirname(httplib2.CA_CERTS)) #: Whether github2 is using the system's certificates for SSL connections -SYSTEM_CERTS = not httplib2.CA_CERTS.startswith(path.dirname(httplib2.__file__)) +SYSTEM_CERTS = not _HTTPLIB2_BUNDLE.startswith(path.dirname(httplib2.__file__)) +CA_CERTS = None #: Whether github2 is using the cert's from the file given in $CURL_CA_BUNDLE CURL_CERTS = False if not SYSTEM_CERTS and sys.platform.startswith('linux'): From 55d92f3268163c3bef902bdb06be706993dd33b5 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 23 May 2012 05:52:51 +0100 Subject: [PATCH 103/110] Updated dependency information for dateutil-2.1 support. This has become quite messy, to the point that I had a little look for a hackable replacement. --- doc/install.rst | 5 +++-- extra/requirements-py25.txt | 5 +++-- extra/requirements-py3.txt | 2 -- extra/requirements.txt | 4 ++-- setup.py | 10 +++++++--- 5 files changed, 15 insertions(+), 11 deletions(-) delete mode 100644 extra/requirements-py3.txt diff --git a/doc/install.rst b/doc/install.rst index 84b57de..7eb1aa6 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -33,5 +33,6 @@ handling [#]_. :pypi:`simplejson` is also required when using :mod:`github2` with Python 2.4 or 2.5. If you install via :pypi:`pip` or :pypi:`easy_install ` the dependencies should be installed automatically for you. -.. [#] You must use :pypi:`python-dateutil` 1.x when working with Python 2.x, - the latest 2.x releases are for Python 3.x installations only. +.. [#] You must use :pypi:`python-dateutil` 1.x when working with Python 2.5 or + earlier, the latest 2.x releases are for Python 2.6 and newer + installations only. diff --git a/extra/requirements-py25.txt b/extra/requirements-py25.txt index 33f97ee..45bfac5 100644 --- a/extra/requirements-py25.txt +++ b/extra/requirements-py25.txt @@ -1,2 +1,3 @@ --r requirements.txt -simplejson>=2.0.9 +httplib2 >= 0.7.0 +python-dateutil < 2.0, >= 2.1 +simplejson >= 2.0.9 diff --git a/extra/requirements-py3.txt b/extra/requirements-py3.txt deleted file mode 100644 index 457b3fb..0000000 --- a/extra/requirements-py3.txt +++ /dev/null @@ -1,2 +0,0 @@ -httplib2>=0.7.0 -python-dateutil>=2.0 diff --git a/extra/requirements.txt b/extra/requirements.txt index 57c76c4..5115300 100644 --- a/extra/requirements.txt +++ b/extra/requirements.txt @@ -1,2 +1,2 @@ -httplib2>=0.7.0 -python-dateutil<2.0 +httplib2 >= 0.7.0 +python-dateutil < 2.0 diff --git a/setup.py b/setup.py index 06c56bb..72073f5 100755 --- a/setup.py +++ b/setup.py @@ -23,10 +23,14 @@ if sys.version_info[:2] < (2, 6): install_requires.append('simplejson >= 2.0.9') -if sys.version_info >= (3,): - install_requires.append('python-dateutil >= 2.0') -else: +# dateutil supports python 2.x in dateutil-1, python 3.x in dateutil-2.0 and +# python 2.6+ in dateutil-2.1. Exciting… +if sys.version_info[:2] <= (2, 5): install_requires.append('python-dateutil < 2.0') +elif sys.version_info < (3, ): + install_requires.append('python-dateutil < 2.0, >= 2.1') +else: + install_requires.append('python-dateutil > 2.0') long_description = (codecs.open('README.rst', "r", "utf-8").read() + "\n" + codecs.open('NEWS.rst', "r", "utf-8").read()) From a77c23a85a1f2eacebd0697608bbe510e3ee775c Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 23 May 2012 07:52:17 +0100 Subject: [PATCH 104/110] Fixed simplejson dependency for Python 2.4. Recent versions of simplejson no longer support Python 2.4. --- setup.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 72073f5..b72d775 100755 --- a/setup.py +++ b/setup.py @@ -19,8 +19,12 @@ install_requires = ['httplib2 >= 0.7.0', ] -# simplejson is included in the standard library since Python 2.6 as json. -if sys.version_info[:2] < (2, 6): + +# simplejson is included in the standard library since Python 2.6 as json +if sys.version_info < (2, 5): + # 2.1 drops support for 2.4 + install_requires.append('simplejson >= 2.0.9, < 2.1') +elif sys.version_info[:2] < (2, 6): install_requires.append('simplejson >= 2.0.9') # dateutil supports python 2.x in dateutil-1, python 3.x in dateutil-2.0 and From bad4e74bf58ad3d4c964070a54304a67ff8b4b09 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 23 May 2012 07:52:46 +0100 Subject: [PATCH 105/110] Re-sync dependencies in tox config. --- tox.ini | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tox.ini b/tox.ini index 531bac9..ffb9775 100644 --- a/tox.ini +++ b/tox.ini @@ -6,8 +6,28 @@ envlist = py24, py25, py26, py27, py31, py32, rst, sphinx deps = nose coverage + mock commands = nosetests {posargs:-vv} tests +# When tox 1.4 is released use substitution to remove all the duplication. +[testenv:py24] +deps = + nose + coverage + mock + unittest2 +[testenv:py25] +deps = + nose + coverage + mock + unittest2 +[testenv:py26] +deps = + nose + coverage + mock + unittest2 [testenv:rst] deps = docutils From 46020575a632f1a4b78c878c84d40e1400ccd42c Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 11 Jun 2012 13:08:14 +0100 Subject: [PATCH 106/110] Rewording of the API v3 migration note. There has been a reprieve for the API v2 switch-off, and the note from 3414c22d25a54624e554be5bdb8a6fb327ff27d7 is no longer as urgent. --- README.rst | 5 ++--- doc/index.rst | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index a266014..b3897ef 100644 --- a/README.rst +++ b/README.rst @@ -8,8 +8,8 @@ github2 - GitHub API v2 library for Python. .. warning:: - GitHub are planning to `switch off API v2`_ on 2012-05-01, you should - be looking to replace ``github2`` as soon as possible. + GitHub have marked API v2 as deprecated, you should be looking to replace + your usage of ``github2`` in the near future. Both remoteobjects_ and micromodels_ provide easy-to-use functionality for creating bindings to remote APIs, and should significantly reduce the amount @@ -21,7 +21,6 @@ of the `GitHub API`_. See the ``doc/`` directory for installation instructions and usage information. If you prefer you can also read the `documentation online`_. -.. _switch off API v2: https://github.com/blog/1090-github-api-moving-on .. _remoteobjects: https://github.com/saymedia/remoteobjects .. _micromodels: https://github.com/j4mie/micromodels .. _GitHub API: http://develop.github.com/ diff --git a/doc/index.rst b/doc/index.rst index d909c02..963e6a2 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -16,14 +16,13 @@ .. warning:: - GitHub are planning to `switch off API v2`_ on 2012-05-01, you should - be looking to replace ``github2`` as soon as possible. + GitHub have marked API v2 as deprecated, you should be looking to replace + your usage of ``github2`` in the near future. Both remoteobjects_ and micromodels_ provide easy-to-use functionality for creating bindings to remote APIs, and should significantly reduce the amount of work needed in moving away from GitHub's API v2. -.. _switch off API v2: https://github.com/blog/1090-github-api-moving-on .. _remoteobjects: https://github.com/saymedia/remoteobjects .. _micromodels: https://github.com/j4mie/micromodels From 8647c559ceb9b0ecd3af68e728e36fb2de4b6ab2 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 11 Jun 2012 13:09:34 +0100 Subject: [PATCH 107/110] Minor fixes to quickstart doc. This makes the usage far closer to what a user would expect in an interactive session. --- doc/quickstart.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/quickstart.rst b/doc/quickstart.rst index 2d3988f..ff54b29 100644 --- a/doc/quickstart.rst +++ b/doc/quickstart.rst @@ -13,6 +13,7 @@ package. Create an unauthenticated client object:: + >>> from github2.client import Github >>> github = Github() .. note:: @@ -28,6 +29,7 @@ Read the description of the ``python-github2`` project:: >>> repo = github.repos.show("ask/python-github2") >>> repo.description + u'github client in python, with issues support.' We can take advantage of Python's :func:`dir` to explore the package a little more:: From 698394fa0d5e03ca43a02dccd4ce6a2f553576f5 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 11 Jun 2012 13:22:19 +0100 Subject: [PATCH 108/110] Include ChangeLog in sdist generated tarballs. --- MANIFEST.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MANIFEST.in b/MANIFEST.in index ac52cc3..e77f35d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,6 @@ recursive-include examples * + +include ChangeLog include NEWS.rst include README.rst include AUTHORS From 587f415607426a1eb1ab8e13f8ea0031525d3de6 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 11 Jun 2012 13:46:39 +0100 Subject: [PATCH 109/110] Bumped version to 0.6.2. --- NEWS.rst | 6 ++++++ README.rst | 2 +- github2/_version.py | 14 +++++++------- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index e7092fe..eaa874c 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -6,6 +6,12 @@ look at the `git repository`_ for the full project history. .. _git repository: https://github.com/ask/python-github2/ +0.6.2 - 2012-06-11 +------------------ + +* Updated dependencies to handle recent ``python-dateutil`` releases +* Fixed ``simplejson`` dependencies for Python 2.4 + 0.6.1 - 2012-02-28 ------------------ diff --git a/README.rst b/README.rst index b3897ef..a91633f 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ github2 - GitHub API v2 library for Python. :Authors: Ask Solem (askh@opera.com) -:Version: 0.6.1 +:Version: 0.6.2 .. warning:: diff --git a/github2/_version.py b/github2/_version.py index 0269a27..6e26b1f 100644 --- a/github2/_version.py +++ b/github2/_version.py @@ -1,9 +1,9 @@ -# This is github2 version 0.6.1 (2012-02-28) +# This is github2 version 0.6.2 (2012-06-11) # pylint: disable=C0103, C0111, C0121, W0622 -dotted = "0.6.1" -libtool = "6:21" -hex = 0x000601 -date = "2012-02-28" -tuple = (0, 6, 1) -web = "github2/0.6.1" +dotted = "0.6.2" +libtool = "6:22" +hex = 0x000602 +date = "2012-06-11" +tuple = (0, 6, 2) +web = "github2/0.6.2" From 4287019520643e2fcd46c9c5b3aac439cdc35b88 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Tue, 20 Jul 2021 07:48:23 +1000 Subject: [PATCH 110/110] docs: Fix a few typos (#82) There are small typos in: - github2/client.py - github2/request.py Fixes: - Should read `specific` rather than `specifc`. - Should read `occurred` rather than `occured`. --- github2/client.py | 2 +- github2/request.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/github2/client.py b/github2/client.py index 56b5dcd..d0a3f2b 100644 --- a/github2/client.py +++ b/github2/client.py @@ -107,7 +107,7 @@ def get_blob_info(self, project, tree_sha, path): return blob.get("blob") def get_tree(self, project, tree_sha): - """Get tree information for a specifc tree. + """Get tree information for a specific tree. :param str project: GitHub project :param str tree_sha: object ID of tree diff --git a/github2/request.py b/github2/request.py index 1314c77..5961471 100644 --- a/github2/request.py +++ b/github2/request.py @@ -113,7 +113,7 @@ class GithubError(Exception): class HttpError(RuntimeError): - """A HTTP error occured when making a request to the GitHub API.""" + """A HTTP error occurred when making a request to the GitHub API.""" def __init__(self, message, content, code): """Create a HttpError exception.