Merge branch 'develop' into topic/ConditionalRequest

Conflicts:
	.gitignore
	github/Requester.py
This commit is contained in:
Vincent Jacques
2013-08-22 11:01:51 +02:00
85 changed files with 684 additions and 421 deletions
+1 -1
View File
@@ -5,8 +5,8 @@
# Copyright 2012 Steve English <steve.english@navetas.com> #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+1 -1
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1 -1
View File
@@ -4,9 +4,9 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+1 -1
View File
@@ -4,9 +4,9 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+1 -16
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -199,18 +199,3 @@ class CommitComment(github.GithubObject.CompletableGithubObject):
if "user" in attributes: # pragma no branch
assert attributes["user"] is None or isinstance(attributes["user"], dict), attributes["user"]
self._user = None if attributes["user"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["user"], completed=False)
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1 -1
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+1 -1
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1 -8
View File
@@ -4,9 +4,9 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -128,10 +128,3 @@ class Event(github.GithubObject.NonCompletableGithubObject):
if "type" in attributes: # pragma no branch
assert attributes["type"] is None or isinstance(attributes["type"], (str, unicode)), attributes["type"]
self._type = attributes["type"]
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+3 -18
View File
@@ -5,8 +5,8 @@
# Copyright 2012 Steve English <steve.english@navetas.com> #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -179,12 +179,12 @@ class Gist(github.GithubObject.CompletableGithubObject):
def create_fork(self):
"""
:calls: `POST /gists/:id/fork <http://developer.github.com/v3/todo>`_
:calls: `POST /gists/:id/forks <http://developer.github.com/v3/gists>`_
:rtype: :class:`github.Gist.Gist`
"""
headers, data = self._requester.requestJsonAndCheck(
"POST",
self.url + "/fork",
self.url + "/forks",
None,
None
)
@@ -360,18 +360,3 @@ class Gist(github.GithubObject.CompletableGithubObject):
if "user" in attributes: # pragma no branch
assert attributes["user"] is None or isinstance(attributes["user"], dict), attributes["user"]
self._user = None if attributes["user"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["user"], completed=False)
+1 -16
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -139,18 +139,3 @@ class GistComment(github.GithubObject.CompletableGithubObject):
if "user" in attributes: # pragma no branch
assert attributes["user"] is None or isinstance(attributes["user"], dict), attributes["user"]
self._user = None if attributes["user"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["user"], completed=False)
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1 -13
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -98,15 +98,3 @@ class GistHistoryState(github.GithubObject.CompletableGithubObject):
if "version" in attributes: # pragma no branch
assert attributes["version"] is None or isinstance(attributes["version"], (str, unicode)), attributes["version"]
self._version = attributes["version"]
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1 -13
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -129,15 +129,3 @@ class GitCommit(github.GithubObject.CompletableGithubObject):
if "url" in attributes: # pragma no branch
assert attributes["url"] is None or isinstance(attributes["url"], (str, unicode)), attributes["url"]
self._url = attributes["url"]
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1 -1
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+1 -13
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -110,15 +110,3 @@ class GitTag(github.GithubObject.CompletableGithubObject):
if "url" in attributes: # pragma no branch
assert attributes["url"] is None or isinstance(attributes["url"], (str, unicode)), attributes["url"]
self._url = attributes["url"]
+1 -6
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -80,8 +80,3 @@ class GitTree(github.GithubObject.CompletableGithubObject):
if "url" in attributes: # pragma no branch
assert attributes["url"] is None or isinstance(attributes["url"], (str, unicode)), attributes["url"]
self._url = attributes["url"]
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1 -1
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+1
View File
@@ -3,6 +3,7 @@
############################ Copyrights and license ############################
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+4 -5
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -31,7 +31,7 @@ import github.HookResponse
class Hook(github.GithubObject.CompletableGithubObject):
"""
This class represents Hooks as returned for example by http://developer.github.com/v3/todo
This class represents Hooks as returned for example by http://developer.github.com/v3/repos/hooks
"""
@property
@@ -157,12 +157,12 @@ class Hook(github.GithubObject.CompletableGithubObject):
def test(self):
"""
:calls: `POST /repos/:owner/:repo/hooks/:id/test <http://developer.github.com/v3/todo>`_
:calls: `POST /repos/:owner/:repo/hooks/:id/tests <http://developer.github.com/v3/repos/hooks>`_
:rtype: None
"""
headers, data = self._requester.requestJsonAndCheck(
"POST",
self.url + "/test",
self.url + "/tests",
None,
None
)
@@ -206,4 +206,3 @@ class Hook(github.GithubObject.CompletableGithubObject):
if "url" in attributes: # pragma no branch
assert attributes["url"] is None or isinstance(attributes["url"], (str, unicode)), attributes["url"]
self._url = attributes["url"]
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+7 -17
View File
@@ -6,8 +6,9 @@
# Copyright 2012 Philip Kimmey <philip@rover.com> #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Stuart Glaser <stuglaser@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -145,7 +146,11 @@ class Issue(github.GithubObject.CompletableGithubObject):
:type: :class:`github.Repository.Repository`
"""
self._completeIfNotSet(self._repository)
return self._NoneIfNotSet(self._repository)
if self._repository is github.GithubObject.NotSet:
# The repository was not set automatically, so it must be looked up by url.
repo_url = "/".join(self.url.split("/")[:-2])
self._repository = github.Repository.Repository(self._requester, self._headers, {'url': repo_url}, completed=False)
return self._repository
@property
def state(self):
@@ -432,18 +437,3 @@ class Issue(github.GithubObject.CompletableGithubObject):
if "user" in attributes: # pragma no branch
assert attributes["user"] is None or isinstance(attributes["user"], dict), attributes["user"]
self._user = None if attributes["user"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["user"], completed=False)
+1 -16
View File
@@ -4,9 +4,9 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Michael Stead <michael.stead@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -152,18 +152,3 @@ class IssueComment(github.GithubObject.CompletableGithubObject):
if "user" in attributes: # pragma no branch
assert attributes["user"] is None or isinstance(attributes["user"], dict), attributes["user"]
self._user = None if attributes["user"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["user"], completed=False)
+1 -13
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -122,15 +122,3 @@ class IssueEvent(github.GithubObject.CompletableGithubObject):
if "url" in attributes: # pragma no branch
assert attributes["url"] is None or isinstance(attributes["url"], (str, unicode)), attributes["url"]
self._url = attributes["url"]
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# #
+1 -2
View File
@@ -5,8 +5,8 @@
# Copyright 2012 Steve English <steve.english@navetas.com> #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -69,7 +69,6 @@ class PaginatedList(github.PaginatedList.PaginatedListBase):
]
def convertUser(attributes):
convertedAttributes = {
"login": attributes["login"],
+48 -16
View File
@@ -2,10 +2,11 @@
############################ Copyrights and license ############################
# #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Ed Jackson <ed.jackson@gmail.com> #
# Copyright 2013 Jonathan J Hunt <hunt@braincorporation.com> #
# Copyright 2013 Peter Golm <golm.peter@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -96,10 +97,34 @@ class Github(object):
@property
def rate_limiting(self):
"""
First value is requests remaining, second value is request limit.
:type: (int, int)
"""
remaining, limit = self.__requester.rate_limiting
if limit < 0:
self.__requester.requestJsonAndCheck(
'GET',
'/rate_limit',
None,
None
)
return self.__requester.rate_limiting
@property
def rate_limiting_resettime(self):
"""
Unix timestamp indicating when rate limiting will reset.
:type: int
"""
if self.__requester.rate_limiting_resettime == 0:
self.__requester.requestJsonAndCheck(
'GET',
'/rate_limit',
None,
None
)
return self.__requester.rate_limiting_resettime
@property
def oauth_scopes(self):
"""
@@ -171,6 +196,23 @@ class Github(object):
)
return Repository.Repository(self.__requester, headers, data, completed=True)
def get_repos(self, since=github.GithubObject.NotSet):
"""
:calls: `GET /repositories <http://developer.github.com/v3/repos/#list-all-public-repositories>`_
:param since: integer
:rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository`
"""
assert since is github.GithubObject.NotSet or isinstance(since, (int, long)), since
url_parameters = dict()
if since is not github.GithubObject.NotSet:
url_parameters["since"] = since
return github.PaginatedList.PaginatedList(
github.Repository.Repository,
self.__requester,
"/repositories",
url_parameters
)
def get_gist(self, id):
"""
:calls: `GET /gists/:id <http://developer.github.com/v3/gists>`_
@@ -200,7 +242,7 @@ class Github(object):
def legacy_search_repos(self, keyword, language=github.GithubObject.NotSet):
"""
:calls: `GET /legacy/repos/search/:keyword <http://developer.github.com/v3/search>`_
:calls: `GET /legacy/repos/search/:keyword <http://developer.github.com/v3/search/legacy>`_
:param keyword: string
:param language: string
:rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository`
@@ -219,7 +261,7 @@ class Github(object):
def legacy_search_users(self, keyword):
"""
:calls: `GET /legacy/user/search/:keyword <http://developer.github.com/v3/search>`_
:calls: `GET /legacy/user/search/:keyword <http://developer.github.com/v3/search/legacy>`_
:param keyword: string
:rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.NamedUser.NamedUser`
"""
@@ -235,7 +277,7 @@ class Github(object):
def legacy_search_user_by_email(self, email):
"""
:calls: `GET /legacy/user/email/:email <http://developer.github.com/v3/search>`_
:calls: `GET /legacy/user/email/:email <http://developer.github.com/v3/search/legacy>`_
:param email: string
:rtype: :class:`github.NamedUser.NamedUser`
"""
@@ -246,7 +288,7 @@ class Github(object):
None,
None
)
return github.NamedUser.NamedUser(self.__requester, headers, Legacy.convertUser(data["user"]), completed=False)
return github.NamedUser.NamedUser(self.__requester, headers, Legacy.convertUser(data["user"]), completed=False)
def render_markdown(self, text, context=github.GithubObject.NotSet):
"""
@@ -311,7 +353,7 @@ class Github(object):
)
return GitignoreTemplate.GitignoreTemplate(self.__requester, headers, attributes, completed=True)
def create_from_raw_data(self, klass, raw_data, headers = {}):
def create_from_raw_data(self, klass, raw_data, headers={}):
"""
Creates an object from raw_data previously obtained by :attr:`github.GithubObject.GithubObject.raw_data`
@@ -320,13 +362,3 @@ class Github(object):
:rtype: instance of class ``klass``
"""
return klass(self.__requester, headers, raw_data, completed=True)
+1 -1
View File
@@ -4,9 +4,9 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+16 -1
View File
@@ -5,8 +5,8 @@
# Copyright 2012 Steve English <steve.english@navetas.com> #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -450,6 +450,21 @@ class NamedUser(github.GithubObject.CompletableGithubObject):
None
)
def has_in_following(self, following):
"""
:calls: `GET /user/:user/following/:target_user <http://developer.github.com/v3/users/followers/#check-if-one-user-follows-another>`_
:param following: :class:`github.NamedUser.NamedUser`
:rtype: bool
"""
assert isinstance(following, github.NamedUser.NamedUser), following
status, headers, data = self._requester.requestJson(
"GET",
self.url + "/following/" + following._identity,
None,
None
)
return status == 204
@property
def _identity(self):
return self.login
+3 -6
View File
@@ -2,10 +2,10 @@
############################ Copyrights and license ############################
# #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Peter Golm <golm.peter@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -119,8 +119,5 @@ class Notification(github.GithubObject.CompletableGithubObject):
assert attributes["updated_at"] is None or isinstance(attributes["updated_at"], (str, unicode)), attributes["updated_at"]
self._updated_at = self._parseDatetime(attributes["updated_at"])
if "url" in attributes: # pragma no branch
assert attributes["url"] is None or isinstance(attributes["url"], (str, unicode)), attributes["url"]
self._url = attributes["url"]
assert attributes["url"] is None or isinstance(attributes["url"], (str, unicode)), attributes["url"] # pragma no cover (but should be investigated)
self._url = attributes["url"] # pragma no cover (but should be investigated)
+5 -4
View File
@@ -2,6 +2,7 @@
############################ Copyrights and license ############################
# #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
@@ -68,11 +69,11 @@ class NotificationSubject(github.GithubObject.NonCompletableGithubObject):
assert attributes["title"] is None or isinstance(attributes["title"], (str, unicode)), attributes["title"]
self._title = attributes["title"]
if "url" in attributes: # pragma no branch
assert attributes["url"] is None or isinstance(attributes["url"], (str, unicode)), attributes["url"]
self._url = attributes["url"]
assert attributes["url"] is None or isinstance(attributes["url"], (str, unicode)), attributes["url"] # pragma no cover (but should be investigated)
self._url = attributes["url"] # pragma no cover (but should be investigated)
if "latest_comment_url" in attributes: # pragma no branch
assert attributes["latest_comment_url"] is None or isinstance(attributes["latest_comment_url"], (str, unicode)), attributes["latest_comment_url"]
self._latest_comment_url = attributes["latest_comment_url"]
assert attributes["latest_comment_url"] is None or isinstance(attributes["latest_comment_url"], (str, unicode)), attributes["latest_comment_url"] # pragma no cover (but should be investigated)
self._latest_comment_url = attributes["latest_comment_url"] # pragma no cover (but should be investigated)
if "type" in attributes: # pragma no branch
assert attributes["type"] is None or isinstance(attributes["type"], (str, unicode)), attributes["type"]
self._type = attributes["type"]
+1 -1
View File
@@ -5,9 +5,9 @@
# Copyright 2012 Steve English <steve.english@navetas.com> #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+43 -13
View File
@@ -4,10 +4,10 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Bill Mill <bill.mill@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 davidbrai <davidbrai@gmail.com> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -27,7 +27,7 @@
################################################################################
import github.GithubObject
import inspect
class PaginatedListBase:
def __init__(self):
@@ -95,6 +95,11 @@ class PaginatedList(PaginatedListBase):
second_repo = user.get_repos()[1]
first_repos = user.get_repos()[:10]
If you want to iterate in reversed order, just do::
for repo in user.get_repos().reversed:
print repo.name
And if you really need it, you can explicitely access a specific page::
some_repos = user.get_repos().get_page(0)
@@ -111,6 +116,25 @@ class PaginatedList(PaginatedListBase):
self.__nextParams = firstParams or {}
if self.__requester.per_page != 30:
self.__nextParams["per_page"] = self.__requester.per_page
self._reversed = False
def _getLastPageUrl(self):
headers, data = self.__requester.requestJsonAndCheck("GET", self.__firstUrl, self.__nextParams, None)
links = self.__parseLinkHeader(headers)
lastUrl = links.get("last")
return lastUrl
@property
def reversed(self):
r = PaginatedList(self.__contentClass, self.__requester, self.__firstUrl, self.__firstParams)
r.__reverse()
return r
def __reverse(self):
self._reversed = True
lastUrl = self._getLastPageUrl()
if lastUrl:
self.__nextUrl = lastUrl
def _couldGrow(self):
return self.__nextUrl is not None
@@ -118,22 +142,28 @@ class PaginatedList(PaginatedListBase):
def _fetchNextPage(self):
headers, data = self.__requester.requestJsonAndCheck("GET", self.__nextUrl, self.__nextParams, None)
links = self.__parseLinkHeader(headers)
if len(data) > 0 and "next" in links:
self.__nextUrl = links["next"]
else:
self.__nextUrl = None
self.__nextUrl = None
if len(data) > 0:
links = self.__parseLinkHeader(headers)
if self._reversed:
if "prev" in links:
self.__nextUrl = links["prev"]
elif "next" in links:
self.__nextUrl = links["next"]
self.__nextParams = None
return [
content = [
self.__contentClass(self.__requester, headers, element, completed=False)
for element in data]
for element in data
]
if self._reversed:
return content[::-1]
return content
def __parseLinkHeader(self, headers):
links = {}
if "link" in headers:
linkHeaders = headers["link"].split(",")
linkHeaders = headers["link"].split(", ")
for linkHeader in linkHeaders:
(url, rel) = linkHeader.split("; ")
url = url[1:-1]
@@ -151,5 +181,5 @@ class PaginatedList(PaginatedListBase):
return [
self.__contentClass(self.__requester, headers, element, completed=False)
for element in data]
for element in data
]
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
+2 -17
View File
@@ -5,9 +5,9 @@
# Copyright 2012 Michael Stead <michael.stead@gmail.com> #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -500,7 +500,7 @@ class PullRequest(github.GithubObject.CompletableGithubObject):
self._additions = attributes["additions"]
if "assignee" in attributes: # pragma no branch
assert attributes["assignee"] is None or isinstance(attributes["assignee"], dict), attributes["assignee"]
self._assignee = None if attributes["assignee"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["assignee"], completed=False)
self._assignee = None if attributes["assignee"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["assignee"], completed=False)
if "base" in attributes: # pragma no branch
assert attributes["base"] is None or isinstance(attributes["base"], dict), attributes["base"]
self._base = None if attributes["base"] is None else github.PullRequestPart.PullRequestPart(self._requester, self._headers, attributes["base"], completed=False)
@@ -576,18 +576,3 @@ class PullRequest(github.GithubObject.CompletableGithubObject):
if "user" in attributes: # pragma no branch
assert attributes["user"] is None or isinstance(attributes["user"], dict), attributes["user"]
self._user = None if attributes["user"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["user"], completed=False)
+1 -16
View File
@@ -4,10 +4,10 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Michael Stead <michael.stead@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -213,18 +213,3 @@ class PullRequestComment(github.GithubObject.CompletableGithubObject):
if "user" in attributes: # pragma no branch
assert attributes["user"] is None or isinstance(attributes["user"], dict), attributes["user"]
self._user = None if attributes["user"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["user"], completed=False)
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# #
+1 -11
View File
@@ -4,8 +4,8 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -93,13 +93,3 @@ class PullRequestPart(github.GithubObject.NonCompletableGithubObject):
if "user" in attributes: # pragma no branch
assert attributes["user"] is None or isinstance(attributes["user"], dict), attributes["user"]
self._user = None if attributes["user"] is None else github.NamedUser.NamedUser(self._requester, self._headers, attributes["user"], completed=False)
+12 -3
View File
@@ -6,10 +6,11 @@
# Copyright 2012 Steve English <steve.english@navetas.com> #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Adrian Petrescu <adrian.petrescu@maluuba.com> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Mark Roddy <markroddy@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -838,20 +839,28 @@ class Repository(github.GithubObject.CompletableGithubObject):
)
return github.Commit.Commit(self._requester, headers, data, completed=True)
def get_commits(self, sha=github.GithubObject.NotSet, path=github.GithubObject.NotSet):
def get_commits(self, sha=github.GithubObject.NotSet, path=github.GithubObject.NotSet, since=github.GithubObject.NotSet, until=github.GithubObject.NotSet):
"""
:calls: `GET /repos/:owner/:repo/commits <http://developer.github.com/v3/repos/commits>`_
:param sha: string
:param path: string
:param since: datetime.datetime
:param until: datetime.datetime
:rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Commit.Commit`
"""
assert sha is github.GithubObject.NotSet or isinstance(sha, (str, unicode)), sha
assert path is github.GithubObject.NotSet or isinstance(path, (str, unicode)), path
assert since is github.GithubObject.NotSet or isinstance(since, datetime.datetime), since
assert until is github.GithubObject.NotSet or isinstance(until, datetime.datetime), until
url_parameters = dict()
if sha is not github.GithubObject.NotSet:
url_parameters["sha"] = sha
if path is not github.GithubObject.NotSet:
url_parameters["path"] = path
if since is not github.GithubObject.NotSet:
url_parameters["since"] = since.strftime("%Y-%m-%dT%H:%M:%SZ")
if until is not github.GithubObject.NotSet:
url_parameters["until"] = until.strftime("%Y-%m-%dT%H:%M:%SZ")
return github.PaginatedList.PaginatedList(
github.Commit.Commit,
self._requester,
@@ -1520,7 +1529,7 @@ class Repository(github.GithubObject.CompletableGithubObject):
def legacy_search_issues(self, state, keyword):
"""
:calls: `GET /legacy/issues/search/:owner/:repository/:state/:keyword <http://developer.github.com/v3/search>`_
:calls: `GET /legacy/issues/search/:owner/:repository/:state/:keyword <http://developer.github.com/v3/search/legacy>`_
:param state: "open" or "closed"
:param keyword: string
:rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Issue.Issue`
+1 -1
View File
@@ -4,10 +4,10 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Srijan Choudhary <srijan4@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+15 -7
View File
@@ -9,9 +9,11 @@
# Copyright 2012 Steve English <steve.english@navetas.com> #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Jonathan J Hunt <hunt@braincorporation.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Ed Jackson <ed.jackson@gmail.com> #
# Copyright 2013 Jonathan J Hunt <hunt@braincorporation.com> #
# Copyright 2013 Mark Roddy <markroddy@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
@@ -62,7 +64,7 @@ class Requester:
def resetConnectionClasses(cls):
cls.__httpConnectionClass = httplib.HTTPConnection
cls.__httpsConnectionClass = httplib.HTTPSConnection
#############################################################
# For Debug
@classmethod
@@ -106,10 +108,9 @@ class Requester:
'''
if not self.DEBUG_FLAG:
return
self._frameBuffer[self._frameCount][1:4] = [statusCode, responseHeader, data]
responseHeader[self.DEBUG_HEADER_KEY] = self._frameCount
def check_me(self, obj):
if self.DEBUG_FLAG and self.ON_CHECK_ME is not None:
@@ -122,6 +123,7 @@ class Requester:
def _initializeDebugFeature(self):
self._frameCount = 0
self._frameBuffer = []
#############################################################
def __init__(self, login_or_token, password, base_url, timeout, client_id, client_secret, user_agent, per_page):
@@ -152,7 +154,8 @@ class Requester:
self.__connectionClass = self.__httpConnectionClass
else:
assert False, "Unknown URL scheme"
self.rate_limiting = (5000, 5000)
self.rate_limiting = (-1, -1)
self.rate_limiting_resettime = 0
self.FIX_REPO_GET_GIT_REF = True
self.per_page = per_page
@@ -201,7 +204,10 @@ class Requester:
else:
if atLeastPython3 and isinstance(data, bytes): # pragma no branch (Covered by Issue142.testDecodeJson with Python 3)
data = data.decode("utf-8") # pragma no cover (Covered by Issue142.testDecodeJson with Python 3)
return json.loads(data)
try:
return json.loads(data)
except ValueError, e:
return {'data': data}
def requestJson(self, verb, url, parameters, input):
def encode(input):
@@ -248,6 +254,8 @@ class Requester:
if "x-ratelimit-remaining" in responseHeaders and "x-ratelimit-limit" in responseHeaders:
self.rate_limiting = (int(responseHeaders["x-ratelimit-remaining"]), int(responseHeaders["x-ratelimit-limit"]))
if "x-ratelimit-reset" in responseHeaders:
self.rate_limiting_resettime = int(responseHeaders["x-ratelimit-reset"])
if "x-oauth-scopes" in responseHeaders:
self.oauth_scopes = responseHeaders["x-oauth-scopes"].split(", ")
+1 -1
View File
@@ -4,9 +4,9 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
# #
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# #
+1
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2013 martinqt <m.ki2@laposte.net> #
# #
+16
View File
@@ -56,6 +56,22 @@ class Exceptions(Framework.TestCase): # To stay compatible with Python 2.6, we
)
self.assertTrue(raised)
def testNonJsonDataReturnedByGithub(self):
# Replay data was forged according to https://github.com/jacquev6/PyGithub/pull/182
raised = False
try:
self.g.get_user("jacquev6")
except github.GithubException, exception:
raised = True
self.assertEqual(exception.status, 503)
self.assertEqual(
exception.data,
{
"data": "<html><body><h1>503 Service Unavailable</h1>No server is available to handle this request.</body></html>",
}
)
self.assertTrue(raised)
def testUnknownObject(self):
raised = False
try:
+4 -11
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
@@ -249,29 +250,21 @@ class TestCase(BasicTestCase):
return
if obj._headers is None and frame == {}:
return
self.assertEqual(obj._headers, frame[2]);
self.assertEqual(obj._headers, frame[2])
def getFrameChecker(self):
return lambda requester, obj, frame: self.doCheckFrame(obj, frame)
def setUp(self):
BasicTestCase.setUp(self)
# Set up frame debugging
github.GithubObject.GithubObject.setCheckAfterInitFlag(True)
# Set up frame debugging
github.GithubObject.GithubObject.setCheckAfterInitFlag(True)
github.Requester.Requester.setDebugFlag(True)
github.Requester.Requester.setOnCheckMe(self.getFrameChecker())
self.g = github.Github(self.login, self.password)
def activateRecordMode(): # pragma no cover (Function useful only when recording new tests, not used during automated tests)
BasicTestCase.recordMode = True
+4 -4
View File
@@ -108,12 +108,12 @@ class Gist(Framework.TestCase):
self.assertFalse(self.gist.is_starred())
def testFork(self):
gist = self.g.get_gist("2729818") # Random gist
gist = self.g.get_gist("6296553") # Random gist
myGist = gist.create_fork()
self.assertEqual(myGist.id, "2729865")
self.assertEqual(myGist.id, "6296732")
self.assertEqual(myGist.fork_of, None) # WTF
sameGist = self.g.get_gist("2729865")
self.assertEqual(sameGist.fork_of.id, "2729818")
sameGist = self.g.get_gist("6296732")
self.assertEqual(sameGist.fork_of.id, "6296553")
def testDelete(self):
self.gist.delete()
+6
View File
@@ -128,3 +128,9 @@ class Github(Framework.TestCase):
def testGetUsersSince(self):
self.assertListKeyBegin(self.g.get_users(since=1000), lambda u: u.login, ["sbecker"])
def testGetRepos(self):
self.assertListKeyBegin(self.g.get_repos(), lambda r: r.name, ["grit", "merb-core", "rubinius", "god", "jsawesome", "jspec", "exception_logger", "ambition"])
def testGetReposSince(self):
self.assertListKeyBegin(self.g.get_repos(since=1000), lambda r: r.name, ["jquery-humanize-messages-plugin", "4slicer", "fixture-scenarios", "mongrel_proctitle", "rails-plugins"])
+2
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Stuart Glaser <stuglaser@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
@@ -54,6 +55,7 @@ class Issue(Framework.TestCase):
self.assertEqual(self.issue.updated_at, datetime.datetime(2012, 5, 26, 14, 59, 33))
self.assertEqual(self.issue.url, "https://api.github.com/repos/jacquev6/PyGithub/issues/28")
self.assertEqual(self.issue.user.login, "jacquev6")
self.assertEqual(self.issue.repository.name, "PyGithub")
def testEditWithoutParameters(self):
self.issue.edit()
+4
View File
@@ -109,6 +109,10 @@ class NamedUser(Framework.TestCase):
def testGetFollowing(self):
self.assertListKeyEqual(self.user.get_following(), lambda f: f.login, ["nvie", "schacon", "jamis", "chad", "unclebob", "dabrahams", "jnorthrup", "brugidou", "regisb", "walidk", "tanzilli", "fjardon", "r3c", "sdanzan", "vineus", "cjuniet", "gturri", "ant9000", "asquini", "claudyus", "jardon-u", "s-bernard", "kamaradclimber", "Lyloa"])
def testHasInFollowing(self):
nvie = self.g.get_user("nvie")
self.assertTrue(self.user.has_in_following(nvie))
def testGetOrgs(self):
self.assertListKeyEqual(self.user.get_orgs(), lambda o: o.login, ["BeaverSoftware"])
+29
View File
@@ -47,6 +47,35 @@ class PaginatedList(Framework.TestCase):
self.assertEqual(self.list[0].id, 4772349)
self.assertEqual(self.list[24].id, 4286936)
def testReversedIterationWithSinglePage(self):
r = self.list.reversed
self.assertEqual(r[0].id, 4286936)
self.assertEqual(r[1].id, 4317009)
def testReversedIterationWithMultiplePages(self):
r = self.list.reversed
self.assertEqual(r[0].id, 94898)
self.assertEqual(r[1].id, 104702)
self.assertEqual(r[13].id, 166211)
self.assertEqual(r[14].id, 166212)
self.assertEqual(r[15].id, 166214)
def testReversedIterationSupportsIterator(self):
r = self.list.reversed
for i in r:
self.assertEqual(i.id, 4286936)
return
self.fail("empty iterator")
def testGettingTheReversedListDoesNotModifyTheOriginalList(self):
self.assertEqual(self.list[0].id, 18345408)
self.assertEqual(self.list[30].id, 17916118)
r = self.list.reversed
self.assertEqual(self.list[0].id, 18345408)
self.assertEqual(self.list[30].id, 17916118)
self.assertEqual(r[0].id, 132373)
self.assertEqual(r[30].id, 543694)
def testIntIndexingInThirdPage(self):
self.assertEqual(self.list[50].id, 3911629)
self.assertEqual(self.list[74].id, 3605277)
+5
View File
@@ -4,6 +4,7 @@
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Ed Jackson <ed.jackson@gmail.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# #
# This file is part of PyGithub. http://jacquev6.github.com/PyGithub/ #
@@ -31,3 +32,7 @@ class RateLimiting(Framework.TestCase):
self.assertEqual(self.g.rate_limiting, (5000, 5000))
self.g.get_user("jacquev6")
self.assertEqual(self.g.rate_limiting, (4999, 5000))
self.assertEqual(self.g.rate_limiting_resettime, 1375802816)
def testResetTime(self):
self.assertEqual(self.g.rate_limiting_resettime, 1375802816)
@@ -0,0 +1,11 @@
https
GET
api.github.com
None
/users/jacquev6
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
null
503
[('status', '503 Servive Unavailable'), ('content-length', '104'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('etag', '"ca6a3702f840b6bff0bb1bca6be0337c"'), ('date', 'Sat, 02 Jun 2012 12:12:32 GMT'), ('content-type', 'application/json; charset=utf-8')]
<html><body><h1>503 Service Unavailable</h1>No server is available to handle this request.</body></html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -2,7 +2,7 @@ https
POST
api.github.com
None
/repos/jacquev6/PyGithub/hooks/257993/test
/repos/jacquev6/PyGithub/hooks/257993/tests
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
null
204
@@ -0,0 +1,11 @@
https
GET
api.github.com
None
/repos/jacquev6/PyGithub
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
null
200
[('status', '200 OK'), ('x-ratelimit-remaining', '4992'), ('content-length', '1129'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"5dc65a168cf4d957347ea04221cd5102"'), ('date', 'Sat, 26 May 2012 14:59:39 GMT'), ('content-type', 'application/json; charset=utf-8')]
{"clone_url":"https://github.com/jacquev6/PyGithub.git","has_downloads":true,"watchers":13,"updated_at":"2012-05-26T11:25:48Z","permissions":{"pull":true,"admin":true,"push":true},"homepage":"http://vincent-jacques.net/PyGithub","url":"https://api.github.com/repos/jacquev6/PyGithub","mirror_url":null,"has_wiki":false,"has_issues":true,"fork":false,"forks":2,"size":412,"private":false,"open_issues":15,"svn_url":"https://github.com/jacquev6/PyGithub","owner":{"url":"https://api.github.com/users/jacquev6","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","login":"jacquev6","id":327146,"avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png"},"name":"PyGithub","language":"Python","description":"Python library implementing the full Github API v3","ssh_url":"git@github.com:jacquev6/PyGithub.git","pushed_at":"2012-05-26T11:25:48Z","created_at":"2012-02-25T12:53:47Z","id":3544490,"git_url":"git://github.com/jacquev6/PyGithub.git","html_url":"https://github.com/jacquev6/PyGithub","full_name":"jacquev6/PyGithub"}
@@ -0,0 +1,22 @@
https
GET
api.github.com
None
/users/nvie
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
null
200
[('status', '200 OK'), ('x-ratelimit-remaining', '4996'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('access-control-allow-credentials', 'true'), ('vary', 'Accept, Authorization, Cookie, Accept-Encoding'), ('content-length', '1218'), ('server', 'GitHub.com'), ('last-modified', 'Wed, 21 Aug 2013 16:26:40 GMT'), ('x-ratelimit-limit', '5000'), ('etag', '"8e2b307f8fb4186bfb512febd7215fc8"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('date', 'Wed, 21 Aug 2013 17:20:44 GMT'), ('access-control-allow-origin', '*'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1377108637')]
{"login":"nvie","id":83844,"avatar_url":"https://2.gravatar.com/avatar/466ef7561a0b100dc5a1021959962d28?d=https%3A%2F%2Fidenticons.github.com%2Fe6d0513ce49cc06cb956251623cb8fd9.png","gravatar_id":"466ef7561a0b100dc5a1021959962d28","url":"https://api.github.com/users/nvie","html_url":"https://github.com/nvie","followers_url":"https://api.github.com/users/nvie/followers","following_url":"https://api.github.com/users/nvie/following{/other_user}","gists_url":"https://api.github.com/users/nvie/gists{/gist_id}","starred_url":"https://api.github.com/users/nvie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nvie/subscriptions","organizations_url":"https://api.github.com/users/nvie/orgs","repos_url":"https://api.github.com/users/nvie/repos","events_url":"https://api.github.com/users/nvie/events{/privacy}","received_events_url":"https://api.github.com/users/nvie/received_events","type":"User","name":"Vincent Driessen","company":"3rd Cloud","blog":"http://nvie.com","location":"Netherlands","email":"vincent@3rdcloud.com","hireable":true,"bio":null,"public_repos":86,"followers":530,"following":45,"created_at":"2009-05-12T21:19:38Z","updated_at":"2013-08-21T16:26:40Z","public_gists":38}
https
GET
api.github.com
None
/users/jacquev6/following/nvie
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
null
204
[('status', '204 No Content'), ('x-ratelimit-remaining', '4995'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('vary', 'Accept-Encoding'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('access-control-allow-credentials', 'true'), ('date', 'Wed, 21 Aug 2013 17:20:48 GMT'), ('access-control-allow-origin', '*'), ('x-ratelimit-reset', '1377108637')]
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,3 +1,14 @@
https
GET
api.github.com
None
/rate_limit
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
null
200
[('status', '200 OK'), ('x-ratelimit-remaining', '5000'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('cache-control', 'max-age=0, private, must-revalidate'), ('vary', 'Accept-Encoding'), ('content-length', '59'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('etag', '"47ba6b48c8b2986ec54f249b51b0a9ec"'), ('access-control-allow-credentials', 'true'), ('date', 'Tue, 06 Aug 2013 14:52:12 GMT'), ('x-oauth-scopes', 'user, public_repo, repo, gist'), ('content-type', 'application/json; charset=utf-8'), ('access-control-allow-origin', '*'), ('x-ratelimit-reset', '1375802816')]
{"rate":{"limit":5000,"remaining":5000,"reset":1375802816}}
https
GET
api.github.com
@@ -6,6 +17,6 @@ None
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
null
200
[('status', '200 OK'), ('x-ratelimit-remaining', '4999'), ('content-length', '801'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"8cd01ddcd0adee5501abc607e6a640b0"'), ('date', 'Mon, 21 May 2012 11:08:21 GMT'), ('content-type', 'application/json; charset=utf-8')]
{"total_private_repos":5,"public_gists":1,"type":"User","owned_private_repos":5,"private_gists":5,"company":"Criteo","url":"https://api.github.com/users/jacquev6","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","plan":{"private_repos":5,"collaborators":1,"name":"micro","space":614400},"followers":13,"blog":"http://vincent-jacques.net","collaborators":0,"login":"jacquev6","email":"vincent@vincent-jacques.net","disk_usage":16812,"public_repos":11,"html_url":"https://github.com/jacquev6","name":"Vincent Jacques","hireable":false,"created_at":"2010-07-09T06:10:06Z","location":"Paris, France","id":327146,"following":24,"bio":""}
[('status', '200 OK'), ('x-ratelimit-remaining', '4999'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('access-control-allow-credentials', 'true'), ('vary', 'Accept, Authorization, Cookie, Accept-Encoding'), ('content-length', '1293'), ('server', 'GitHub.com'), ('access-control-allow-origin', '*'), ('last-modified', 'Mon, 05 Aug 2013 07:28:42 GMT'), ('x-ratelimit-limit', '5000'), ('etag', '"7d9b8600b27332ec98f57ee9e18639e9"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('date', 'Tue, 06 Aug 2013 14:52:12 GMT'), ('x-oauth-scopes', 'user, public_repo, repo, gist'), ('content-type', 'application/json; charset=utf-8'), ('x-accepted-oauth-scopes', 'user, user:email, user:follow, site_admin'), ('x-ratelimit-reset', '1375802816')]
{"login":"jacquev6","id":327146,"avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","url":"https://api.github.com/users/jacquev6","html_url":"https://github.com/jacquev6","followers_url":"https://api.github.com/users/jacquev6/followers","following_url":"https://api.github.com/users/jacquev6/following{/other_user}","gists_url":"https://api.github.com/users/jacquev6/gists{/gist_id}","starred_url":"https://api.github.com/users/jacquev6/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacquev6/subscriptions","organizations_url":"https://api.github.com/users/jacquev6/orgs","repos_url":"https://api.github.com/users/jacquev6/repos","events_url":"https://api.github.com/users/jacquev6/events{/privacy}","received_events_url":"https://api.github.com/users/jacquev6/received_events","type":"User","name":"Vincent Jacques","company":"","blog":"http://vincent-jacques.net","location":"Paris, France","email":"vincent@vincent-jacques.net","hireable":false,"bio":"","public_repos":16,"followers":27,"following":39,"created_at":"2010-07-09T06:10:06Z","updated_at":"2013-08-05T07:28:42Z","public_gists":3}
+10
View File
@@ -0,0 +1,10 @@
https
GET
api.github.com
None
/rate_limit
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
null
200
[('status', '200 OK'), ('x-ratelimit-remaining', '5000'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('cache-control', 'max-age=0, private, must-revalidate'), ('vary', 'Accept-Encoding'), ('content-length', '59'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('etag', '"47ba6b48c8b2986ec54f249b51b0a9ec"'), ('access-control-allow-credentials', 'true'), ('date', 'Tue, 06 Aug 2013 14:52:12 GMT'), ('x-oauth-scopes', 'user, public_repo, repo, gist'), ('content-type', 'application/json; charset=utf-8'), ('access-control-allow-origin', '*'), ('x-ratelimit-reset', '1375802816')]
{"rate":{"limit":5000,"remaining":5000,"reset":1375802816}}
File diff suppressed because one or more lines are too long
+3
View File
@@ -272,6 +272,9 @@ class Repository(Framework.TestCase):
def testGetCommitsWithArguments(self):
self.assertListKeyEqual(self.repo.get_commits("topic/RewriteWithGeneratedCode", "codegen/GenerateCode.py"), lambda c: c.sha, ["de386d5dc9cf103c90c4128eeca0e6abdd382065", "5b44982f6111bff2454243869df2e1c3086ccbba", "d6835ff949141957a733c8ddfa147026515ae493", "075d3d961d4614a2a0835d5583248adfc0687a7d", "8956796e7f462a49f499eac52fab901cdb59abdb", "283da5e7de6a4a3b6aaae7045909d70b643ad380", "d631e83b7901b0a0b6061b361130700a79505319"])
def testGetCommitsWithSinceUntil(self):
self.assertListKeyEqual(self.repo.get_commits(since=datetime.datetime(2013, 3, 1), until=datetime.datetime(2013, 3, 31)), lambda c: c.sha, ['db5560bd658b5d8057a864f7037ace4d5f618f1b', 'f266fed520fea4f683caabe0b38e1f758cfc5cff', 'dff094650011398fd8f0a57bf2668a066fb2cbcb', 'c1d747a9133a1c6cae1f0e11105a5f490f65fda6', '0bc368973acfb50a531329b6c196ba92e0a81890', '7b3e4c15ed6182963d66ffa9f0522acd0765275c', '4df3a7eb47888f38c4c6dae50573f030a0a3f1e1', 'e0db8cad4ec01c65e5e0eb50e11765e425e88ef9', '1c47be4e895b823baf907b25c647e43ab63c16dd', '8a9afbb1aa36c6ba04142c6e6c1cfbd7de982a6a', '1c67359a318f05e50bf457818e1983ce95aa5946', '1d18bd66f3a4a4225435bd38df04b8a227b5e821', 'b9d71fa787a2ffb99b6631e4bd6df932a4d4adbb', 'f5d8e221d116b74a200d87afca32247f01204ba1', 'dc96fef052f2b5c6adb34da65169e8df3f35f611', 'c85af79db11ed1d2f93261ea4069a23ff1709125', '0dd1adb4f06f45d554d12083b312fcdb6f6be8d1', 'b7e4000450e89b8c6e947e3a1e52fb06da7c9621', '1d9ad14fa918866c418067e774f65cede8e38682', '1bb05fef01d0a040cb2b931a4d44392784a2f0c1', 'd9b29851ddccc907f71f1ae662e57f2cd7c7dc71', 'f962bc71fee609cd54fe69c956c8b81703d2c19a', '7a9c0b916c632be8d6a65bc1b6f558508f04bb22', '82ce7b1ee30d308b48bdac6d8737dbca70500462', '1e99e7d5b21c71bf68cc5cc21faec30ee603b8b8', 'a397fac6db9f87a903ec3ede9643cb2b4224ed82', '109495175e926731703a55cafd8b542a07366513', 'da6bbdb69485fc3256030d8296589d4c2fb5df21', '34c18342dcce9697abc6f522c3506485202e6e7e', 'ee29deddd27480401db484733ecde9e7b1df5eda', '0901df1a2bed3f993cfe6e0d4cff5923bbf6ce32', 'edcf40bc7f25d1aff5c404406fbb37ad1bcf691e', 'f25c54e1d4eefb11c18f3de85270a4b19edea3ce', '23d668f11bdd806a871e0979bf5295d001f66ef2', '50a243671f1fa139cb1186c4a44c1e96b8cd5749', '6a3a384fd0decac1203db6c2bddc58039b0390bc', '82f5b4c61f86ae8c7cc85a31cb1a31180eeae32f', '6ac783974d3985dd0c162c1e8d1150615cc0082e', '0f9bb5d9fd2dcfbf03f094362e86323c9ef915e6', 'e25a6a49d1ab1a10c84db9b6722a6186ff6dfcbd', '4f1780f427eba400cbc06897e69eda0ecdecd887', '28648a51a15e430b85d6fe8f2514e1cb06bc76b8', 'a39f421ca24bd7aae984f8703159c7e30798a121', '86fe370b97b62548317cb35bc02ece3fabb7fa03', '03a256a4052cacea998d8205a83d5b5465f31e18', '9e6b086c2db5e4884484a04934f6f2e53e3f441b', '0ddb34d987b5a03813fdfa2fac13c933834a4804'])
def testGetDownloads(self):
self.assertListKeyEqual(self.repo.get_downloads(), lambda d: d.id, [245143])