Skip to content

Commit 748b320

Browse files
committed
Merge 'services/pull_requests'
2 parents 8f1b051 + 24a3ed5 commit 748b320

File tree

16 files changed

+649
-67
lines changed

16 files changed

+649
-67
lines changed

docs/pull_requests.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
.. _Pull Requests service:
2+
3+
Pull Requests service
4+
=====================
5+
6+
**Example**::
7+
8+
from pygithub3 import Github
9+
10+
gh = Github(user='octocat', repo='sample')
11+
12+
pull_requests = gh.pull_requests.list().all()
13+
pull_request_commits = gh.pull_requests.list_commits(2512).all()
14+
15+
Pull Requests
16+
-------------
17+
18+
.. autoclass:: pygithub3.services.pull_requests.PullRequests
19+
:members:
20+
21+
.. attribute:: comments
22+
23+
:ref:`Pull Request Comments service`
24+
25+
26+
.. _Pull Request Comments service:
27+
28+
Pull Request Comments
29+
---------------------
30+
31+
.. autoclass:: pygithub3.services.pull_requests.Comments
32+
:members:
33+
34+
.. _github pullrequests doc: http://developer.github.com/v3/pulls
35+
.. _github pullrequests comments doc: http://developer.github.com/v3/pulls/comments

docs/services.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,6 @@ List of services
7373
repos
7474
gists
7575
git_data
76+
pull_requests
7677

7778
.. _mimetypes: http://developer.github.com/v3/mime

pygithub3/core/errors.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
#!/usr/bin/env python
22
# -*- encoding: utf-8 -*-
33

4-
try:
5-
import simplejson as json
6-
except ImportError:
7-
import json
8-
4+
from pygithub3.core.utils import json
95
from pygithub3.exceptions import NotFound, BadRequest, UnprocessableEntity
106

117

pygithub3/core/utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
# -*- encoding: utf-8 -*-
33
""" Utils to support python 2.6 compatibility """
44

5+
try:
6+
import simplejson as json
7+
except ImportError:
8+
import json
9+
510
from collections import MutableMapping
611

712

pygithub3/exceptions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class InvalidBodySchema(Exception):
88
pass
99

1010

11-
class DoesNotExists(Exception):
11+
class RequestDoesNotExist(Exception):
1212
""" Raised when `Request` factory can't find the subclass """
1313
pass
1414

@@ -37,6 +37,6 @@ class UnprocessableEntity(Exception):
3737
class NotFound(Exception):
3838
""" Raised when server response is 404
3939
40-
Catched with a pygithub3-exception to `services.base.Service._bool` method
40+
Caught with a pygithub3-exception to `services.base.Service._bool` method
4141
"""
4242
pass

pygithub3/github.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ def __init__(self, **config):
1818
from pygithub3.services.repos import Repo
1919
from pygithub3.services.gists import Gist
2020
from pygithub3.services.git_data import GitData
21+
from pygithub3.services.pull_requests import PullRequests
2122
self._users = User(**config)
2223
self._repos = Repo(**config)
2324
self._gists = Gist(**config)
2425
self._git_data = GitData(**config)
26+
self._pull_requests = PullRequests(**config)
2527

2628
@property
2729
def remaining_requests(self):
@@ -56,3 +58,10 @@ def git_data(self):
5658
:ref:`Git Data service <Git Data service>`
5759
"""
5860
return self._git_data
61+
62+
@property
63+
def pull_requests(self):
64+
"""
65+
:ref:`Pull Requests service <Pull Requests service>`
66+
"""
67+
return self._pull_requests

pygithub3/requests/base.py

Lines changed: 40 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,17 @@
22
# -*- encoding: utf-8 -*-
33

44
import re
5-
try:
6-
import simplejson as json
7-
except ImportError:
8-
import json
95

10-
from pygithub3.exceptions import (DoesNotExists, UriInvalid, ValidationError,
11-
InvalidBodySchema)
6+
from pygithub3.core.utils import import_module, json
7+
from pygithub3.exceptions import (RequestDoesNotExist, UriInvalid,
8+
ValidationError, InvalidBodySchema)
129
from pygithub3.resources.base import Raw
13-
from pygithub3.core.utils import import_module
1410

1511
ABS_IMPORT_PREFIX = 'pygithub3.requests'
1612

1713

1814
class Body(object):
15+
""" Input's request handler """
1916

