Skip to content
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

merge GithubObject.pyi/Requester.pyi stubs back to source #2463

Merged
merged 51 commits into from Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
1c27b76
merge GithubObject stubs back to source
trim21 Mar 20, 2023
e857eb2
typo
trim21 Mar 20, 2023
47e4268
more type
trim21 Mar 20, 2023
54c447b
fix type import
trim21 Mar 20, 2023
a441a80
Merge branch 'master' into type
trim21 May 8, 2023
a1b4956
wip
trim21 May 8, 2023
20368a1
wip[skip ci]
trim21 May 8, 2023
daf26cf
wip[skip ci]
trim21 May 8, 2023
138ef0f
wip[skip ci]
trim21 May 8, 2023
dc88329
Update Requester.py
trim21 May 8, 2023
c3f8d6f
Update Requester.py
trim21 May 8, 2023
2a27864
Update ci.yml
trim21 May 8, 2023
e04cfee
update ci
trim21 May 8, 2023
12812b5
Update lint.yml
trim21 May 8, 2023
21c4f10
Merge remote-tracking branch 'upstream/master' into pr/2463
trim21 May 23, 2023
944d963
fix test
trim21 May 23, 2023
dbcdaa4
fix type
trim21 May 23, 2023
d6087f7
revert
trim21 May 23, 2023
1e6e5c7
type
trim21 May 23, 2023
78af79a
revert
trim21 May 23, 2023
21656b3
add real usage example
trim21 May 23, 2023
de351b5
use is instance
trim21 May 23, 2023
e1bde06
fix type
trim21 May 23, 2023
599f483
fix type
trim21 May 23, 2023
a21eb6b
type
trim21 May 23, 2023
6b79429
type
trim21 May 23, 2023
a6d27c6
type
trim21 May 23, 2023
c1e81f7
better code
trim21 May 23, 2023
7b28c24
better code
trim21 May 23, 2023
1accb10
method name
trim21 May 23, 2023
703b864
Merge branch 'master' into type
trim21 Jun 1, 2023
2d19cf3
Merge remote-tracking branch 'upstream/master' into pr/2463
trim21 Jun 13, 2023
cf7854d
fix type
trim21 Jun 13, 2023
25a3081
rename Attr to Attribute
trim21 Jun 13, 2023
e235af6
Update github/Authorization.py
trim21 Jun 13, 2023
37a98bc
run pre-commit
trim21 Jun 13, 2023
1cff8f9
Merge branch 'master' into type
trim21 Jun 13, 2023
6d4f636
Merge remote-tracking branch 'upstream/master' into pr/2463
trim21 Jun 14, 2023
3696407
fix
trim21 Jun 14, 2023
8906d8f
Update github/Authorization.py
trim21 Jun 15, 2023
fa29df6
Update github/Authorization.py
trim21 Jun 15, 2023
cab0709
code review
trim21 Jun 15, 2023
5e925f8
code review
trim21 Jun 15, 2023
823f9f6
fix type
trim21 Jun 15, 2023
cd94401
code review
trim21 Jun 15, 2023
ab380f0
code review
trim21 Jun 15, 2023
4447be1
Update github/GithubObject.py
trim21 Jun 15, 2023
276701c
Revert "Update github/GithubObject.py"
trim21 Jun 15, 2023
1ffb057
type subclass
trim21 Jun 15, 2023
1cf2f46
Merge branch 'master' into type
trim21 Jun 16, 2023
ee1340c
Merge branch 'master' into type
trim21 Jun 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 24 additions & 19 deletions github/AccessToken.py
Expand Up @@ -21,16 +21,27 @@
################################################################################

from datetime import datetime, timedelta, timezone
from typing import Optional

import github.GithubObject

from .GithubObject import Attribute


class AccessToken(github.GithubObject.NonCompletableGithubObject):
"""
This class represents access tokens.
"""

def __repr__(self):
_created: datetime
_token: Attribute[str]
_type: Attribute[str]
_scope: Attribute[str]
_expires_in: Attribute[Optional[int]]
_refresh_token: Attribute[str]
_refresh_expires_in: Attribute[Optional[int]]

