From 2c77cfad5626264f7a511ee8489ceb3315f0abae Mon Sep 17 00:00:00 2001 From: MeggyCal Date: Wed, 24 Mar 2021 11:30:01 +0100 Subject: [PATCH] Adjust to Github API changes regarding emails (#1890) Handle AuthenticatedUser.get_emails() correctly with the GitHub API changes. Fixes #1852 --- github/AuthenticatedUser.py | 10 ++++++---- github/AuthenticatedUser.pyi | 10 ++++++++-- tests/AuthenticatedUser.py | 10 +++++++--- tests/ReplayData/AuthenticatedUser.testEmails.txt | 12 ++++++------ 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/github/AuthenticatedUser.py b/github/AuthenticatedUser.py index 86206b72..5f645ac2 100644 --- a/github/AuthenticatedUser.py +++ b/github/AuthenticatedUser.py @@ -40,6 +40,7 @@ ################################################################################ import datetime +from collections import namedtuple import github.Authorization import github.Event @@ -373,7 +374,7 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): :rtype: None """ assert all(isinstance(element, str) for element in emails), emails - post_parameters = emails + post_parameters = {"emails": emails} headers, data = self._requester.requestJsonAndCheck( "POST", "/user/emails", input=post_parameters ) @@ -763,10 +764,11 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): def get_emails(self): """ :calls: `GET /user/emails `_ - :rtype: list of string + :rtype: list of namedtuples with members email, primary, verified and visibility """ headers, data = self._requester.requestJsonAndCheck("GET", "/user/emails") - return data + itemdata = namedtuple("EmailData", data[0].keys()) + return [itemdata._make(item.values()) for item in data] def get_events(self): """ @@ -1189,7 +1191,7 @@ class AuthenticatedUser(github.GithubObject.CompletableGithubObject): :rtype: None """ assert all(isinstance(element, str) for element in emails), emails - post_parameters = emails + post_parameters = {"emails": emails} headers, data = self._requester.requestJsonAndCheck( "DELETE", "/user/emails", input=post_parameters ) diff --git a/github/AuthenticatedUser.pyi b/github/AuthenticatedUser.pyi index 6e8c2c93..b6832b48 100644 --- a/github/AuthenticatedUser.pyi +++ b/github/AuthenticatedUser.pyi @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union, NamedTuple from github.Authorization import Authorization from github.Event import Event @@ -20,6 +20,12 @@ from github.Repository import Repository from github.Team import Team from github.UserKey import UserKey +class EmailData(NamedTuple): + email: str + primary: bool + verified: bool + visibility: str + class AuthenticatedUser(CompletableGithubObject): def __repr__(self) -> str: ... def _initAttributes(self) -> None: ... @@ -108,7 +114,7 @@ class AuthenticatedUser(CompletableGithubObject): def following_url(self) -> str: ... def get_authorization(self, id: int) -> Authorization: ... def get_authorizations(self) -> PaginatedList[Authorization]: ... - def get_emails(self) -> List[str]: ... + def get_emails(self) -> List[EmailData]: ... def get_events(self) -> PaginatedList[Event]: ... def get_followers(self) -> PaginatedList[NamedUser]: ... def get_following(self) -> PaginatedList[NamedUser]: ... diff --git a/tests/AuthenticatedUser.py b/tests/AuthenticatedUser.py index 79e10528..ac32251c 100644 --- a/tests/AuthenticatedUser.py +++ b/tests/AuthenticatedUser.py @@ -99,13 +99,17 @@ class AuthenticatedUser(Framework.TestCase): self.assertEqual(self.user.bio, "Bio edited by PyGithub") def testEmails(self): + emails = self.user.get_emails() self.assertEqual( - self.user.get_emails(), + [item.email for item in emails], ["vincent@vincent-jacques.net", "github.com@vincent-jacques.net"], ) + self.assertTrue(emails[0].primary) + self.assertTrue(emails[0].verified) + self.assertEqual(emails[0].visibility, "private") self.user.add_to_emails("1@foobar.com", "2@foobar.com") self.assertEqual( - self.user.get_emails(), + [item.email for item in self.user.get_emails()], [ "vincent@vincent-jacques.net", "1@foobar.com", @@ -115,7 +119,7 @@ class AuthenticatedUser(Framework.TestCase): ) self.user.remove_from_emails("1@foobar.com", "2@foobar.com") self.assertEqual( - self.user.get_emails(), + [item.email for item in self.user.get_emails()], ["vincent@vincent-jacques.net", "github.com@vincent-jacques.net"], ) diff --git a/tests/ReplayData/AuthenticatedUser.testEmails.txt b/tests/ReplayData/AuthenticatedUser.testEmails.txt index 6b3a9cb3..22f9c286 100644 --- a/tests/ReplayData/AuthenticatedUser.testEmails.txt +++ b/tests/ReplayData/AuthenticatedUser.testEmails.txt @@ -7,7 +7,7 @@ None None 200 [('status', '200 OK'), ('x-ratelimit-remaining', '4934'), ('content-length', '64'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"ea6dacf29569317ccf460b4bb07075e5"'), ('date', 'Sun, 20 May 2012 12:41:39 GMT'), ('content-type', 'application/json; charset=utf-8')] -["vincent@vincent-jacques.net","github.com@vincent-jacques.net"] +[{"email": "vincent@vincent-jacques.net", "primary": true, "verified": true, "visibility": "private"}, {"email": "github.com@vincent-jacques.net", "primary": false, "verified": true, "visibility": null}] https POST @@ -15,10 +15,10 @@ api.github.com None /user/emails {'Content-Type': 'application/json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} -["1@foobar.com", "2@foobar.com"] +{"emails": ["1@foobar.com", "2@foobar.com"]} 201 [('status', '201 Created'), ('x-ratelimit-remaining', '4933'), ('content-length', '94'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"8efae10ea5e433b0d68201389058e4ee"'), ('date', 'Sun, 20 May 2012 12:41:40 GMT'), ('content-type', 'application/json; charset=utf-8')] -["vincent@vincent-jacques.net","1@foobar.com","2@foobar.com","github.com@vincent-jacques.net"] +[{"email": "vincent@vincent-jacques.net", "primary": true, "verified": true, "visibility": "private"}, {"email": "1@foobar.com", "primary": false, "verified": false, "visibility": null}, {"email": "2@foobar.com", "primary": false, "verified": false, "visibility": null}, {"email": "github.com@vincent-jacques.net", "primary": false, "verified": true, "visibility": null}] https GET @@ -29,7 +29,7 @@ None None 200 [('status', '200 OK'), ('content-length', '94'), ('x-ratelimit-remaining', '4932'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"8efae10ea5e433b0d68201389058e4ee"'), ('date', 'Sun, 20 May 2012 12:41:41 GMT'), ('content-type', 'application/json; charset=utf-8')] -["vincent@vincent-jacques.net","1@foobar.com","2@foobar.com","github.com@vincent-jacques.net"] +[{"email": "vincent@vincent-jacques.net", "primary": true, "verified": true, "visibility": "private"}, {"email": "1@foobar.com", "primary": false, "verified": false, "visibility": null}, {"email": "2@foobar.com", "primary": false, "verified": false, "visibility": null}, {"email": "github.com@vincent-jacques.net", "primary": false, "verified": true, "visibility": null}] https DELETE @@ -37,7 +37,7 @@ api.github.com None /user/emails {'Content-Type': 'application/json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} -["1@foobar.com", "2@foobar.com"] +{"emails": ["1@foobar.com", "2@foobar.com"]} 204 [('status', '204 No Content'), ('x-ratelimit-remaining', '4931'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"d41d8cd98f00b204e9800998ecf8427e"'), ('date', 'Sun, 20 May 2012 12:41:41 GMT')] @@ -51,5 +51,5 @@ None None 200 [('status', '200 OK'), ('x-ratelimit-remaining', '4930'), ('content-length', '64'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"ea6dacf29569317ccf460b4bb07075e5"'), ('date', 'Sun, 20 May 2012 12:41:42 GMT'), ('content-type', 'application/json; charset=utf-8')] -["vincent@vincent-jacques.net","github.com@vincent-jacques.net"] +[{"email": "vincent@vincent-jacques.net", "primary": true, "verified": true, "visibility": "private"}, {"email": "github.com@vincent-jacques.net", "primary": false, "verified": true, "visibility": null}]