2017
def __init__(self, content, schema, required):
2118
self.content = content
@@ -28,6 +25,7 @@ def dumps(self):
2825
return json.dumps(self.parse())
2926

3027
def parse(self):
28+
""" Parse body with schema-required rules """
3129
if not hasattr(self.content, 'items'):
3230
raise ValidationError("'%s' needs a content dictionary"
3331
% self.__class__.__name__)
@@ -44,29 +42,42 @@ def parse(self):
4442

4543

4644
class Request(object):
47-
""" """
4845

4946
uri = ''
5047
resource = Raw
5148
body_schema = {}
5249

5350
def __init__(self, **kwargs):
54-
""" """
55-
self.body = kwargs.pop('body', None)
51+
self.body = kwargs.pop('body', {})
5652
self.args = kwargs
5753
self.clean()
5854

55+
def __getattr__(self, name):
56+
return self.args.get(name)
57+
58+
def __str__(self):
59+
return self.populate_uri()
60+
61+
def populate_uri(self):
62+
try:
63+
populated_uri = self.uri.format(**self.args)
64+
except KeyError:
65+
raise ValidationError(
66+
"'%s' request wasn't be able to populate the uri '%s' with "
67+
"'%s' args" % (self.__class__.__name__, self.uri, self.args))
68+
return str(populated_uri).strip('/')
69+
5970
def clean(self):
6071
self.uri = self.clean_uri() or self.uri
61-
self.body = Body(self.clean_body(), **self.clean_valid_body())
72+
self.body = Body(self.clean_body(), **self._clean_valid_body())
6273

6374
def clean_body(self):
6475
return self.body
6576

6677
def clean_uri(self):
6778
return None
6879

69-
def clean_valid_body(self):
80+
def _clean_valid_body(self):
7081
schema = set(self.body_schema.get('schema', ()))
7182
required = set(self.body_schema.get('required', ()))
7283
if not required.issubset(schema):
@@ -76,21 +87,6 @@ def clean_valid_body(self):
7687
self.__class__.__name__, required, schema))
7788
return dict(schema=schema, required=required)
7889

79-
def __getattr__(self, name):
80-
return self.args.get(name)
81-
82-
def __str__(self):
83-
return self.populate_uri()
84-
85-
def populate_uri(self):
86-
try:
87-
populated_uri = self.uri.format(**self.args)
88-
except KeyError:
89-
raise ValidationError(
90-
"'%s' request wasn't be able to populate the uri '%s' with "
91-
"'%s' args" % (self.__class__.__name__, self.uri, self.args))
92-
return str(populated_uri).strip('/')
93-
9490
def get_body(self):
9591
return self.body.dumps()
9692

@@ -110,28 +106,21 @@ def wrapper(self, request_uri, **kwargs):
110106
return func(self, request_uri.lower(), **kwargs)
111107
return wrapper
112108