trim21 marked this conversation as resolved.
Show resolved Hide resolved
def __repr__(self) -> str:
return self.get__repr__(
{
"token": f"{self.token[:5]}...",
Expand All @@ -45,44 +56,42 @@ def __repr__(self):
)

@property
def token(self):
def token(self) -> str:
"""
:type: string
"""
return self._token.value

@property
def type(self):
def type(self) -> str:
"""
:type: string
"""
return self._type.value

@property
def scope(self):
def scope(self) -> str:
"""
:type: string
"""
return self._scope.value

@property
def created(self):
def created(self) -> datetime:
"""
:type: datetime
"""
return self._created

@property
def expires_in(self):
def expires_in(self) -> Optional[int]:
"""
:type: Optional[int]
"""
if self._expires_in is not github.GithubObject.NotSet:
return self._expires_in.value
return None
return self._expires_in.value

@property
def expires_at(self):
def expires_at(self) -> Optional[datetime]:
"""
:type: Optional[datetime]
"""
Expand All @@ -92,25 +101,21 @@ def expires_at(self):
return None

@property
def refresh_token(self):
def refresh_token(self) -> Optional[str]:
"""
:type: Optional[string]
"""
if self._refresh_token is not github.GithubObject.NotSet:
return self._refresh_token.value
return None
return self._refresh_token.value

@property
def refresh_expires_in(self):
def refresh_expires_in(self) -> Optional[int]:
"""
:type: Optional[int]
"""
if self._refresh_expires_in is not github.GithubObject.NotSet:
return self._refresh_expires_in.value
return None
return self._refresh_expires_in.value

@property
def refresh_expires_at(self):
def refresh_expires_at(self) -> Optional[datetime]:
"""
:type: Optional[datetime]
"""
Expand Down
29 changes: 0 additions & 29 deletions github/AccessToken.pyi

This file was deleted.

127 changes: 58 additions & 69 deletions github/Authorization.py
Expand Up @@ -27,106 +27,97 @@
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
from datetime import datetime
from typing import TYPE_CHECKING, List, Optional

import github.AuthorizationApplication
import github.GithubObject
from github.GithubObject import Attribute, NotSet, Opt, _NotSetType

if TYPE_CHECKING:
from github.AuthorizationApplication import AuthorizationApplication


class Authorization(github.GithubObject.CompletableGithubObject):
"""
This class represents Authorizations. The reference can be found here https://docs.github.com/en/enterprise-server@3.0/rest/reference/oauth-authorizations
"""

def __repr__(self):
_app: Attribute["AuthorizationApplication"]
_created_at: Attribute[datetime]
_id: Attribute[int]
_note: Attribute[Optional[str]]
_note_url: Attribute[Optional[str]]
_scopes: Attribute[str]
_token: Attribute[str]
_updated_at: Attribute[datetime]
_url: Attribute[str]

def __repr__(self) -> str:
return self.get__repr__({"scopes": self._scopes.value})

@property
def app(self):
"""
:type: :class:`github.AuthorizationApplication.AuthorizationApplication`
"""
def app(self) -> "AuthorizationApplication":
self._completeIfNotSet(self._app)
return self._app.value

@property
def created_at(self):
def created_at(self) -> datetime:
"""
:type: datetime.datetime
"""
self._completeIfNotSet(self._created_at)
return self._created_at.value

@property
def id(self):
"""
:type: integer
"""
def id(self) -> int:
self._completeIfNotSet(self._id)
return self._id.value

@property
def note(self):
"""
:type: string
"""
def note(self) -> Optional[str]:
self._completeIfNotSet(self._note)
return self._note.value

@property
def note_url(self):
"""
:type: string
"""
def note_url(self) -> Optional[str]:
self._completeIfNotSet(self._note_url)
return self._note_url.value

@property
def scopes(self):
"""
:type: list of string
"""
def scopes(self) -> str:
self._completeIfNotSet(self._scopes)
return self._scopes.value

@property
def token(self):
"""
:type: string
"""
def token(self) -> str:
self._completeIfNotSet(self._token)
return self._token.value

@property
def updated_at(self):
"""
:type: datetime.datetime
"""
def updated_at(self) -> datetime:
self._completeIfNotSet(self._updated_at)
return self._updated_at.value

@property
def url(self):
"""
:type: string
"""
def url(self) -> str:
self._completeIfNotSet(self._url)
return self._url.value

def delete(self):
def delete(self) -> None:
"""
:calls: `DELETE /authorizations/{id} <https://docs.github.com/en/developers/apps/authorizing-oauth-apps>`_
:rtype: None
"""
headers, data = self._requester.requestJsonAndCheck("DELETE", self.url)

def edit(
self,
scopes=github.GithubObject.NotSet,
add_scopes=github.GithubObject.NotSet,
remove_scopes=github.GithubObject.NotSet,
note=github.GithubObject.NotSet,
note_url=github.GithubObject.NotSet,
):
scopes: Opt[List[str]] = NotSet,
add_scopes: Opt[List[str]] = NotSet,
remove_scopes: Opt[List[str]] = NotSet,
note: Opt[str] = NotSet,
note_url: Opt[str] = NotSet,
) -> None:
"""
:calls: `PATCH /authorizations/{id} <https://docs.github.com/en/developers/apps/authorizing-oauth-apps>`_
:param scopes: list of string
Expand All @@ -136,45 +127,43 @@ def edit(
:param note_url: string
:rtype: None
"""
assert scopes is github.GithubObject.NotSet or all(
assert isinstance(scopes, _NotSetType) or all(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like how this degenerates from

assert scopes is NotSet

to

assert isinstance(scopes, _NotSetType)

@JLLeitschuh any suggestions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why it's a degenerate...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's going from a constant comparison using is to an isinstance check, which means that the entire type hierarchy needs to be checked every time now, right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@trim21 trim21 Jun 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, it impact performance.

But I don't think it's very necessary

and also UnSet is Attribute[None] now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean this aesthetically.

assert scopes is NotSet

Is readable,

assert isinstance(scopes, _NotSetType)

is ugly.

Plus, we need to import a private class _NotSetType. A lot of code has to be touched. The former was present before.

Copy link
Contributor Author

@trim21 trim21 Jun 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But python typing system doesn't support this.

If I use emun as single value here, it can't pass mypy:

o: Attribute[Optional[int]] = NotSet

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also Protocol doesn't support generic, so make Attribute a Protocol won't work.

I don't know if there is any way to avoid all these problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a good side of this, now you can write assert isinstance(v, (_NotSetType, str)) instead of assert v is NotSet or instance(v, str)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @trim21 here. There may not be a way to make the type checker happy moving forward. Im inclined to let us poke at trying to make this better in a followup PR

isinstance(element, str) for element in scopes
), scopes
assert add_scopes is github.GithubObject.NotSet or all(
assert isinstance(add_scopes, _NotSetType) or all(
isinstance(element, str) for element in add_scopes
), add_scopes
assert remove_scopes is github.GithubObject.NotSet or all(
assert isinstance(remove_scopes, _NotSetType) or all(
isinstance(element, str) for element in remove_scopes
), remove_scopes
assert note is github.GithubObject.NotSet or isinstance(note, str), note
assert note_url is github.GithubObject.NotSet or isinstance(
note_url, str
), note_url
post_parameters = dict()
if scopes is not github.GithubObject.NotSet:
post_parameters["scopes"] = scopes
if add_scopes is not github.GithubObject.NotSet:
post_parameters["add_scopes"] = add_scopes
if remove_scopes is not github.GithubObject.NotSet:
post_parameters["remove_scopes"] = remove_scopes
if note is not github.GithubObject.NotSet:
post_parameters["note"] = note
if note_url is not github.GithubObject.NotSet:
post_parameters["note_url"] = note_url
assert isinstance(note, (_NotSetType, str)), note
assert isinstance(note_url, (_NotSetType, str)), note_url

post_parameters = NotSet.remove_unset_items(
trim21 marked this conversation as resolved.
Show resolved Hide resolved
{
"scopes": scopes,
"add_scopes": add_scopes,
"remove_scopes": remove_scopes,
"note": note,
"note_url": note_url,
}
)

headers, data = self._requester.requestJsonAndCheck(
"PATCH", self.url, input=post_parameters
)
self._useAttributes(data)

def _initAttributes(self):
self._app = github.GithubObject.NotSet
self._created_at = github.GithubObject.NotSet
self._id = github.GithubObject.NotSet
self._note = github.GithubObject.NotSet
self._note_url = github.GithubObject.NotSet
self._scopes = github.GithubObject.NotSet
self._token = github.GithubObject.NotSet
self._updated_at = github.GithubObject.NotSet
self._url = github.GithubObject.NotSet
self._app = NotSet
self._created_at = NotSet
self._id = NotSet
self._note = NotSet
self._note_url = NotSet
self._scopes = NotSet
self._token = NotSet
self._updated_at = NotSet
self._url = NotSet

def _useAttributes(self, attributes):
if "app" in attributes: # pragma no branch
Expand Down
37 changes: 0 additions & 37 deletions github/Authorization.pyi

This file was deleted.