-
Notifications
You must be signed in to change notification settings - Fork 406
Added Collaborator, Contributor and Repository.collaborators(affiliation) #731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added Collaborator, Contributor and Repository.collaborators(affiliation) #731
Conversation
@sigmavirus24 any chance this gets looked at? |
@AndreasBackx I'd be happy to give this a look. Would you mind rebasing this to merge cleanly? |
I will, I'm currently not at my apartment for a few days so I might not be able to get to it this week. I'll rebase when I get back to my apartment, I hope to be back in a couple days. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple comments inline. Also I'd like to know what the right method is to go from having a Collaborator
object and turning it into a User
object.
@@ -524,17 +524,24 @@ def code_frequency(self, number=-1, etag=None): | |||
url = self._build_url('stats', 'code_frequency', base_url=self._api) | |||
return self._iter(int(number), url, list, etag=etag) | |||
|
|||
def collaborators(self, number=-1, etag=None): | |||
def collaborators(self, affiliation='all', number=-1, etag=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The affiliations parameter should be documented here.
github3/repos/repo.py
Outdated
""" | ||
url = self._build_url('collaborators', base_url=self._api) | ||
return self._iter(int(number), url, users.ShortUser, etag=etag) | ||
affiliations = {'outside', 'direct', 'all'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a static list, not sure it belongs defined in this function or if it should be defined somewhere more global. That's likely a project preference thing, I defer to @sigmavirus24 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eh. I've waffled on this before. I think we do something similar in other places. I've wondered about having a github3.constants
or (github3._constants
) but it never felt important enough, honestly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also toyed with some decorators that would do strong validation of the parameters and what's passed in to the function but that turned out to be way too much work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can create an enum Affiliation
perhaps with uppercase choices for each: Affiliation.OUTSIDE
. You can then do list(Affiliation)
for a list of all of them (though it'll give a list of enums, not their values). Maybe something along those lines could be adopted for other stuff as well. I don't really mind here. Tell me what to do for the constants here, and it'll get done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need to tackle this @AndreasBackx. I think this is a murky corner for a library that supports Py2 and Py3. If we were Py3 only, I'd go whole-hog on using an Enum. Relying on the enum34
backport, however, has its own issues, I've found, and isn't worth the headache for end users right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, I've been working exclusively in Python 3 so I've been forgetting about the Python 2 support as of late. Are there any plans to drop Python 2 support in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing firm. Maybe later this year. Maybe next year.
github3/repos/users.py
Outdated
This represents a user as a collaborator of a :class:`Repository`. | ||
This adds permission information of the user to the repository. | ||
|
||
.. versionadded:: 1.0.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This version is a bit behind now.
github3/repos/users.py
Outdated
@@ -0,0 +1,33 @@ | |||
from ..users import _User |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there reason to not just put these classes in github3.users
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason at all, preference perhaps. It'll get changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait, now that I think about it. The reason I put it in github3.repos.users
instead of github3.users
is because I assumed that was implied in issue #670. As a collaborator's endpoint is /repos/:owner/:repo/collaborators
. They belong to the repo so I thought it would be good to put those in github3.repos.users
instead. Regardless though, tell me what you think is best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's precedence for both decisions. I think we already have Contributor
in github3.users
so moving Collaborator
in there too probably wouldn't hurt.
github3/repos/repo.py
Outdated
""" | ||
url = self._build_url('collaborators', base_url=self._api) | ||
return self._iter(int(number), url, users.ShortUser, etag=etag) | ||
affiliations = {'outside', 'direct', 'all'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eh. I've waffled on this before. I think we do something similar in other places. I've wondered about having a github3.constants
or (github3._constants
) but it never felt important enough, honestly.
github3/repos/repo.py
Outdated
""" | ||
url = self._build_url('collaborators', base_url=self._api) | ||
return self._iter(int(number), url, users.ShortUser, etag=etag) | ||
affiliations = {'outside', 'direct', 'all'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also toyed with some decorators that would do strong validation of the parameters and what's passed in to the function but that turned out to be way too much work.
github3/repos/repo.py
Outdated
"'direct', or 'all' (default 'all')." | ||
) | ||
params = {'affiliation': affiliation} | ||
return self._iter(int(number), url, Collaborator, params, etag=etag) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think as a rule we've switched to importing modules and not classes, so these shouldn't be the exception.
github3/repos/repo.py
Outdated
affiliations = {'outside', 'direct', 'all'} | ||
if affiliation not in affiliations: | ||
raise ValueError( | ||
"Invalid affiliation parameter passed, must be 'outside', " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should format the given affiliation into this to make it easier for debugging. Perhaps:
("Invalid affiliation value {!r} parameter passed, must be 'outside',"
"'direct', or 'all' (defaults to 'all').").format(affiliation)
tests/unit/test_repos_repo.py
Outdated
) | ||
|
||
def test_collaborators_valid_affiliation(self): | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we're not great at this elsewhere in the tests, but I'm hoping to get our doc-strings cleaned up soon. I tried to do so in the code itself. I'm going to target the tests next and it'd be good to do less work 😉
Could you substitute something like
"""Verify we can list collaborator with a valid affiliation.
Let's ensure that our affiliation validation works.
"""
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a mistake on my end. I usually follow the same principle.
Gave this a review pass as well. There's no rush to fix it up. This looks really close to perfect. Thanks @AndreasBackx for putting the work into doing this. 🎉 |
Alright, I've looked over the comments and I'll fix what needs to be fixed and I've replied to your questions. I'll try to get to it the coming days. Thanks for taking the time to review the PR. |
Oh, and regarding how |
I'm rebasing right now and see that Contributor has the attribute A User has got: self.followers_count = user['followers'] And the Contributor has got: class Contributor(_User):
"""Object for the specialized representation of a contributor.
When retrieving a repository's contributors, GitHub returns the same
information as a :class:`~github3.users.ShortUser` with an additional
attribute:
.. versionadded:: 1.0.0
This class was added in version 1.0.0
.. attribute:: contributions_count
The number of contributions a contributor has made to the repository
"""
class_name = 'Contributor'
def _update_attributes(self, contributor):
super(Contributor, self)._update_attributes(contributor)
self.contributions = contributor['contributions'] Should it become: self.contributions_count = contributor['contributions'] I thought I'd post it here and include it in the PR perhaps, it seems a bit silly to make a new PR/issue just for this. |
15af1b9
to
ff8501a
Compare
…ion). See sigmavirus24#730 for some background information. Note that I have currently put the named parameter `affiliation` at the front of the arguments in `Repository.collaborators`. I did this to be in line with the other similar iterators. This can be moved to the back, but I assume some backwards-incompatible changes are fine for 1.0.0? This uses separate classes for the specific User object uses as I understood the idea was from sigmavirus24#670.
ff8501a
to
17de8b8
Compare
I've rebased the PR following your feedback. I haven't changed I've added the ability to refresh the I had to update the cassette Let me know if I missed something. PS: The AppVeyor build seems to use the old commit, could someone run the latest? I assume Travis is running as I am typing this, but I can't check as it seems to be set to private (which I assume is in case of secrets leaking?). I tested everything successfully locally. |
It should be |
Reverted Repository_collaborators.json, as the base64 in it still contained the wrong URLs for the integration tests. They need to be regenerated by someone who has push access to the repository.
Let me try closing and re-opening this to trigger builds. Travis was broken so let's see if this fixes AppVeyor too. |
I've reverted I've also found another "bug" as you will in the tox config: envlist = py{27,34,35,36,py},py{27,34,36}-flake8,docstrings The envlist mentions a |
I re-recorded the cassette and pushed it to your branch. @AndreasBackx can you send another PR to add that environment to our tox.ini? |
All feedback seems to have been addressed. Thanks for reviewing this
I pushed some extra changes here as I noticed some things I didn't quite like about the docstrings. |
🎉 Thanks @AndreasBackx! |
Regarding the environment change in PS: I accidentally checked |
You can change And don't worry about checking in the old cassette. It's all sorted 😄 |
Will do. I know, I saw the diff which is when I realised that I had accidentally checked it in. |
This also requires us to be slightly more explicit with our Travis configuration. See discussion on gh-731.
See #730 for some background information. This still fails 1 test because the cassette
Repository_collaborators.json
needs to be updated with the permissions as it somehow does not contain that information. The GitHub API does say that it should be there, but the recording is from 2014 so perhaps it wasn't returned back then.Note that I have currently put the named parameter
affiliation
at the front of the arguments inRepository.collaborators
. I did this to be in line with the other similar iterators. This can be moved to the back, but I assume some backwards-incompatible changes are fine for 1.0.0?This uses separate classes for the specific User object uses as I understood the idea was from #670.