113-
def dispatch(func):
114-
def wrapper(self, request_uri, **kwargs):
115-
module_chunk, s, request_chunk = request_uri.rpartition('.')
116-
request_chunk = request_chunk.capitalize()
117-
try:
118-
# TODO: CamelCase and under_score support, now only Class Name
119-
module = import_module('%s.%s'
120-
% (ABS_IMPORT_PREFIX, module_chunk))
121-
request = getattr(module, request_chunk)
122-
except ImportError:
123-
raise DoesNotExists("'%s' module does not exists"
124-
% module_chunk)
125-
except AttributeError:
126-
raise DoesNotExists(
127-
"'%s' request doesn't exists into '%s' module"
128-
% (request_chunk, module_chunk))
129-
return func(self, request, **kwargs)
130-
return wrapper
131-
132109
@validate
133-
@dispatch
134-
def __call__(self, request='', **kwargs):
135-
request = request(**kwargs)
136-
assert isinstance(request, Request)
137-
return request
110+
def __call__(self, request_uri, **kwargs):
111+
module_chunk, s, request_chunk = request_uri.rpartition('.')
112+
request_chunk = request_chunk.capitalize()
113+
try:
114+
# TODO: CamelCase and under_score support, now only Class Name
115+
module = import_module('%s.%s' % (ABS_IMPORT_PREFIX, module_chunk))
116+
request_class = getattr(module, request_chunk)
117+
request = request_class(**kwargs)
118+
assert isinstance(request, Request)
119+
return request
120+
except ImportError:
121+
raise RequestDoesNotExist("'%s' module does not exist"
122+
% module_chunk)
123+
except AttributeError:
124+
raise RequestDoesNotExist("'%s' request does not exist in "
125+
"'%s' module" % (request_chunk,
126+
module_chunk))
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# -*- encoding: utf-8 -*-
2+
3+
from pygithub3.requests.base import Request, ValidationError
4+
from pygithub3.resources.pull_requests import PullRequest, File
5+
from pygithub3.resources.repos import Commit
6+
7+
8+
class List(Request):
9+
uri = 'repos/{user}/{repo}/pulls'
10+
resource = PullRequest
11+
12+
13+
class Get(Request):
14+
uri = 'repos/{user}/{repo}/pulls/{number}'
15+
resource = PullRequest
16+
17+
18+
class Create(Request):
19+
uri = 'repos/{user}/{repo}/pulls'
20+
resource = PullRequest
21+
body_schema = {
22+
'schema': ('title', 'body', 'base', 'head', 'issue'),
23+
'required': ('base', 'head'),
24+
}
25+
26+
def clean_body(self):
27+
if (not ('title' in self.body and 'body' in self.body) and
28+
not 'issue' in self.body):
29+
raise ValidationError('pull request creation requires either an '
30+
'issue number or a title and body')
31+
return self.body
32+
33+
class Update(Request):
34+
uri = 'repos/{user}/{repo}/pulls/{number}'
35+
resource = PullRequest
36+
body_schema = {
37+
'schema': ('title', 'body', 'state'),
38+
'required': (),
39+
}
40+
41+
def clean_body(self):
42+
if ('state' in self.body and
43+
self.body['state'] not in ['open', 'closed']):
44+
raise ValidationError('If a state is specified, it must be one '
45+
'of "open" or "closed"')
46+
return self.body
47+
48+
49+
class List_commits(Request):
50+
uri = 'repos/{user}/{repo}/pulls/{number}/commits'
51+
resource = Commit
52+
53+
54+
class List_files(Request):
55+
uri = 'repos/{user}/{repo}/pulls/{number}/files'
56+
resource = File
57+
58+
59+
class Is_merged(Request):
60+
uri = 'repos/{user}/{repo}/pulls/{number}/merge'
61+
62+
63+
class Merge(Request):
64+
uri = 'repos/{user}/{repo}/pulls/{number}/merge'
65+
body_schema = {
66+
'schema': ('commit_message',),
67+
'required': (),
68+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# -*- encoding: utf-8 -*-
2+
3+
from pygithub3.requests.base import Request, ValidationError
4+
from pygithub3.resources.pull_requests import Comment
5+
6+
7+
class List(Request):
8+
uri = 'repos/{user}/{repo}/pulls/{number}/comments'
9+
resource = Comment
10+
11+
12+
class Get(Request):
13+
uri = 'repos/{user}/{repo}/pulls/comments/{number}'
14+
resource = Comment
15+
16+
17+
class Create(Request):
18+
uri = 'repos/{user}/{repo}/pulls/{number}/comments'
19+
resource = Comment
20+
body_schema = {
21+
'schema': ('body', 'commit_id', 'path', 'position', 'in_reply_to'),
22+
'required': ('body',),
23+
}
24+
25+
def clean_body(self):
26+
if (not ('commit_id' in self.body and
27+
'path' in self.body and
28+
'position' in self.body) and
29+
not 'in_reply_to' in self.body):
30+
raise ValidationError('supply either in_reply_to or commit_id, '
31+
'path, and position')
32+
return self.body
33+
34+
35+
class Edit(Request):
36+
uri = 'repos/{user}/{repo}/pulls/comments/{number}'
37+
resource = Comment
38+
body_schema = {
39+
'schema': ('body',),
40+
'required': ('body',),
41+
}
42+
43+
44+
class Delete(Request):
45+
uri = 'repos/{user}/{repo}/pulls/comments/{number}'
46+
resource = Comment

pygithub3/resources/base.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
#!/usr/bin/env python
22
# -*- encoding: utf-8 -*-
33

4-
try:
5-
import simplejson as json
6-
except ImportError:
7-
import json
4+
from pygithub3.core.utils import json
85

96

107
class Resource(object):

0 commit comments

Comments
 (0)